From b497f538ea339c8e87404bc3337f0c0ce8790c4a Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 9 Jul 2024 11:45:10 +0100 Subject: [PATCH 01/93] docs: add readme --- verifier/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 verifier/README.md diff --git a/verifier/README.md b/verifier/README.md new file mode 100644 index 0000000..39d9d2f --- /dev/null +++ b/verifier/README.md @@ -0,0 +1,20 @@ +# Babylon Verifier Program + +This is a peripheral program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks via RESTful API endpoints. It is served as a Docker container for local use or hosted on a server. + +## Running the Docker container + +To get started, clone the repository and navigate to the `/verifier` directory. + +```bash +git clone https://github.com/babylonchain/babylon-finality-gadget.git +cd verifier +``` + +Make sure you have Docker installed locally. If you don't, you can download it [here](https://www.docker.com/products/docker-desktop). + +To run the Docker container, run: + +```bash +docker compose up +``` From c12bc2aba80d021e69ade5b120b4cf233ef414a6 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 11 Jul 2024 07:43:30 +0100 Subject: [PATCH 02/93] feat: scaffold initial services --- .gitignore | 3 +- go.mod | 17 +- go.sum | 45 +++++ verifier/cmd/main.go | 65 +++++++ verifier/db/db.go | 111 +++++++++++ .../db/migrations/0000_initial_tables.sql | 7 + verifier/db/models.go | 8 + verifier/server/handlers.go | 113 ++++++++++++ verifier/server/routes.go | 16 ++ verifier/server/server.go | 21 +++ verifier/verifier/types.go | 32 ++++ verifier/verifier/verifier.go | 172 ++++++++++++++++++ 12 files changed, 607 insertions(+), 3 deletions(-) create mode 100644 verifier/cmd/main.go create mode 100644 verifier/db/db.go create mode 100644 verifier/db/migrations/0000_initial_tables.sql create mode 100644 verifier/db/models.go create mode 100644 verifier/server/handlers.go create mode 100644 verifier/server/routes.go create mode 100644 verifier/server/server.go create mode 100644 verifier/verifier/types.go create mode 100644 verifier/verifier/verifier.go diff --git a/.gitignore b/.gitignore index 417d34c..cf0957f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ **/target/ -.DS_Store \ No newline at end of file +.DS_Store +*/.env \ No newline at end of file diff --git a/go.mod b/go.mod index 024cc70..955f1c8 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,10 @@ require ( github.com/btcsuite/btcd v0.24.2 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 github.com/cosmos/cosmos-sdk v0.50.6 + github.com/ethereum/go-ethereum v1.13.15 + github.com/gorilla/mux v1.8.1 + github.com/jackc/pgx/v5 v5.6.0 + github.com/joho/godotenv v1.5.1 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.26.0 ) @@ -39,6 +43,8 @@ require ( github.com/CosmWasm/wasmvm/v2 v2.0.0 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect github.com/aead/siphash v1.0.1 // indirect github.com/aws/aws-sdk-go v1.44.312 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -80,6 +86,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect @@ -92,7 +99,6 @@ require ( github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/dot v1.6.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/ethereum/go-ethereum v1.13.15 // indirect github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -102,6 +108,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/gobwas/ws v1.1.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect @@ -120,7 +127,6 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/handlers v1.5.2 // indirect - github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect @@ -143,6 +149,8 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect @@ -185,6 +193,7 @@ require ( github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect @@ -199,6 +208,8 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.2 // indirect @@ -213,6 +224,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect @@ -220,6 +232,7 @@ require ( golang.org/x/term v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.20.0 // indirect google.golang.org/api v0.169.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 // indirect diff --git a/go.sum b/go.sum index b686081..3d9a9bb 100644 --- a/go.sum +++ b/go.sum @@ -413,8 +413,10 @@ github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5n github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cosmos/relayer/v2 v2.5.2 h1:AF0MOo1GvJo94QNB996fBHdKlH+vrIY3JcFNrIvZNP0= github.com/cosmos/relayer/v2 v2.5.2/go.mod h1:h4Ng2QsVpxExIq5S+WvLr8slDb9MSBh82gQS4DeMwDo= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= @@ -429,6 +431,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= @@ -488,6 +492,8 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= +github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -498,6 +504,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -531,6 +539,7 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -565,6 +574,8 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= @@ -709,6 +720,8 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NM github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= @@ -754,6 +767,8 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= @@ -764,6 +779,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -774,6 +791,16 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= @@ -787,6 +814,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -882,6 +911,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= @@ -1024,8 +1055,10 @@ github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= @@ -1072,6 +1105,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/strangelove-ventures/cometbft-client v0.1.0 h1:fcA652QaaR0LDnyJOZVjZKtuyAawnVXaq/p1MWJSYD4= github.com/strangelove-ventures/cometbft-client v0.1.0/go.mod h1:QzThgjzvsGgUNVNpGPitmxOWMIhp6a0oqf80nCRNt/0= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1124,11 +1159,16 @@ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/vulpine-io/io-test v1.0.0 h1:Ot8vMh+ssm1VWDAwJ3U4C5qG9aRnr5YfQFZPNZBAUGI= github.com/vulpine-io/io-test v1.0.0/go.mod h1:X1I+p5GCxVX9m4nFd1HBtr2bVX9v1ZE6x8w+Obt36AU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1367,6 +1407,7 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1443,6 +1484,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -1788,6 +1831,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/verifier/cmd/main.go b/verifier/cmd/main.go new file mode 100644 index 0000000..1277194 --- /dev/null +++ b/verifier/cmd/main.go @@ -0,0 +1,65 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strconv" + "time" + + "github.com/babylonchain/babylon-finality-gadget/verifier/server" + "github.com/babylonchain/babylon-finality-gadget/verifier/verifier" + "github.com/joho/godotenv" +) +func main() { + ctx := context.Background() + + // Load .env file + cwd, err := os.Getwd() + if err != nil { + fmt.Printf("error getting current working directory: %v\n", err) + } + envFile := filepath.Join(cwd, ".env") + fmt.Printf("loading env file: %s\n", envFile) + err = godotenv.Load(envFile) + if err != nil { + fmt.Printf("error loading .env file: %v\n", err) + } + + // Import and parse env vars + L2_RPC_HOST := os.Getenv("L2_RPC_HOST") + BITCOIN_RPC_HOST := os.Getenv("BITCOIN_RPC_HOST") + PG_CONNECTION_STRING := os.Getenv("PG_CONNECTION_STRING") + FG_CONTRACT_ADDRESS := os.Getenv("FG_CONTRACT_ADDRESS") + BBN_CHAIN_TYPE := os.Getenv("BBN_CHAIN_TYPE") + POLL_INTERVAL_IN_SECS := os.Getenv("POLL_INTERVAL_IN_SECS") + + bbnChainType, err := strconv.Atoi(BBN_CHAIN_TYPE) + if err != nil { + fmt.Printf("error converting babylon chain type to int: %v\n", err) + } + pollInterval, err := strconv.Atoi(POLL_INTERVAL_IN_SECS) + if err != nil { + fmt.Printf("error converting poll interval to int: %v\n", err) + } + + // Create verifier + vf, err := verifier.NewVerifier(ctx, &verifier.Config{ + L2RPCHost: L2_RPC_HOST, + BitcoinRPCHost: BITCOIN_RPC_HOST, + PGConnectionString: PG_CONNECTION_STRING, + FGContractAddress:FG_CONTRACT_ADDRESS, + BBNChainType: bbnChainType, + PollInterval: time.Second * time.Duration(pollInterval), + }) + if err != nil { + fmt.Printf("error creating verifier: %v\n", err) + } + + // Start server + go server.StartServer() + + // Start processing blocks + vf.ProcessBlocks(ctx) +} \ No newline at end of file diff --git a/verifier/db/db.go b/verifier/db/db.go new file mode 100644 index 0000000..e93c2d2 --- /dev/null +++ b/verifier/db/db.go @@ -0,0 +1,111 @@ +package db + +import ( + "context" + "fmt" + "os" + + "github.com/jackc/pgx/v5" +) + +type PostgresHandler struct { + conn *pgx.Conn +} + +func NewPostgresHandler(ctx context.Context, connString string) (*PostgresHandler, error) { + conn, err := pgx.Connect(ctx, connString) + if err != nil { + return nil, err + } + + return &PostgresHandler{ + conn: conn, + }, nil +} + +func (pg *PostgresHandler) TryCreateInitialTables(ctx context.Context) error { + // Load the migration file + filePath := "db/migrations/0000_initial_tables.sql" + + sqlBytes, err := os.ReadFile(filePath) + if err != nil { + return fmt.Errorf("unable to read SQL file: %v", err) + } + sql := string(sqlBytes) + + // Execute the SQL statements + _, err = pg.conn.Exec(ctx, sql) + if err != nil { + return fmt.Errorf("unable to execute SQL statements: %v", err) + } + + return nil +} + +func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { + fmt.Printf("Inserting block %d into DB\n", block.BlockHeight) + _, err := pg.conn.Exec( + ctx, + "INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4)", + block.BlockHeight, + block.BlockHash, + block.BlockTimestamp, + block.IsFinalized, + ) + + if err != nil { + return fmt.Errorf("unable to insert block: %v", err) + } + + return nil +} + +func (pg *PostgresHandler) GetBlockStatusByHeight(ctx context.Context, blockHeight uint64) bool { + query := `SELECT is_finalized FROM blocks WHERE block_height = $1` + + var isFinalized bool + err := pg.conn.QueryRow(ctx, query, blockHeight).Scan(&isFinalized) + if err != nil { + fmt.Printf("GetBlockStatusByHeight: %v\n", err) + return false + } + + return isFinalized +} + +func (pg *PostgresHandler) GetBlockStatusByHash(ctx context.Context, blockHash string) bool { + query := `SELECT is_finalized FROM blocks WHERE block_hash = $1` + + var isFinalized bool + err := pg.conn.QueryRow(ctx, query, blockHash).Scan(&isFinalized) + + if err != nil { + fmt.Printf("GetBlockStatusByHash: %v\n", err) + return false + } + + return isFinalized +} + +func (pg *PostgresHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { + query := ` + SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized + FROM blocks b + JOIN blocks prev ON b.block_height = prev.block_height + 1 + WHERE b.is_finalized = TRUE AND prev.is_finalized = TRUE + ORDER BY b.block_height DESC + LIMIT 1; + ` + + var block Block + err := pg.conn.QueryRow(ctx, query).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) + if err != nil { + return nil, fmt.Errorf("unable to get latest consecutively finalized block: %v", err) + } + + return &block, nil +} + +func (pg *PostgresHandler) Close(ctx context.Context) { + pg.conn.Close(ctx) +} \ No newline at end of file diff --git a/verifier/db/migrations/0000_initial_tables.sql b/verifier/db/migrations/0000_initial_tables.sql new file mode 100644 index 0000000..90c94ce --- /dev/null +++ b/verifier/db/migrations/0000_initial_tables.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS blocks ( + block_height INTEGER PRIMARY KEY, + block_hash TEXT NOT NULL, + block_timestamp INTEGER NOT NULL, + is_finalized BOOLEAN NOT NULL +); +CREATE INDEX IF NOT EXISTS blocks_hash_idx ON blocks (block_hash, block_timestamp); \ No newline at end of file diff --git a/verifier/db/models.go b/verifier/db/models.go new file mode 100644 index 0000000..a0a1624 --- /dev/null +++ b/verifier/db/models.go @@ -0,0 +1,8 @@ +package db + +type Block struct { + BlockHeight uint64 `json:"block_height" description:"block height"` + BlockHash string `json:"block_hash" description:"block hash"` + BlockTimestamp uint64 `json:"block_timestamp" description:"block timestamp"` + IsFinalized bool `json:"is_finalized" description:"babylon block finality status"` +} \ No newline at end of file diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go new file mode 100644 index 0000000..e00a9ea --- /dev/null +++ b/verifier/server/handlers.go @@ -0,0 +1,113 @@ +package server + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "strconv" + + "github.com/babylonchain/babylon-finality-gadget/verifier/db" +) + +type StatusResponse struct { + IsFinalized bool `json:"isFinalized"` +} + +func getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) { + // Fetch params and run validation check + blockHeightStr := r.URL.Query().Get("blockHeight") + if blockHeightStr == "" { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "Missing required params: blockHeight\n") + return + } + + // Parse params + blockHeight, err := strconv.Atoi(blockHeightStr) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "Invalid blockHeight\n") + return + } + + // Fetch status from DB + ctx := context.Background() + pg, err := db.NewPostgresHandler(ctx, os.Getenv("PG_CONNECTION_STRING")) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error creating postgres handler: %v\n", err) + return + } + isFinal := pg.GetBlockStatusByHeight(ctx, uint64(blockHeight)) + + // Marshal and return status + jsonResponse, err := json.Marshal(StatusResponse { + IsFinalized: isFinal, + }) + if err != nil { + http.Error(w, "unable to marshal JSON response", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(jsonResponse) +} + +func getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { + // Fetch params and run validation check + hash := r.URL.Query().Get("hash") + if hash == "" { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "Missing required params: hash\n") + return + } + + // Fetch status from DB + ctx := context.Background() + pg, err := db.NewPostgresHandler(ctx, os.Getenv("PG_CONNECTION_STRING")) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error creating postgres handler: %v\n", err) + return + } + isFinal := pg.GetBlockStatusByHash(ctx, hash) + + // Marshal and return status + jsonResponse, err := json.Marshal(StatusResponse { + IsFinalized: isFinal, + }) + if err != nil { + http.Error(w, "unable to marshal JSON response", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(jsonResponse) +} + +func getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { + // Fetch status from DB + ctx := context.Background() + pg, err := db.NewPostgresHandler(ctx, os.Getenv("PG_CONNECTION_STRING")) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error creating postgres handler: %v\n", err) + return + } + block, err := pg.GetLatestConsecutivelyFinalizedBlock(ctx) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error getting latest block: %v\n", err) + return + } + + // Marshal and return status + jsonResponse, err := json.Marshal(block) + if err != nil { + http.Error(w, "unable to marshal JSON response", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(jsonResponse) +} + diff --git a/verifier/server/routes.go b/verifier/server/routes.go new file mode 100644 index 0000000..5421b6c --- /dev/null +++ b/verifier/server/routes.go @@ -0,0 +1,16 @@ +package server + +import ( + "github.com/gorilla/mux" +) + +func NewRouter() *mux.Router { + router := mux.NewRouter().StrictSlash(true) + + // Routes + router.HandleFunc("/getBlockStatusByHeight", getBlockStatusByHeight) + router.HandleFunc("/getBlockStatusByHash", getBlockStatusByHash) + router.HandleFunc("/getLatest", getLatestConsecutivelyFinalizedBlock) + + return router +} \ No newline at end of file diff --git a/verifier/server/server.go b/verifier/server/server.go new file mode 100644 index 0000000..e3f32bc --- /dev/null +++ b/verifier/server/server.go @@ -0,0 +1,21 @@ +package server + +import ( + "log" + "net/http" + "os" +) + +func StartServer() { + router := NewRouter() + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + log.Printf("Starting server on port %s...", port) + if err := http.ListenAndServe(":"+port, router); err != nil { + log.Fatalf("Could not start server: %s\n", err.Error()) + } +} \ No newline at end of file diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go new file mode 100644 index 0000000..3a476d0 --- /dev/null +++ b/verifier/verifier/types.go @@ -0,0 +1,32 @@ +package verifier + +import ( + "time" + + "github.com/babylonchain/babylon-finality-gadget/sdk" + "github.com/babylonchain/babylon-finality-gadget/verifier/db" + "github.com/ethereum/go-ethereum/ethclient" +) + +type Verifier struct { + SdkClient *sdk.BabylonFinalityGadgetClient + L2Client *ethclient.Client + Pg *db.PostgresHandler + PollInterval time.Duration + blockHeight uint64 +} + +type Config struct { + L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` + BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` + PGConnectionString string `long:"pg-connection-string" description:"Postgres DB connection string"` + FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` + BBNChainType int `long:"bbn-chain-type" description:"BabylonChain chain type"` + PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` +} + +type BlockInfo struct { + Height uint64 + Hash string + Timestamp uint64 +} \ No newline at end of file diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go new file mode 100644 index 0000000..133e065 --- /dev/null +++ b/verifier/verifier/verifier.go @@ -0,0 +1,172 @@ +package verifier + +import ( + "context" + "encoding/hex" + "fmt" + "math/big" + "time" + + "github.com/babylonchain/babylon-finality-gadget/btcclient" + "github.com/babylonchain/babylon-finality-gadget/sdk" + "github.com/babylonchain/babylon-finality-gadget/verifier/db" + "github.com/ethereum/go-ethereum/ethclient" + ethrpc "github.com/ethereum/go-ethereum/rpc" +) + +// TODO: refactor to use op types and methods + +// TODO: add method `SubscribeToNewHeads` to subscribe to new block heads +// TODO: add method `GetBlockByNumber` to get block by number +// TODO: add method `GetBlockByHash` to get block by hash + +func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { + // Create finality gadget client + btcConfig := btcclient.DefaultBTCConfig() + btcConfig.RPCHost = cfg.BitcoinRPCHost + sdkClient, err := sdk.NewClient(&sdk.Config{ + ChainType: cfg.BBNChainType, + ContractAddr: cfg.FGContractAddress, + BTCConfig: btcConfig, + }) + if err != nil { + return nil, fmt.Errorf("error creating client: %w", err) + } + + // Create L2 client + l2Client, err := ethclient.Dial(cfg.L2RPCHost) + if err != nil { + return nil, fmt.Errorf("failed to create OPStack L2 client: %w", err) + } + + // Create local DB for storing and querying blocks + pg, err := db.NewPostgresHandler(ctx, cfg.PGConnectionString) + if err != nil { + return nil, fmt.Errorf("failed to create postgres handler: %w", err) + } + err = pg.TryCreateInitialTables(ctx) + if err != nil { + return nil, fmt.Errorf("create initial tables error: %w", err) + } + + // Create verifier + return &Verifier{ + SdkClient: sdkClient, + L2Client: l2Client, + Pg: pg, + PollInterval: cfg.PollInterval, + }, nil +} + +func (vf *Verifier) ProcessBlocks(ctx context.Context) error { + // Query L2 node for last finalized block + block, err := vf.getLatestFinalizedBlock(ctx) + if err != nil { + return fmt.Errorf("error getting last finalized block: %v\n", err) + } + + // If this block already exists in our DB, skip the finality check + exists := vf.Pg.GetBlockStatusByHeight(ctx, block.Height) + if err != nil { + return fmt.Errorf("error checking block %d: %v", block.Height, err) + } + if !exists { + // Check the block is finalized using sdk client + isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) + // If not finalized, throw error + if !isFinal { + return fmt.Errorf("block %d should be finalized according to client but is not", block.Height) + } + if err != nil { + return fmt.Errorf("error checking block %d: %v", block.Height, err) + } + // If finalised, store the block in DB and set the last finalized block + err = vf.Pg.InsertBlock(ctx, db.Block{ + BlockHeight: block.Height, + BlockHash: block.Hash, + BlockTimestamp: block.Timestamp, + IsFinalized: true, + }) + if err != nil { + return fmt.Errorf("error storing block %d: %v", block.Height, err) + } + } + + // Start service at block height + fmt.Printf("starting service at block %d\n", block.Height) + + // Store the last finalized block height in memory + vf.blockHeight = block.Height + + // Start polling for new blocks at set interval + ticker := time.NewTicker(vf.PollInterval) + for range ticker.C { + fmt.Printf("polling for new block at height %d\n", vf.blockHeight + 1) + block, err := vf.getBlockByNumber(ctx, int64(vf.blockHeight + 1)) + if err != nil { + fmt.Printf("error getting new block: %v\n", err) + continue + } + go handleBlock(vf, ctx, block) + } + + return nil +} + +// Get last btc finalized block +func (vf *Verifier) getLatestFinalizedBlock(ctx context.Context) (*BlockInfo, error) { + return vf.getBlockByNumber(ctx, ethrpc.FinalizedBlockNumber.Int64()) +} + +// Get block by number +func (vf *Verifier) getBlockByNumber(ctx context.Context, blockNumber int64) (*BlockInfo, error) { + header, err := vf.L2Client.HeaderByNumber(ctx, big.NewInt(blockNumber)) + if err != nil { + return nil, err + } + return &BlockInfo{ + Height: header.Number.Uint64(), + Hash: hex.EncodeToString(header.Hash().Bytes()), + Timestamp: header.Time, + }, nil +} + +func handleBlock(vf *Verifier, ctx context.Context, block *BlockInfo) { + // while block is not finalized, recheck if block is finalized every `retryInterval` seconds + // if finalized, store the block in DB and set the last finalized block + for { + fmt.Printf("checking finality of block %d\n", block.Height) + // Check if block is finalized + isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) + if err != nil { + fmt.Printf("error checking block %d: %v\n", block.Height, err) + return + } + if isFinal { + // Store block in DB + err := vf.Pg.InsertBlock(ctx, db.Block{ + BlockHeight: block.Height, + BlockHash: block.Hash, + BlockTimestamp: block.Timestamp, + IsFinalized: true, + }) + if err != nil { + fmt.Printf("error storing block %d: %v\n", block.Height, err) + } + // Set last finalized block in memory + vf.blockHeight = block.Height + return + } + + // Sleep for `PollInterval` seconds + time.Sleep(vf.PollInterval * time.Second) + } +} + +func (vf *Verifier) queryIsBlockBabylonFinalized(ctx context.Context, block *BlockInfo) (bool, error) { + return vf.SdkClient.QueryIsBlockBabylonFinalized(&sdk.L2Block{ + BlockHash: string(block.Hash), + BlockHeight: block.Height, + BlockTimestamp: block.Timestamp, + }) +} \ No newline at end of file From 24a69dcbb2620adc90c8b5684ac3137f702ab3d3 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 11 Jul 2024 07:44:15 +0100 Subject: [PATCH 03/93] docs: update readme --- verifier/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/verifier/README.md b/verifier/README.md index 39d9d2f..89c11af 100644 --- a/verifier/README.md +++ b/verifier/README.md @@ -11,6 +11,17 @@ git clone https://github.com/babylonchain/babylon-finality-gadget.git cd verifier ``` +Create a `.env` file in the `/verifier` directory with the following content: + +```bash +L2_RPC_HOST= +BITCOIN_RPC_HOST= +PG_CONNECTION_STRING= +FG_CONTRACT_ADDRESS= +BBN_CHAIN_TYPE= +POLL_INTERVAL_IN_SECS= +``` + Make sure you have Docker installed locally. If you don't, you can download it [here](https://www.docker.com/products/docker-desktop). To run the Docker container, run: From 935c53c441fab2772bdd92422a34e0bf312c1905 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 11 Jul 2024 07:52:18 +0100 Subject: [PATCH 04/93] chore: remove old comments --- verifier/verifier/verifier.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 133e065..6a22229 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -14,12 +14,6 @@ import ( ethrpc "github.com/ethereum/go-ethereum/rpc" ) -// TODO: refactor to use op types and methods - -// TODO: add method `SubscribeToNewHeads` to subscribe to new block heads -// TODO: add method `GetBlockByNumber` to get block by number -// TODO: add method `GetBlockByHash` to get block by hash - func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { // Create finality gadget client btcConfig := btcclient.DefaultBTCConfig() @@ -62,7 +56,7 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { // Query L2 node for last finalized block block, err := vf.getLatestFinalizedBlock(ctx) if err != nil { - return fmt.Errorf("error getting last finalized block: %v\n", err) + return fmt.Errorf("error getting last finalized block: %v", err) } // If this block already exists in our DB, skip the finality check From 088d0bf81b68f864814901790ff4321855f26a2a Mon Sep 17 00:00:00 2001 From: parketh Date: Fri, 12 Jul 2024 10:41:56 +0100 Subject: [PATCH 05/93] feat: add mutex for db write operations --- verifier/verifier/types.go | 4 ++++ verifier/verifier/verifier.go | 44 +++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index 3a476d0..985c690 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -1,6 +1,7 @@ package verifier import ( + "sync" "time" "github.com/babylonchain/babylon-finality-gadget/sdk" @@ -12,6 +13,9 @@ type Verifier struct { SdkClient *sdk.BabylonFinalityGadgetClient L2Client *ethclient.Client Pg *db.PostgresHandler + + Mutex sync.Mutex + PollInterval time.Duration blockHeight uint64 } diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 6a22229..5308173 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -75,12 +75,7 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { return fmt.Errorf("error checking block %d: %v", block.Height, err) } // If finalised, store the block in DB and set the last finalized block - err = vf.Pg.InsertBlock(ctx, db.Block{ - BlockHeight: block.Height, - BlockHash: block.Hash, - BlockTimestamp: block.Timestamp, - IsFinalized: true, - }) + err = vf.insertBlock(ctx, block) if err != nil { return fmt.Errorf("error storing block %d: %v", block.Height, err) } @@ -101,7 +96,9 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { fmt.Printf("error getting new block: %v\n", err) continue } - go handleBlock(vf, ctx, block) + go func() { + vf.handleBlock(ctx, block) + }() } return nil @@ -125,7 +122,7 @@ func (vf *Verifier) getBlockByNumber(ctx context.Context, blockNumber int64) (*B }, nil } -func handleBlock(vf *Verifier, ctx context.Context, block *BlockInfo) { +func (vf *Verifier) handleBlock(ctx context.Context, block *BlockInfo) { // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { @@ -137,18 +134,10 @@ func handleBlock(vf *Verifier, ctx context.Context, block *BlockInfo) { return } if isFinal { - // Store block in DB - err := vf.Pg.InsertBlock(ctx, db.Block{ - BlockHeight: block.Height, - BlockHash: block.Hash, - BlockTimestamp: block.Timestamp, - IsFinalized: true, - }) + err = vf.insertBlock(ctx, block) if err != nil { fmt.Printf("error storing block %d: %v\n", block.Height, err) } - // Set last finalized block in memory - vf.blockHeight = block.Height return } @@ -163,4 +152,25 @@ func (vf *Verifier) queryIsBlockBabylonFinalized(ctx context.Context, block *Blo BlockHeight: block.Height, BlockTimestamp: block.Timestamp, }) +} + +func (vf *Verifier) insertBlock(ctx context.Context, block *BlockInfo) error { + // Lock mutex + vf.Mutex.Lock() + // Store block in DB + err := vf.Pg.InsertBlock(ctx, db.Block{ + BlockHeight: block.Height, + BlockHash: block.Hash, + BlockTimestamp: block.Timestamp, + IsFinalized: true, + }) + if err != nil { + return err + } + // Set last finalized block in memory + vf.blockHeight = block.Height + // Unlock mutex + vf.Mutex.Unlock() + + return nil } \ No newline at end of file From 5026dc93264c3455823d954712355d8f20fba78e Mon Sep 17 00:00:00 2001 From: parketh Date: Fri, 12 Jul 2024 10:47:56 +0100 Subject: [PATCH 06/93] feat: convert db write to tx with rollback --- verifier/db/db.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/verifier/db/db.go b/verifier/db/db.go index e93c2d2..6565d45 100644 --- a/verifier/db/db.go +++ b/verifier/db/db.go @@ -44,7 +44,15 @@ func (pg *PostgresHandler) TryCreateInitialTables(ctx context.Context) error { func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { fmt.Printf("Inserting block %d into DB\n", block.BlockHeight) - _, err := pg.conn.Exec( + + // Start atomic insert tx + tx, err := pg.conn.Begin(ctx) + if err != nil { + return fmt.Errorf("unable to start DB tx: %v", err) + } + + // Insert block + _, err = tx.Exec( ctx, "INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4)", block.BlockHeight, @@ -52,11 +60,19 @@ func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { block.BlockTimestamp, block.IsFinalized, ) - + // Rollback tx if error if err != nil { + if rollbackErr := tx.Rollback(ctx); rollbackErr != nil { + return fmt.Errorf("unable to insert block: %v, unable to rollback transaction: %v", err, rollbackErr) + } return fmt.Errorf("unable to insert block: %v", err) } + // Commit tx if no error + if err := tx.Commit(ctx); err != nil { + return fmt.Errorf("unable to commit transaction: %v", err) + } + return nil } From c422e3faf1afaf799fb13d09202326463e615146 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 16 Jul 2024 20:43:06 +0100 Subject: [PATCH 07/93] chore: rename main -> demo --- verifier/{cmd => demo}/main.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename verifier/{cmd => demo}/main.go (100%) diff --git a/verifier/cmd/main.go b/verifier/demo/main.go similarity index 100% rename from verifier/cmd/main.go rename to verifier/demo/main.go From c7fca2938463e43c7bd041602b2bc6f2e095ba00 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 16 Jul 2024 22:42:09 +0100 Subject: [PATCH 08/93] fix: update verifier for sdk configs --- verifier/demo/main.go | 10 ++++------ verifier/verifier/types.go | 7 ++++--- verifier/verifier/verifier.go | 15 +++++++++------ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/verifier/demo/main.go b/verifier/demo/main.go index 1277194..c18c4b6 100644 --- a/verifier/demo/main.go +++ b/verifier/demo/main.go @@ -32,13 +32,10 @@ func main() { BITCOIN_RPC_HOST := os.Getenv("BITCOIN_RPC_HOST") PG_CONNECTION_STRING := os.Getenv("PG_CONNECTION_STRING") FG_CONTRACT_ADDRESS := os.Getenv("FG_CONTRACT_ADDRESS") - BBN_CHAIN_TYPE := os.Getenv("BBN_CHAIN_TYPE") + BBN_CHAIN_ID := os.Getenv("BBN_CHAIN_ID") + BBN_RPC_ADDRESS := os.Getenv("BBN_RPC_ADDRESS") POLL_INTERVAL_IN_SECS := os.Getenv("POLL_INTERVAL_IN_SECS") - bbnChainType, err := strconv.Atoi(BBN_CHAIN_TYPE) - if err != nil { - fmt.Printf("error converting babylon chain type to int: %v\n", err) - } pollInterval, err := strconv.Atoi(POLL_INTERVAL_IN_SECS) if err != nil { fmt.Printf("error converting poll interval to int: %v\n", err) @@ -50,7 +47,8 @@ func main() { BitcoinRPCHost: BITCOIN_RPC_HOST, PGConnectionString: PG_CONNECTION_STRING, FGContractAddress:FG_CONTRACT_ADDRESS, - BBNChainType: bbnChainType, + BBNChainID: BBN_CHAIN_ID, + BBNRPCAddress: BBN_RPC_ADDRESS, PollInterval: time.Second * time.Duration(pollInterval), }) if err != nil { diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index 985c690..6888874 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -4,13 +4,13 @@ import ( "sync" "time" - "github.com/babylonchain/babylon-finality-gadget/sdk" + "github.com/babylonchain/babylon-finality-gadget/sdk/client" "github.com/babylonchain/babylon-finality-gadget/verifier/db" "github.com/ethereum/go-ethereum/ethclient" ) type Verifier struct { - SdkClient *sdk.BabylonFinalityGadgetClient + SdkClient *client.SdkClient L2Client *ethclient.Client Pg *db.PostgresHandler @@ -25,7 +25,8 @@ type Config struct { BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` PGConnectionString string `long:"pg-connection-string" description:"Postgres DB connection string"` FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` - BBNChainType int `long:"bbn-chain-type" description:"BabylonChain chain type"` + BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` + BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` } diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 5308173..106c6e8 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -7,8 +7,10 @@ import ( "math/big" "time" - "github.com/babylonchain/babylon-finality-gadget/btcclient" - "github.com/babylonchain/babylon-finality-gadget/sdk" + "github.com/babylonchain/babylon-finality-gadget/sdk/btcclient" + "github.com/babylonchain/babylon-finality-gadget/sdk/client" + sdkconfig "github.com/babylonchain/babylon-finality-gadget/sdk/config" + "github.com/babylonchain/babylon-finality-gadget/sdk/cwclient" "github.com/babylonchain/babylon-finality-gadget/verifier/db" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" @@ -18,10 +20,11 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { // Create finality gadget client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost - sdkClient, err := sdk.NewClient(&sdk.Config{ - ChainType: cfg.BBNChainType, - ContractAddr: cfg.FGContractAddress, + sdkClient, err := client.NewClient(&sdkconfig.Config{ BTCConfig: btcConfig, + ContractAddr: cfg.FGContractAddress, + ChainID: cfg.BBNChainID, + RPCAddr: cfg.BBNRPCAddress, }) if err != nil { return nil, fmt.Errorf("error creating client: %w", err) @@ -147,7 +150,7 @@ func (vf *Verifier) handleBlock(ctx context.Context, block *BlockInfo) { } func (vf *Verifier) queryIsBlockBabylonFinalized(ctx context.Context, block *BlockInfo) (bool, error) { - return vf.SdkClient.QueryIsBlockBabylonFinalized(&sdk.L2Block{ + return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.Hash), BlockHeight: block.Height, BlockTimestamp: block.Timestamp, From 36562c7017169f48711a377bbdebfcc25ed6d357 Mon Sep 17 00:00:00 2001 From: parketh Date: Wed, 17 Jul 2024 12:23:51 +0100 Subject: [PATCH 09/93] feat: run server inside verifier --- verifier/demo/main.go | 4 ---- verifier/verifier/verifier.go | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/verifier/demo/main.go b/verifier/demo/main.go index c18c4b6..47e39a7 100644 --- a/verifier/demo/main.go +++ b/verifier/demo/main.go @@ -8,7 +8,6 @@ import ( "strconv" "time" - "github.com/babylonchain/babylon-finality-gadget/verifier/server" "github.com/babylonchain/babylon-finality-gadget/verifier/verifier" "github.com/joho/godotenv" ) @@ -55,9 +54,6 @@ func main() { fmt.Printf("error creating verifier: %v\n", err) } - // Start server - go server.StartServer() - // Start processing blocks vf.ProcessBlocks(ctx) } \ No newline at end of file diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 106c6e8..8ff0a38 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -12,6 +12,7 @@ import ( sdkconfig "github.com/babylonchain/babylon-finality-gadget/sdk/config" "github.com/babylonchain/babylon-finality-gadget/sdk/cwclient" "github.com/babylonchain/babylon-finality-gadget/verifier/db" + "github.com/babylonchain/babylon-finality-gadget/verifier/server" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" ) @@ -46,6 +47,9 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { return nil, fmt.Errorf("create initial tables error: %w", err) } + // Start server + go server.StartServer() + // Create verifier return &Verifier{ SdkClient: sdkClient, From 607236d3e10f82b377107598c37f441aff4d01fa Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:07:48 +0800 Subject: [PATCH 10/93] fix: remove hardcode sql script --- verifier/db/db.go | 62 ++++++++++--------- .../db/migrations/0000_initial_tables.sql | 7 --- 2 files changed, 34 insertions(+), 35 deletions(-) delete mode 100644 verifier/db/migrations/0000_initial_tables.sql diff --git a/verifier/db/db.go b/verifier/db/db.go index 6565d45..64a09ac 100644 --- a/verifier/db/db.go +++ b/verifier/db/db.go @@ -3,7 +3,6 @@ package db import ( "context" "fmt" - "os" "github.com/jackc/pgx/v5" ) @@ -12,6 +11,35 @@ type PostgresHandler struct { conn *pgx.Conn } +const ( + createTablesSql = ` + CREATE TABLE IF NOT EXISTS blocks ( + block_height INTEGER PRIMARY KEY, + block_hash TEXT NOT NULL, + block_timestamp INTEGER NOT NULL, + is_finalized BOOLEAN NOT NULL + ); + CREATE INDEX IF NOT EXISTS blocks_hash_idx ON blocks (block_hash, block_timestamp); + ` + insertBlockSql = ` + INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4) + ` + getBlockStatusByHeightSql = ` + SELECT is_finalized FROM blocks WHERE block_height = $1 + ` + getBlockStatusByHashSql = ` + SELECT is_finalized FROM blocks WHERE block_hash = $1 + ` + getLatestBlockSql = ` + SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized + FROM blocks b + JOIN blocks prev ON b.block_height = prev.block_height + 1 + WHERE b.is_finalized = TRUE AND prev.is_finalized = TRUE + ORDER BY b.block_height DESC + LIMIT 1; + ` +) + func NewPostgresHandler(ctx context.Context, connString string) (*PostgresHandler, error) { conn, err := pgx.Connect(ctx, connString) if err != nil { @@ -24,17 +52,8 @@ func NewPostgresHandler(ctx context.Context, connString string) (*PostgresHandle } func (pg *PostgresHandler) TryCreateInitialTables(ctx context.Context) error { - // Load the migration file - filePath := "db/migrations/0000_initial_tables.sql" - - sqlBytes, err := os.ReadFile(filePath) - if err != nil { - return fmt.Errorf("unable to read SQL file: %v", err) - } - sql := string(sqlBytes) - // Execute the SQL statements - _, err = pg.conn.Exec(ctx, sql) + _, err := pg.conn.Exec(ctx, createTablesSql) if err != nil { return fmt.Errorf("unable to execute SQL statements: %v", err) } @@ -54,7 +73,7 @@ func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { // Insert block _, err = tx.Exec( ctx, - "INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4)", + insertBlockSql, block.BlockHeight, block.BlockHash, block.BlockTimestamp, @@ -77,10 +96,8 @@ func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { } func (pg *PostgresHandler) GetBlockStatusByHeight(ctx context.Context, blockHeight uint64) bool { - query := `SELECT is_finalized FROM blocks WHERE block_height = $1` - var isFinalized bool - err := pg.conn.QueryRow(ctx, query, blockHeight).Scan(&isFinalized) + err := pg.conn.QueryRow(ctx, getBlockStatusByHeightSql, blockHeight).Scan(&isFinalized) if err != nil { fmt.Printf("GetBlockStatusByHeight: %v\n", err) return false @@ -90,10 +107,8 @@ func (pg *PostgresHandler) GetBlockStatusByHeight(ctx context.Context, blockHeig } func (pg *PostgresHandler) GetBlockStatusByHash(ctx context.Context, blockHash string) bool { - query := `SELECT is_finalized FROM blocks WHERE block_hash = $1` - var isFinalized bool - err := pg.conn.QueryRow(ctx, query, blockHash).Scan(&isFinalized) + err := pg.conn.QueryRow(ctx, getBlockStatusByHashSql, blockHash).Scan(&isFinalized) if err != nil { fmt.Printf("GetBlockStatusByHash: %v\n", err) @@ -104,17 +119,8 @@ func (pg *PostgresHandler) GetBlockStatusByHash(ctx context.Context, blockHash s } func (pg *PostgresHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { - query := ` - SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized - FROM blocks b - JOIN blocks prev ON b.block_height = prev.block_height + 1 - WHERE b.is_finalized = TRUE AND prev.is_finalized = TRUE - ORDER BY b.block_height DESC - LIMIT 1; - ` - var block Block - err := pg.conn.QueryRow(ctx, query).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) + err := pg.conn.QueryRow(ctx, getLatestBlockSql).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) if err != nil { return nil, fmt.Errorf("unable to get latest consecutively finalized block: %v", err) } diff --git a/verifier/db/migrations/0000_initial_tables.sql b/verifier/db/migrations/0000_initial_tables.sql deleted file mode 100644 index 90c94ce..0000000 --- a/verifier/db/migrations/0000_initial_tables.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE IF NOT EXISTS blocks ( - block_height INTEGER PRIMARY KEY, - block_hash TEXT NOT NULL, - block_timestamp INTEGER NOT NULL, - is_finalized BOOLEAN NOT NULL -); -CREATE INDEX IF NOT EXISTS blocks_hash_idx ON blocks (block_hash, block_timestamp); \ No newline at end of file From 033ba5a0dbe14388b1b2b60382a56c2f20a36d7e Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:18:58 +0800 Subject: [PATCH 11/93] fix: sql to handle query non locally stored blocks --- verifier/db/db.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/verifier/db/db.go b/verifier/db/db.go index 64a09ac..262e9d9 100644 --- a/verifier/db/db.go +++ b/verifier/db/db.go @@ -25,10 +25,14 @@ const ( INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4) ` getBlockStatusByHeightSql = ` - SELECT is_finalized FROM blocks WHERE block_height = $1 - ` - getBlockStatusByHashSql = ` - SELECT is_finalized FROM blocks WHERE block_hash = $1 + SELECT COALESCE(is_finalized, false) AS is_finalized + FROM blocks + WHERE block_height = $1 + ` + getBlockStatusByHashSql = ` + SELECT COALESCE(is_finalized, false) AS is_finalized + FROM blocks + WHERE block_hash = $1 ` getLatestBlockSql = ` SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized From 6d2abd40e906da3c587afe42b68633513f67fead Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:27:59 +0800 Subject: [PATCH 12/93] Revert "fix: sql to handle query non locally stored blocks" This reverts commit 033ba5a0dbe14388b1b2b60382a56c2f20a36d7e. --- verifier/db/db.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/verifier/db/db.go b/verifier/db/db.go index 262e9d9..64a09ac 100644 --- a/verifier/db/db.go +++ b/verifier/db/db.go @@ -25,14 +25,10 @@ const ( INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4) ` getBlockStatusByHeightSql = ` - SELECT COALESCE(is_finalized, false) AS is_finalized - FROM blocks - WHERE block_height = $1 - ` - getBlockStatusByHashSql = ` - SELECT COALESCE(is_finalized, false) AS is_finalized - FROM blocks - WHERE block_hash = $1 + SELECT is_finalized FROM blocks WHERE block_height = $1 + ` + getBlockStatusByHashSql = ` + SELECT is_finalized FROM blocks WHERE block_hash = $1 ` getLatestBlockSql = ` SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized From a0ec321aa9514ea98787236ae1d0e7a54ca75995 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:32:48 +0800 Subject: [PATCH 13/93] fix: remove incorrect error check --- verifier/verifier/verifier.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 8ff0a38..aeac2fb 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -68,9 +68,6 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { // If this block already exists in our DB, skip the finality check exists := vf.Pg.GetBlockStatusByHeight(ctx, block.Height) - if err != nil { - return fmt.Errorf("error checking block %d: %v", block.Height, err) - } if !exists { // Check the block is finalized using sdk client isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) From 102f9ff75da38290bfd9547426e54d3156bcfdea Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:37:42 +0800 Subject: [PATCH 14/93] debug: add test messages --- verifier/verifier/verifier.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index aeac2fb..9656ad8 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -65,12 +65,15 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { if err != nil { return fmt.Errorf("error getting last finalized block: %v", err) } - + fmt.Printf("[ProcessBlocks] last finalized block: %d\n", block.Height) + // If this block already exists in our DB, skip the finality check exists := vf.Pg.GetBlockStatusByHeight(ctx, block.Height) + fmt.Printf("[ProcessBlocks] does latest block exist in db: %v\n", exists) if !exists { // Check the block is finalized using sdk client isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) + fmt.Printf("[ProcessBlocks] is block %d finalized: %v\n", block.Height, isFinal) // If not finalized, throw error if !isFinal { return fmt.Errorf("block %d should be finalized according to client but is not", block.Height) @@ -79,6 +82,7 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { return fmt.Errorf("error checking block %d: %v", block.Height, err) } // If finalised, store the block in DB and set the last finalized block + fmt.Printf("[ProcessBlocks] storing block %d\n", block.Height) err = vf.insertBlock(ctx, block) if err != nil { return fmt.Errorf("error storing block %d: %v", block.Height, err) From f95959169bdfca55b3678689cb1bce9db4c2c4b6 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:46:51 +0800 Subject: [PATCH 15/93] fix: handle latest finalised block 0 exception --- verifier/verifier/verifier.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 9656ad8..6c7e4d8 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -66,6 +66,14 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { return fmt.Errorf("error getting last finalized block: %v", err) } fmt.Printf("[ProcessBlocks] last finalized block: %d\n", block.Height) + + // If block height is 0, replace it with block height 1 + if block.Height == 0 { + block, err = vf.getBlockByNumber(ctx, 1) + if err != nil { + return fmt.Errorf("error getting block 1: %v", err) + } + } // If this block already exists in our DB, skip the finality check exists := vf.Pg.GetBlockStatusByHeight(ctx, block.Height) From 99a41ef74d6dac17b51fdd4c631be2f47a68fe37 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 22:47:20 +0800 Subject: [PATCH 16/93] fix: log errors in demo process --- verifier/demo/main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/verifier/demo/main.go b/verifier/demo/main.go index 47e39a7..08ae9e5 100644 --- a/verifier/demo/main.go +++ b/verifier/demo/main.go @@ -55,5 +55,8 @@ func main() { } // Start processing blocks - vf.ProcessBlocks(ctx) + err = vf.ProcessBlocks(ctx) + if err != nil { + fmt.Println(err) + } } \ No newline at end of file From f50db6a2d00167b2f9bf65501553c48090ace273 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 25 Jul 2024 23:15:13 +0800 Subject: [PATCH 17/93] fix: move server port and pg conn into configs --- verifier/demo/main.go | 5 ++++ verifier/server/handlers.go | 33 +++++------------------- verifier/server/routes.go | 16 ------------ verifier/server/server.go | 47 +++++++++++++++++++++++++++++------ verifier/verifier/types.go | 3 ++- verifier/verifier/verifier.go | 5 +++- 6 files changed, 56 insertions(+), 53 deletions(-) delete mode 100644 verifier/server/routes.go diff --git a/verifier/demo/main.go b/verifier/demo/main.go index 08ae9e5..1b4a1ba 100644 --- a/verifier/demo/main.go +++ b/verifier/demo/main.go @@ -39,6 +39,10 @@ func main() { if err != nil { fmt.Printf("error converting poll interval to int: %v\n", err) } + serverPort := os.Getenv("SERVER_PORT") + if serverPort == "" { + serverPort = "8080" + } // Create verifier vf, err := verifier.NewVerifier(ctx, &verifier.Config{ @@ -48,6 +52,7 @@ func main() { FGContractAddress:FG_CONTRACT_ADDRESS, BBNChainID: BBN_CHAIN_ID, BBNRPCAddress: BBN_RPC_ADDRESS, + ServerPort: serverPort, PollInterval: time.Second * time.Duration(pollInterval), }) if err != nil { diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go index e00a9ea..eb06575 100644 --- a/verifier/server/handlers.go +++ b/verifier/server/handlers.go @@ -5,17 +5,14 @@ import ( "encoding/json" "fmt" "net/http" - "os" "strconv" - - "github.com/babylonchain/babylon-finality-gadget/verifier/db" ) type StatusResponse struct { IsFinalized bool `json:"isFinalized"` } -func getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) { +func (s *Server) getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) { // Fetch params and run validation check blockHeightStr := r.URL.Query().Get("blockHeight") if blockHeightStr == "" { @@ -34,13 +31,7 @@ func getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) { // Fetch status from DB ctx := context.Background() - pg, err := db.NewPostgresHandler(ctx, os.Getenv("PG_CONNECTION_STRING")) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Error creating postgres handler: %v\n", err) - return - } - isFinal := pg.GetBlockStatusByHeight(ctx, uint64(blockHeight)) + isFinal := s.pg.GetBlockStatusByHeight(ctx, uint64(blockHeight)) // Marshal and return status jsonResponse, err := json.Marshal(StatusResponse { @@ -54,7 +45,7 @@ func getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) { w.Write(jsonResponse) } -func getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { +func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { // Fetch params and run validation check hash := r.URL.Query().Get("hash") if hash == "" { @@ -65,13 +56,7 @@ func getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { // Fetch status from DB ctx := context.Background() - pg, err := db.NewPostgresHandler(ctx, os.Getenv("PG_CONNECTION_STRING")) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Error creating postgres handler: %v\n", err) - return - } - isFinal := pg.GetBlockStatusByHash(ctx, hash) + isFinal := s.pg.GetBlockStatusByHash(ctx, hash) // Marshal and return status jsonResponse, err := json.Marshal(StatusResponse { @@ -85,16 +70,10 @@ func getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { w.Write(jsonResponse) } -func getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { +func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { // Fetch status from DB ctx := context.Background() - pg, err := db.NewPostgresHandler(ctx, os.Getenv("PG_CONNECTION_STRING")) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Error creating postgres handler: %v\n", err) - return - } - block, err := pg.GetLatestConsecutivelyFinalizedBlock(ctx) + block, err := s.pg.GetLatestConsecutivelyFinalizedBlock(ctx) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Error getting latest block: %v\n", err) diff --git a/verifier/server/routes.go b/verifier/server/routes.go deleted file mode 100644 index 5421b6c..0000000 --- a/verifier/server/routes.go +++ /dev/null @@ -1,16 +0,0 @@ -package server - -import ( - "github.com/gorilla/mux" -) - -func NewRouter() *mux.Router { - router := mux.NewRouter().StrictSlash(true) - - // Routes - router.HandleFunc("/getBlockStatusByHeight", getBlockStatusByHeight) - router.HandleFunc("/getBlockStatusByHash", getBlockStatusByHash) - router.HandleFunc("/getLatest", getLatestConsecutivelyFinalizedBlock) - - return router -} \ No newline at end of file diff --git a/verifier/server/server.go b/verifier/server/server.go index e3f32bc..3be5f1b 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -1,21 +1,52 @@ package server import ( + "context" + "fmt" "log" "net/http" - "os" + + "github.com/gorilla/mux" + + "github.com/babylonchain/babylon-finality-gadget/verifier/db" ) -func StartServer() { - router := NewRouter() +type Server struct { + port string + pg *db.PostgresHandler +} - port := os.Getenv("PORT") - if port == "" { - port = "8080" +type ServerConfig struct { + Port string + ConnString string +} + +func StartServer(ctx context.Context, cfg *ServerConfig) (*Server, error) { + // Create Postgres handler. + pg, err := db.NewPostgresHandler(ctx, cfg.ConnString) + if err != nil { + return nil, fmt.Errorf("failed to create postgres handler: %w", err) } - log.Printf("Starting server on port %s...", port) - if err := http.ListenAndServe(":"+port, router); err != nil { + // Define server. + s := &Server{ + port: cfg.Port, + pg: pg, + } + + // Create router. + router := mux.NewRouter().StrictSlash(true) + + // Define routes. + router.HandleFunc("/getBlockStatusByHeight", s.getBlockStatusByHeight) + router.HandleFunc("/getBlockStatusByHash", s.getBlockStatusByHash) + router.HandleFunc("/getLatest", s.getLatestConsecutivelyFinalizedBlock) + + // Start server. + log.Printf("Starting server on port %s...", cfg.Port) + if err := http.ListenAndServe(":"+cfg.Port, router); err != nil { log.Fatalf("Could not start server: %s\n", err.Error()) } + + return s, nil } \ No newline at end of file diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index 6888874..1bc976f 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -23,10 +23,11 @@ type Verifier struct { type Config struct { L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` - PGConnectionString string `long:"pg-connection-string" description:"Postgres DB connection string"` FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` + PGConnectionString string `long:"pg-connection-string" description:"Postgres DB connection string"` + ServerPort string `long:"server-port" description:"port to start the verifier server"` PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` } diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 6c7e4d8..e3a4f43 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -48,7 +48,10 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { } // Start server - go server.StartServer() + go server.StartServer(ctx, &server.ServerConfig{ + Port: cfg.ServerPort, + ConnString: cfg.PGConnectionString, + }) // Create verifier return &Verifier{ From 0bc78bc5b39cc97dce99fb7c39e2da066d6b6682 Mon Sep 17 00:00:00 2001 From: parketh Date: Fri, 26 Jul 2024 11:24:17 +0800 Subject: [PATCH 18/93] feat: add `processNBlocks` for testing, improve block handling on restart --- verifier/db/db.go | 15 +++++- verifier/demo/main.go | 1 + verifier/verifier/types.go | 3 +- verifier/verifier/verifier.go | 88 ++++++++++++++++++++++++----------- 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/verifier/db/db.go b/verifier/db/db.go index 64a09ac..e82efc7 100644 --- a/verifier/db/db.go +++ b/verifier/db/db.go @@ -31,6 +31,9 @@ const ( SELECT is_finalized FROM blocks WHERE block_hash = $1 ` getLatestBlockSql = ` + SELECT block_height, block_hash, block_timestamp, is_finalized FROM blocks ORDER BY block_height DESC LIMIT 1 + ` + getLatestConsecutivelyFinalizedBlockSql = ` SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized FROM blocks b JOIN blocks prev ON b.block_height = prev.block_height + 1 @@ -118,9 +121,19 @@ func (pg *PostgresHandler) GetBlockStatusByHash(ctx context.Context, blockHash s return isFinalized } -func (pg *PostgresHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { +func (pg *PostgresHandler) GetLatestBlock(ctx context.Context) (*Block, error) { var block Block err := pg.conn.QueryRow(ctx, getLatestBlockSql).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) + if err != nil { + return nil, fmt.Errorf("unable to get latest block: %v", err) + } + + return &block, nil +} + +func (pg *PostgresHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { + var block Block + err := pg.conn.QueryRow(ctx, getLatestConsecutivelyFinalizedBlockSql).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) if err != nil { return nil, fmt.Errorf("unable to get latest consecutively finalized block: %v", err) } diff --git a/verifier/demo/main.go b/verifier/demo/main.go index 1b4a1ba..ec0493d 100644 --- a/verifier/demo/main.go +++ b/verifier/demo/main.go @@ -11,6 +11,7 @@ import ( "github.com/babylonchain/babylon-finality-gadget/verifier/verifier" "github.com/joho/godotenv" ) + func main() { ctx := context.Background() diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index 1bc976f..b751667 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -17,7 +17,8 @@ type Verifier struct { Mutex sync.Mutex PollInterval time.Duration - blockHeight uint64 + startHeight uint64 + currHeight uint64 } type Config struct { diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index e3a4f43..6668b31 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -62,7 +62,44 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { }, nil } +// This function process blocks indefinitely, starting from the last finalized block. func (vf *Verifier) ProcessBlocks(ctx context.Context) error { + return vf.ProcessNBlocks(ctx, -1) +} + +// This function process n blocks, starting from the last finalized block. +// n is the number of blocks to process, pass in -1 to process blocks indefinitely. +// Passing in non-negative n is useful for testing. +func (vf *Verifier) ProcessNBlocks(ctx context.Context, n int) error { + // Start service at last finalized block + err := vf.startService(ctx) + if err != nil { + return fmt.Errorf("%v", err) + } + + // Start polling for new blocks at set interval + ticker := time.NewTicker(vf.PollInterval) + for range ticker.C { + // If n is positive and we have processed n blocks, stop the process + if n > 0 && vf.currHeight == vf.startHeight + uint64(n - 1) { + break + } + fmt.Printf("polling for new block at height %d\n", vf.currHeight + 1) + block, err := vf.getBlockByNumber(ctx, int64(vf.currHeight + 1)) + if err != nil { + fmt.Printf("error getting new block: %v\n", err) + continue + } + go func() { + vf.handleBlock(ctx, block) + }() + } + + return nil +} + +// Start service at last finalized block +func (vf *Verifier) startService(ctx context.Context) error { // Query L2 node for last finalized block block, err := vf.getLatestFinalizedBlock(ctx) if err != nil { @@ -70,18 +107,28 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { } fmt.Printf("[ProcessBlocks] last finalized block: %d\n", block.Height) - // If block height is 0, replace it with block height 1 - if block.Height == 0 { - block, err = vf.getBlockByNumber(ctx, 1) - if err != nil { - return fmt.Errorf("error getting block 1: %v", err) - } + // Query local DB for last block processed + localBlock, err := vf.Pg.GetLatestBlock(ctx) + if err != nil { + return fmt.Errorf("error getting latest block from db: %v", err) } + + // if local chain tip is ahead of node, start service at latest block + if localBlock.BlockHeight >= block.Height { + block = &BlockInfo{ + Height: localBlock.BlockHeight, + Hash: localBlock.BlockHash, + Timestamp: localBlock.BlockTimestamp, + } + } else { + // If block height is 0, replace it with block height 1 + if block.Height == 0 { + block, err = vf.getBlockByNumber(ctx, 1) + if err != nil { + return fmt.Errorf("error getting block 1: %v", err) + } + } - // If this block already exists in our DB, skip the finality check - exists := vf.Pg.GetBlockStatusByHeight(ctx, block.Height) - fmt.Printf("[ProcessBlocks] does latest block exist in db: %v\n", exists) - if !exists { // Check the block is finalized using sdk client isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) fmt.Printf("[ProcessBlocks] is block %d finalized: %v\n", block.Height, isFinal) @@ -103,22 +150,9 @@ func (vf *Verifier) ProcessBlocks(ctx context.Context) error { // Start service at block height fmt.Printf("starting service at block %d\n", block.Height) - // Store the last finalized block height in memory - vf.blockHeight = block.Height - - // Start polling for new blocks at set interval - ticker := time.NewTicker(vf.PollInterval) - for range ticker.C { - fmt.Printf("polling for new block at height %d\n", vf.blockHeight + 1) - block, err := vf.getBlockByNumber(ctx, int64(vf.blockHeight + 1)) - if err != nil { - fmt.Printf("error getting new block: %v\n", err) - continue - } - go func() { - vf.handleBlock(ctx, block) - }() - } + // Set the start block and curr finalized block in memory + vf.startHeight = block.Height + vf.currHeight = block.Height return nil } @@ -187,7 +221,7 @@ func (vf *Verifier) insertBlock(ctx context.Context, block *BlockInfo) error { return err } // Set last finalized block in memory - vf.blockHeight = block.Height + vf.currHeight = block.Height // Unlock mutex vf.Mutex.Unlock() From 1a197c140f14d20c193c9aac45ff82697ed4491c Mon Sep 17 00:00:00 2001 From: parketh Date: Fri, 26 Jul 2024 11:38:57 +0800 Subject: [PATCH 19/93] fix: handle non-existent local block --- verifier/db/db.go | 4 ++++ verifier/verifier/verifier.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/verifier/db/db.go b/verifier/db/db.go index e82efc7..2583e02 100644 --- a/verifier/db/db.go +++ b/verifier/db/db.go @@ -125,6 +125,10 @@ func (pg *PostgresHandler) GetLatestBlock(ctx context.Context) (*Block, error) { var block Block err := pg.conn.QueryRow(ctx, getLatestBlockSql).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) if err != nil { + if err == pgx.ErrNoRows { + // If no rows are returned, return a block with BlockHeight = 0 + return &Block{BlockHeight: 0}, nil + } return nil, fmt.Errorf("unable to get latest block: %v", err) } diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 6668b31..a511159 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -114,7 +114,7 @@ func (vf *Verifier) startService(ctx context.Context) error { } // if local chain tip is ahead of node, start service at latest block - if localBlock.BlockHeight >= block.Height { + if localBlock.BlockHeight != 0 && localBlock.BlockHeight >= block.Height { block = &BlockInfo{ Height: localBlock.BlockHeight, Hash: localBlock.BlockHash, From 709e3e427bdb08fd73dd07d0db7808494abf33bf Mon Sep 17 00:00:00 2001 From: parketh Date: Fri, 26 Jul 2024 15:05:21 +0800 Subject: [PATCH 20/93] chore: remove debugging logs --- verifier/verifier/verifier.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index a511159..5f48cc0 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -84,7 +84,6 @@ func (vf *Verifier) ProcessNBlocks(ctx context.Context, n int) error { if n > 0 && vf.currHeight == vf.startHeight + uint64(n - 1) { break } - fmt.Printf("polling for new block at height %d\n", vf.currHeight + 1) block, err := vf.getBlockByNumber(ctx, int64(vf.currHeight + 1)) if err != nil { fmt.Printf("error getting new block: %v\n", err) @@ -105,7 +104,6 @@ func (vf *Verifier) startService(ctx context.Context) error { if err != nil { return fmt.Errorf("error getting last finalized block: %v", err) } - fmt.Printf("[ProcessBlocks] last finalized block: %d\n", block.Height) // Query local DB for last block processed localBlock, err := vf.Pg.GetLatestBlock(ctx) @@ -131,7 +129,6 @@ func (vf *Verifier) startService(ctx context.Context) error { // Check the block is finalized using sdk client isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) - fmt.Printf("[ProcessBlocks] is block %d finalized: %v\n", block.Height, isFinal) // If not finalized, throw error if !isFinal { return fmt.Errorf("block %d should be finalized according to client but is not", block.Height) @@ -140,7 +137,6 @@ func (vf *Verifier) startService(ctx context.Context) error { return fmt.Errorf("error checking block %d: %v", block.Height, err) } // If finalised, store the block in DB and set the last finalized block - fmt.Printf("[ProcessBlocks] storing block %d\n", block.Height) err = vf.insertBlock(ctx, block) if err != nil { return fmt.Errorf("error storing block %d: %v", block.Height, err) @@ -179,7 +175,6 @@ func (vf *Verifier) handleBlock(ctx context.Context, block *BlockInfo) { // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { - fmt.Printf("checking finality of block %d\n", block.Height) // Check if block is finalized isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) if err != nil { From afbaa4560ee5a41bdf16409cd68c70ee86386629 Mon Sep 17 00:00:00 2001 From: parketh Date: Fri, 26 Jul 2024 15:34:29 +0800 Subject: [PATCH 21/93] chore: fix lint errors --- verifier/db/models.go | 2 +- verifier/server/handlers.go | 12 +++++++++--- verifier/server/server.go | 2 +- verifier/verifier/types.go | 2 +- verifier/verifier/verifier.go | 12 ++++++++---- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/verifier/db/models.go b/verifier/db/models.go index a0a1624..35ecb08 100644 --- a/verifier/db/models.go +++ b/verifier/db/models.go @@ -1,8 +1,8 @@ package db type Block struct { - BlockHeight uint64 `json:"block_height" description:"block height"` BlockHash string `json:"block_hash" description:"block hash"` + BlockHeight uint64 `json:"block_height" description:"block height"` BlockTimestamp uint64 `json:"block_timestamp" description:"block timestamp"` IsFinalized bool `json:"is_finalized" description:"babylon block finality status"` } \ No newline at end of file diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go index eb06575..8a3c7f5 100644 --- a/verifier/server/handlers.go +++ b/verifier/server/handlers.go @@ -42,7 +42,9 @@ func (s *Server) getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) return } w.Header().Set("Content-Type", "application/json") - w.Write(jsonResponse) + if _, err := w.Write(jsonResponse); err != nil { + http.Error(w, "unable to write JSON response", http.StatusInternalServerError) + } } func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { @@ -67,7 +69,9 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { return } w.Header().Set("Content-Type", "application/json") - w.Write(jsonResponse) + if _, err := w.Write(jsonResponse); err != nil { + http.Error(w, "unable to write JSON response", http.StatusInternalServerError) + } } func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { @@ -87,6 +91,8 @@ func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r * return } w.Header().Set("Content-Type", "application/json") - w.Write(jsonResponse) + if _, err := w.Write(jsonResponse); err != nil { + http.Error(w, "unable to write JSON response", http.StatusInternalServerError) + } } diff --git a/verifier/server/server.go b/verifier/server/server.go index 3be5f1b..8118381 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -12,8 +12,8 @@ import ( ) type Server struct { - port string pg *db.PostgresHandler + port string } type ServerConfig struct { diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index b751667..05abc39 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -33,7 +33,7 @@ type Config struct { } type BlockInfo struct { - Height uint64 Hash string + Height uint64 Timestamp uint64 } \ No newline at end of file diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 5f48cc0..bed5cd8 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -48,10 +48,14 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { } // Start server - go server.StartServer(ctx, &server.ServerConfig{ - Port: cfg.ServerPort, - ConnString: cfg.PGConnectionString, - }) + go func() { + if _, err := server.StartServer(ctx, &server.ServerConfig{ + Port: cfg.ServerPort, + ConnString: cfg.PGConnectionString, + }); err != nil { + fmt.Printf("error starting server: %v\n", err) + } + }() // Create verifier return &Verifier{ From ac5146875bedddcf5d1917ff07b8652214d8d5fb Mon Sep 17 00:00:00 2001 From: parketh Date: Sat, 27 Jul 2024 16:41:12 +0800 Subject: [PATCH 22/93] feat: refactor to bbolt db --- go.mod | 2 +- go.sum | 8 +- verifier/data.db | Bin 0 -> 262144 bytes verifier/db/bbolt.go | 245 +++++++++++++++++++++++++++++ verifier/db/{db.go => postgres.go} | 2 + verifier/demo/main.go | 4 +- verifier/server/handlers.go | 6 +- verifier/server/server.go | 15 +- verifier/verifier/types.go | 4 +- verifier/verifier/verifier.go | 19 +-- 10 files changed, 274 insertions(+), 31 deletions(-) create mode 100644 verifier/data.db create mode 100644 verifier/db/bbolt.go rename verifier/db/{db.go => postgres.go} (99%) diff --git a/go.mod b/go.mod index 2a645a6..f112162 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/jackc/pgx/v5 v5.6.0 github.com/joho/godotenv v1.5.1 github.com/stretchr/testify v1.9.0 + go.etcd.io/bbolt v1.3.10 go.uber.org/mock v0.4.0 go.uber.org/zap v1.26.0 ) @@ -212,7 +213,6 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect - go.etcd.io/bbolt v1.3.8 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect diff --git a/go.sum b/go.sum index 60387ab..6314048 100644 --- a/go.sum +++ b/go.sum @@ -560,8 +560,9 @@ github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u1 github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= +github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -1179,8 +1180,8 @@ github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWp github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= +go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1440,6 +1441,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/verifier/data.db b/verifier/data.db new file mode 100644 index 0000000000000000000000000000000000000000..6975fc195a11f32b770d752002aec06cfeab13c4 GIT binary patch literal 262144 zcmeI*JFI0{edqD(@-Q$nFm4aF9$Aga1) z8bdnb zs$1v&?>={(|NiXt+NWyob#-;~_;<(Wzy8+S|N7qH`{!JWca&xh;&pVHSM{+MF@xw_U@`^2aEZ@q9m zU%Y?)=%M1D`?z=Yo;QDP^p4LddU6AS>s|b%UHsZEeoA@X{{0W{;@{cDU){xjyNlne zJ0ILG@8i4p4|nm`ck$bFhlJa||J*KqWfy;W7ysohez&A=m-qZG{^BnF^Id%P*1Nx- zck!op@t^GC*LU%+=|J7i=OerL_jd8ucJUj#*!+jPc1r?SZa1O_aTKkkLA4ICgZ2eTa9_PSV!H`(y!Q1t@XBKx5ef{S)m(W;?ncf zJ}0N5Z73$*l(QaL6;X?EHm>N`YGIV#%u3buP?L|@=Ha*1+>9-5xz)CMi_KJL%Un

;8A_D7AW<1XN?|YxxjUOQwVpay2H^FnrwNN=|O6c$}7V-_RYBHLn~uVx4bE_)|^XTCf1dke&?o~>o;60F|RERx6BMJ`Bm+h z%E)@}V@-V~ z)R#4?z=!_yP!C_*R5`ZI#L!on-PUdSna8HGdNe+Tq^db*(3{1fs-R=ia^A8klPZk< zx+&+uv)-9#Rf(Lcv&&YMuWdDLu?MH>tfLon1cHsun6TwpwlR${Hf?6he#~P%y#H$5>MLzQMI8C8}r zm#NyHv0`?s%G|hA=B6q!qY#y)TD02EW^5~AYsYr_;C-R@Hu`?Qu8r+X4NBQSIj6)h|cM!u~|KZEj86m-;1;T=<|bAXGlHi znC3jIS5M}ZQHv$1ljt%|u{y7J5>xG4RUP$asEX<6tIsLNa=w+L^}*I`)jnDdKB>-z zp{Cukkz4U8_vqHL`bkSYn{JGcJvJS*qS|tFeo56Xw-r`(?NGd4yRD*LE4#L4ZRXI$ zZ+24&)8^Q`x_uK|Rl6%ub>m6<`bO4%SvAz@d+RB$9#!iO?OfH)2Gf#uZ5FlqHReby z*EXHA>Sa}QEPWjF`GWR)YeO%r&ZVK=J9*V&)wwjbqMjx+)pfJF`alg%hl6y08#=sB zov%Oc*Y%G|RS#HOSKr(>HA&;usWm&*$Iql1o5Z03Md_*~PE)6TqNKZe6=O>Y$9!Hb zZM0yNbQhZw>WJz{y|i(s_9*6!p_Y$Z2Y_Ixf+P3v&m(xz#nP%RO?Q6ZFrmsFCOnrr^JyBVzeVbLg zblvEc#rM(FdNfw68<5@_MR59)HG)6M=lkjjwA*VowGZ_^8Wi;Yt#lRR4?}oY9WvXT zLek!hnbQ_j53<_Xrb_z6`KRiwy@pw*{qr2hsaYs^H|}~2S;m+Q$-Wz2x9N9NA-lNJZ8iZhT2`w0NG1dKcq42 zrkn>K7+#0(u>W06M{l+1)v;?ZI~>ANM5g!9;I)~l-b7VdS=Sz z`Ox~erWEQ5>S-mUnON6sU}{*X>S~-(&wh0N+2fOjhnh&=d3>Tinhzhn@Oa~$4Yz`O zSNGnG-mUL6`F-BoKAiofM=!qoWG43P;T1d(KmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009IL_%|z{tKlC%o;qIt|CVEXxUlB%(AD5P5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zK;U0k;K?GK_paXa<~td!v8h$tum0EZCx5n!e^WONxV`_x$SJ`2X(Ww?4l<^ZBPAuiN^Ksph=+S3h zn*ZZaiviy_s5rS?dXFvE_I&#e6Qs?Ocj4?NYpS3GkCC>R8^?sGoD7OE{O} z%exe{Z1NUXbV-YbYfboMw3hb>hsExVq_jG?Nt`y5*^K04-L$T>UVJJ= zYtE&pT5!59es-6lmj5oQz$SVfL%p|hi*_|FvOQL@Tkk8*Vr|nh)>^dP4Wq^3ZOFc9 zJ?5p=xKF02>ULW3Y;$>Km*S;sho4N*olY^Dv(4pmyA&^7=K5rcY7wUtqdD7LUfrd5 z>5A|tQ}pLjJlkA8ze_P_NpC;YP)g9k@LPzXIxXp~rO`K6U5&ojGPJ~c)gtO{Gg^1N zdo5tD<;GVDT0Z<_ipt`&;@Rf%gN0TWKwAt28&WYirhKvg=7p z*=q^)X>)8^Dqg*ltE+0&`rwNB`6+rAPuInygK?(Qx&PWOMK}8( zF_%*3rc^>(+U|-?_Hb}pb<4RKmo?p`(=i%RiaUA+IzU5cg#y^}9m?S9rVs_~}H z=rqVxqw#yQVoL|gvemJ=--?!H8Tg_whW^6U713%P^lPR9Ai%RiqUHtYgMX%YB)m*}r zY+bgo+NSs4Vh=7%yL<@F#$cl}CTw|@ZA@c~J=CY{$2>8*s4kwK>8Ng>>$>lMXP2TR zYAr^2ERBJyg;9DlD^(5NRbz3s8k)DI1{7NqY;CKz*i3b{%+=~i#nUsLL-RY=T)w+Y zG4!5X@vCa+tw95`ts}>7)moFrYZ>cc+pd{cT5IWr(;nJ%9Yr&?Xx7OTPtSCe;@Rf% zy#&Y)XAC2U90gNWn_+o7tJU#pA)1`ljB$)KN?3WRqs(JQO*GARD#dhqrlSVx{J~nQ9QekER__EB9k1-_|I_Xf_+N+WyG{olehm zl;YXu^7<~t;f*ba6uKH~&ubfT#O{{SXwpkj*0T${3icBXldRS(DOXFm7&*REljjHF*{@N>hb(PCt#!>M3lgsXO<*INMJi z=yRisJKJ1-xJ$9L(ZXXgb;mB{K4SF2TU&Ffd3l#oOnH-E^v1VMRkg?DZ1a9?YGEf+ zJU6~mttHJ>ecBz)c`h~18bNzb5pi@yHJE=8Rr`MG(w)!x+t4wbQoqG?Qyev8TLfNNxIxtr3a`l6tD z{8TZC1+crhL_EC4IMq?UJqy0*$Gmns+z5gHQn;2 z#Hy4_UMAKh!+5G+)VO(aN}KeCXGWLnpYBrBSnQ_J8H^6N&i|B0SHmq`-J(BCX8P#G zY;)@TRE=cJoVK6=EUOFOG{-nu7sHtro%6XCef_gtifid?Gu4r#ubxp;*Qj|`)}FQ; zR1vpP>k2wm(4jE=_7z#+~LfsR(;Sj)lRBibyNFN_Y_j7rzT?>?oZZ5rFiZ@Kls2d z#jbO`JT=IT6*iqyMQe=H$%*>s5!91+*P}j%&|x+j8pF`26GE=Nbj^6wWKJCD98UL( zO7ZN0erA`V9i{3Mi4;mwx7T&dgJw6$sNYd0I`%aTA2(G8eW+tKT-qGejYo|vZqx3a zN->`97nS0{D!`pPbU_1GjSr`dq*G;MrY@>asPam>BvhI^1rW$2INk15ult80DTT+w&^_$uv(ihu57e{+H7^s2)J>W9a*ZZ7bgo}a{D+QqN! z;-{47?bm;J7yr&K{^~CN+g>6QP-a$dglO4*xo?!R{F|F^y==fSg=UeI~W z=i8UwcHrpq*-J0GIPTZ`F1^I^xL@DB^b+>tetrJZ>nV@q5_;gdwgAZJK1@Y16^-FJ2 zbW_fHcSye4;+m9i3iyyz$P4Tfx1ndv8YX)_0ox zzIo>GE`6^%T|JI(%2J^D--Bn5CHGH#^5N_+J$muwdED~B!!r*A5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**{>=&; zE}%I)o;qIt|K#!-T_ykcp{v1pAb block + err := bb.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(blocksBucket)) + key := itob(block.BlockHeight) + blockBytes, err := json.Marshal(block) + if err != nil { + return err + } + return b.Put(key, blockBytes) + }) + if err != nil { + fmt.Printf("Error inserting block: %v\n", err) + return err + } + + // Store mapping hash -> number + err = bb.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(blockHeightsBucket)) + return b.Put([]byte(block.BlockHash), itob(block.BlockHeight)) + }) + if err != nil { + fmt.Printf("Error inserting block: %v\n", err) + return err + } + + // Get current latest block + latestBlock, err := bb.GetLatestBlock(ctx) + if err != nil { + fmt.Printf("Error getting latest block: %v\n", err) + return err + } + + // Update latest block if it's the latest + err = bb.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(latestBlockBucket)) + if err != nil { + fmt.Printf("Error getting latest block: %v\n", err) + return err + } + if latestBlock.BlockHeight < block.BlockHeight { + fmt.Printf("Updating latest block: %v\n", block.BlockHeight) + return b.Put([]byte(latestBlockKey), itob(block.BlockHeight)) + } + return nil + }) + if err != nil { + fmt.Printf("Error updating latest block: %v\n", err) + return err + } + + // Update latest consecutive block if it's the latest and it's consecutive to + // the previous one + err = bb.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(latestBlockBucket)) + if latestBlock.BlockHeight == block.BlockHeight-1 { + return b.Put([]byte(latestConsecutiveBlockKey), itob(block.BlockHeight)) + } + return nil + }) + if err != nil { + fmt.Printf("Error updating latest block: %v\n", err) + return err + } + + return nil +} + +func (bb *BBoltHandler) GetBlockByHeight(ctx context.Context, height uint64) (*Block, error) { + var block Block + err := bb.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(blocksBucket)) + v := b.Get(itob(height)) + if v == nil { + return ErrBlockNotFound + } + return json.Unmarshal(v, &block) + }) + if err != nil { + fmt.Printf("Error getting block by %d\n", err) + return nil, err + } + return &block, nil +} + +func (bb *BBoltHandler) GetBlockStatusByHeight(ctx context.Context, height uint64) bool { + block, err := bb.GetBlockByHeight(ctx, height) + if err != nil { + return false + } + return block.IsFinalized +} + +func (bb *BBoltHandler) GetBlockStatusByHash(ctx context.Context, hash string) bool { + // Fetch block number by hash + var blockHeight uint64 + err := bb.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(blockHeightsBucket)) + blockHeight = btoi(b.Get([]byte(hash))) + return nil + }) + if err != nil { + fmt.Printf("Error getting block by hash: %v\n", err) + return false + } + + return bb.GetBlockStatusByHeight(ctx, blockHeight) +} + +func (bb *BBoltHandler) GetLatestBlock(ctx context.Context) (*Block, error) { + var latestBlockHeight uint64 + + // Fetch latest block height + err := bb.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(latestBlockBucket)) + v := b.Get([]byte(latestBlockKey)) + if v == nil { + return ErrBlockNotFound + } + latestBlockHeight = btoi(v) + return nil + }) + if err != nil { + // If no latest block has been stored yet, return empty block (block 0) + if errors.Is(err, ErrBlockNotFound) { + return &Block{ + BlockHeight: 0, + BlockHash: "", + IsFinalized: false, + }, nil + } + fmt.Printf("Error getting latest block: %v\n", err) + return nil, err + } + + // Fetch latest block by height + return bb.GetBlockByHeight(ctx, latestBlockHeight) +} + +func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { + var latestBlockHeight uint64 + err := bb.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(latestBlockBucket)) + v := b.Get([]byte(latestConsecutiveBlockKey)) + if v == nil { + return ErrBlockNotFound + } + latestBlockHeight = btoi(v) + return nil + }) + if err != nil { + fmt.Printf("Error getting latest block: %v\n", err) + return nil, err + } + return bb.GetBlockByHeight(ctx, latestBlockHeight) +} + +func (bb *BBoltHandler) Close() error { + return bb.db.Close() +} + +func itob(v uint64) []byte { + buf := new(bytes.Buffer) + err := binary.Write(buf, binary.BigEndian, v) + if err != nil { + fmt.Printf("Error writing to buffer: %v\n", err) + } + return buf.Bytes() + } + +func btoi(b []byte) uint64 { + var v uint64 + buf := bytes.NewReader(b) + err := binary.Read(buf, binary.BigEndian, &v) + if err != nil { + fmt.Printf("Error reading from buffer: %v\n", err) + } + return v +} \ No newline at end of file diff --git a/verifier/db/db.go b/verifier/db/postgres.go similarity index 99% rename from verifier/db/db.go rename to verifier/db/postgres.go index 2583e02..f4f7548 100644 --- a/verifier/db/db.go +++ b/verifier/db/postgres.go @@ -1,3 +1,5 @@ +// DEPRECATED - use bbolt.go instead + package db import ( diff --git a/verifier/demo/main.go b/verifier/demo/main.go index ec0493d..fb649ad 100644 --- a/verifier/demo/main.go +++ b/verifier/demo/main.go @@ -30,7 +30,7 @@ func main() { // Import and parse env vars L2_RPC_HOST := os.Getenv("L2_RPC_HOST") BITCOIN_RPC_HOST := os.Getenv("BITCOIN_RPC_HOST") - PG_CONNECTION_STRING := os.Getenv("PG_CONNECTION_STRING") + DB_FILE_PATH := os.Getenv("DB_FILE_PATH") FG_CONTRACT_ADDRESS := os.Getenv("FG_CONTRACT_ADDRESS") BBN_CHAIN_ID := os.Getenv("BBN_CHAIN_ID") BBN_RPC_ADDRESS := os.Getenv("BBN_RPC_ADDRESS") @@ -49,7 +49,7 @@ func main() { vf, err := verifier.NewVerifier(ctx, &verifier.Config{ L2RPCHost: L2_RPC_HOST, BitcoinRPCHost: BITCOIN_RPC_HOST, - PGConnectionString: PG_CONNECTION_STRING, + DBFilePath: DB_FILE_PATH, FGContractAddress:FG_CONTRACT_ADDRESS, BBNChainID: BBN_CHAIN_ID, BBNRPCAddress: BBN_RPC_ADDRESS, diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go index 8a3c7f5..430f8ce 100644 --- a/verifier/server/handlers.go +++ b/verifier/server/handlers.go @@ -31,7 +31,7 @@ func (s *Server) getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) // Fetch status from DB ctx := context.Background() - isFinal := s.pg.GetBlockStatusByHeight(ctx, uint64(blockHeight)) + isFinal := s.db.GetBlockStatusByHeight(ctx, uint64(blockHeight)) // Marshal and return status jsonResponse, err := json.Marshal(StatusResponse { @@ -58,7 +58,7 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { // Fetch status from DB ctx := context.Background() - isFinal := s.pg.GetBlockStatusByHash(ctx, hash) + isFinal := s.db.GetBlockStatusByHash(ctx, hash) // Marshal and return status jsonResponse, err := json.Marshal(StatusResponse { @@ -77,7 +77,7 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { // Fetch status from DB ctx := context.Background() - block, err := s.pg.GetLatestConsecutivelyFinalizedBlock(ctx) + block, err := s.db.GetLatestConsecutivelyFinalizedBlock(ctx) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Error getting latest block: %v\n", err) diff --git a/verifier/server/server.go b/verifier/server/server.go index 8118381..deae520 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -2,7 +2,6 @@ package server import ( "context" - "fmt" "log" "net/http" @@ -12,26 +11,20 @@ import ( ) type Server struct { - pg *db.PostgresHandler + db *db.BBoltHandler port string } type ServerConfig struct { - Port string - ConnString string + Db *db.BBoltHandler + Port string } func StartServer(ctx context.Context, cfg *ServerConfig) (*Server, error) { - // Create Postgres handler. - pg, err := db.NewPostgresHandler(ctx, cfg.ConnString) - if err != nil { - return nil, fmt.Errorf("failed to create postgres handler: %w", err) - } - // Define server. s := &Server{ port: cfg.Port, - pg: pg, + db: cfg.Db, } // Create router. diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index 05abc39..1556412 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -12,7 +12,7 @@ import ( type Verifier struct { SdkClient *client.SdkClient L2Client *ethclient.Client - Pg *db.PostgresHandler + Db *db.BBoltHandler Mutex sync.Mutex @@ -27,7 +27,7 @@ type Config struct { FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` - PGConnectionString string `long:"pg-connection-string" description:"Postgres DB connection string"` + DBFilePath string `long:"db-file-path" description:"path to the DB file"` ServerPort string `long:"server-port" description:"port to start the verifier server"` PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` } diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index bed5cd8..d766ed1 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -38,20 +38,21 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { } // Create local DB for storing and querying blocks - pg, err := db.NewPostgresHandler(ctx, cfg.PGConnectionString) + db, err := db.NewBBoltHandler(ctx, cfg.DBFilePath) if err != nil { - return nil, fmt.Errorf("failed to create postgres handler: %w", err) + return nil, fmt.Errorf("failed to create DB handler: %w", err) } - err = pg.TryCreateInitialTables(ctx) + defer db.Close() + err = db.TryCreateInitialBuckets(ctx) if err != nil { - return nil, fmt.Errorf("create initial tables error: %w", err) + return nil, fmt.Errorf("create initial buckets error: %w", err) } // Start server go func() { if _, err := server.StartServer(ctx, &server.ServerConfig{ - Port: cfg.ServerPort, - ConnString: cfg.PGConnectionString, + Port: cfg.ServerPort, + Db: db, }); err != nil { fmt.Printf("error starting server: %v\n", err) } @@ -61,7 +62,7 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { return &Verifier{ SdkClient: sdkClient, L2Client: l2Client, - Pg: pg, + Db: db, PollInterval: cfg.PollInterval, }, nil } @@ -110,7 +111,7 @@ func (vf *Verifier) startService(ctx context.Context) error { } // Query local DB for last block processed - localBlock, err := vf.Pg.GetLatestBlock(ctx) + localBlock, err := vf.Db.GetLatestBlock(ctx) if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } @@ -210,7 +211,7 @@ func (vf *Verifier) insertBlock(ctx context.Context, block *BlockInfo) error { // Lock mutex vf.Mutex.Lock() // Store block in DB - err := vf.Pg.InsertBlock(ctx, db.Block{ + err := vf.Db.InsertBlock(ctx, db.Block{ BlockHeight: block.Height, BlockHash: block.Hash, BlockTimestamp: block.Timestamp, From bdae82c9ad20f76578c964e064baf568b51ceb3b Mon Sep 17 00:00:00 2001 From: parketh Date: Sun, 28 Jul 2024 09:30:01 +0800 Subject: [PATCH 23/93] fix: throw if block height is 0 --- verifier/verifier/verifier.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index d766ed1..3c4d4ca 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -124,12 +124,9 @@ func (vf *Verifier) startService(ctx context.Context) error { Timestamp: localBlock.BlockTimestamp, } } else { - // If block height is 0, replace it with block height 1 + // throw if block height is 0 if block.Height == 0 { - block, err = vf.getBlockByNumber(ctx, 1) - if err != nil { - return fmt.Errorf("error getting block 1: %v", err) - } + return fmt.Errorf("block height 0") } // Check the block is finalized using sdk client From 43e997c883f672334e895ec38d371a9a46e72e5a Mon Sep 17 00:00:00 2001 From: parketh Date: Sun, 28 Jul 2024 09:34:02 +0800 Subject: [PATCH 24/93] docs: update verifier readme --- verifier/README.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/verifier/README.md b/verifier/README.md index 89c11af..eb6eac4 100644 --- a/verifier/README.md +++ b/verifier/README.md @@ -2,7 +2,7 @@ This is a peripheral program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks via RESTful API endpoints. It is served as a Docker container for local use or hosted on a server. -## Running the Docker container +## Running the daemon To get started, clone the repository and navigate to the `/verifier` directory. @@ -16,16 +16,26 @@ Create a `.env` file in the `/verifier` directory with the following content: ```bash L2_RPC_HOST= BITCOIN_RPC_HOST= -PG_CONNECTION_STRING= +DB_FILE_PATH= FG_CONTRACT_ADDRESS= -BBN_CHAIN_TYPE= +BBN_CHAIN_ID= +BBN_RPC_ADDRESS= POLL_INTERVAL_IN_SECS= ``` -Make sure you have Docker installed locally. If you don't, you can download it [here](https://www.docker.com/products/docker-desktop). +To run the demo program: + +```bash +cd verifier +go run demo/main.go +``` + + + + From 79b58ee5b3de7651e58298bb0d915ec9cdda5603 Mon Sep 17 00:00:00 2001 From: parketh Date: Sun, 28 Jul 2024 09:36:40 +0800 Subject: [PATCH 25/93] fix: gitignore .db --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cf0957f..acce1e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ **/target/ .DS_Store -*/.env \ No newline at end of file +**/.env +**/.db \ No newline at end of file From 1030a5d2bb2789d42746a649f32edb683bce375b Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 13:35:49 +0800 Subject: [PATCH 26/93] feat: create cli daemon and config file --- go.mod | 5 +-- go.sum | 2 - verifier/cmd/cmd.go | 20 ++++++++++ verifier/cmd/main.go | 37 +++++++++++++++++ verifier/cmd/start.go | 72 ++++++++++++++++++++++++++++++++++ verifier/config.toml | 8 ++++ verifier/config/config.go | 34 ++++++++++++++++ verifier/data.db | Bin 262144 -> 131072 bytes verifier/db/bbolt.go | 28 ++++++------- verifier/demo/main.go | 68 -------------------------------- verifier/server/handlers.go | 10 ++--- verifier/server/server.go | 3 +- verifier/verifier/types.go | 11 ------ verifier/verifier/verifier.go | 68 ++++++++++++-------------------- 14 files changed, 215 insertions(+), 151 deletions(-) create mode 100644 verifier/cmd/cmd.go create mode 100644 verifier/cmd/main.go create mode 100644 verifier/cmd/start.go create mode 100644 verifier/config.toml create mode 100644 verifier/config/config.go delete mode 100644 verifier/demo/main.go diff --git a/go.mod b/go.mod index f112162..0bb71bb 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,8 @@ require ( github.com/ethereum/go-ethereum v1.13.15 github.com/gorilla/mux v1.8.1 github.com/jackc/pgx/v5 v5.6.0 - github.com/joho/godotenv v1.5.1 + github.com/spf13/cobra v1.8.0 + github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 go.etcd.io/bbolt v1.3.10 go.uber.org/mock v0.4.0 @@ -197,9 +198,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect github.com/strangelove-ventures/cometbft-client v0.1.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect diff --git a/go.sum b/go.sum index 6314048..4647e28 100644 --- a/go.sum +++ b/go.sum @@ -814,8 +814,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= diff --git a/verifier/cmd/cmd.go b/verifier/cmd/cmd.go new file mode 100644 index 0000000..dad14d8 --- /dev/null +++ b/verifier/cmd/cmd.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" +) + +// Runs cmd with client context and returns an error. +func runEWithClientCtx( + fRunWithCtx func(ctx client.Context, cmd *cobra.Command, args []string) error, +) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + return fRunWithCtx(clientCtx, cmd, args) + } +} diff --git a/verifier/cmd/main.go b/verifier/cmd/main.go new file mode 100644 index 0000000..68b7872 --- /dev/null +++ b/verifier/cmd/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func NewRootCmd() *cobra.Command { + rootCmd := &cobra.Command{ + Use: "vrf", + Short: "vrf - Babylon OP Finality Gadget Verifier", + Long: `vrf is a daemon to track consecutive quorum and query the Babylon BTC block finalization status of OP stack chains.`, + SilenceErrors: false, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + viper.BindPFlags(cmd.PersistentFlags()) + }, + } + + return rootCmd +} + +func main() { + cmd := NewRootCmd() + + cmd.PersistentFlags().String("cfg", "config.toml", "config file") + viper.BindPFlag("cfg", cmd.PersistentFlags().Lookup("cfg")) + + cmd.AddCommand(CommandStart()) + + if err := cmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Whoops. There was an error while executing your vrf CLI '%s'", err) + os.Exit(1) + } +} diff --git a/verifier/cmd/start.go b/verifier/cmd/start.go new file mode 100644 index 0000000..cef1000 --- /dev/null +++ b/verifier/cmd/start.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" + + "github.com/babylonchain/babylon-finality-gadget/verifier/config" + "github.com/babylonchain/babylon-finality-gadget/verifier/db" + "github.com/babylonchain/babylon-finality-gadget/verifier/server" + "github.com/babylonchain/babylon-finality-gadget/verifier/verifier" +) + +const ( + cfgFlag = "cfg" +) + +// CommandStart returns the start command of fpd daemon. +func CommandStart() *cobra.Command { + var cmd = &cobra.Command{ + Use: "start", + Short: "Start the finality gadget verifier daemon", + Long: `Start the finality gadget verifier daemon. Note that a config.toml file is required to start the daemon.`, + Example: `vrf start --cfg config.toml`, + Args: cobra.NoArgs, + RunE: runEWithClientCtx(runStartCmd), + } + return cmd +} + +func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { + // Parse configs + cfgPath, err := cmd.Flags().GetString(cfgFlag) + if err != nil { + return err + } + cfg, err := config.Load(cfgPath) + if err != nil { + return fmt.Errorf("failed to load configuration: %w", err) + } + + // Init local DB for storing and querying blocks + db, err := db.NewBBoltHandler(cfg.DBFilePath) + if err != nil { + return fmt.Errorf("failed to create DB handler: %w", err) + } + defer db.Close() + err = db.TryCreateInitialBuckets() + if err != nil { + return fmt.Errorf("create initial buckets error: %w", err) + } + + // Create verifier + vrf, err := verifier.NewVerifier(cfg, db) + if err != nil { + return fmt.Errorf("error creating verifier: %v", err) + } + + // Start server + go func() { + if _, err := server.StartServer(&server.ServerConfig{ + Port: cfg.ServerPort, + Db: db, + }); err != nil { + fmt.Printf("error starting server: %v\n", err) + } + }() + + // Start processing blocks + return vrf.ProcessBlocks() +} \ No newline at end of file diff --git a/verifier/config.toml b/verifier/config.toml new file mode 100644 index 0000000..f3b2b1a --- /dev/null +++ b/verifier/config.toml @@ -0,0 +1,8 @@ +L2RPCHost = "https://mainnet.optimism.io" +BitcoinRPCHost = "rpc.ankr.com/btc" +DBFilePath = "/Users/parkyeung/dev/babylon-finality-gadget/verifier/data.db" +FGContractAddress = "bbn1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqxxvh0f" +BBNChainID = "euphrates-0.2.0" +BBNRPCAddress = "https://rpc-euphrates.devnet.babylonchain.io" +ServerPort = "8080" +PollInterval = "10s" \ No newline at end of file diff --git a/verifier/config/config.go b/verifier/config/config.go new file mode 100644 index 0000000..76c2ec8 --- /dev/null +++ b/verifier/config/config.go @@ -0,0 +1,34 @@ +package config + +import ( + "time" + + "github.com/spf13/viper" +) + +type Config struct { + L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` + BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` + FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` + BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` + BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` + DBFilePath string `long:"db-file-path" description:"path to the DB file"` + ServerPort string `long:"server-port" description:"port to start the verifier server"` + PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` +} + +func Load(configPath string) (*Config, error) { + viper.SetConfigFile(configPath) + viper.SetConfigType("toml") + + if err := viper.ReadInConfig(); err != nil { + return nil, err + } + + var config Config + if err := viper.Unmarshal(&config); err != nil { + return nil, err + } + + return &config, nil +} \ No newline at end of file diff --git a/verifier/data.db b/verifier/data.db index 6975fc195a11f32b770d752002aec06cfeab13c4..cf53eb8796f985eecba43306cfc1209e1e8c4187 100644 GIT binary patch literal 131072 zcmeI*v2NQ&7yw|^N!koC5Cm<}l9i$PLUE!1&}O3Bb7Tjst% zmOMu6HGAixk5C|8`U1U^C_pf5!G+-MJNR_`Me6s@kK}l~UT@WIcjKqO?tR*e+lQ+! zmfNe%<>#$#`}1!6x*Pxg=INi`y?Od=7a9lMckEU3 z|JUEIQ{L$|*7N_r>f)zg{;~i2zjyyxA7>;$fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7t}n3H9lF=M zwcLvD14u&O5B+fnV*D(8#QFYZI5@^{!=d-WcpQ3t^0N8q=(wHzc)Xa0_|mpc9(Ts% zhoRpMJ+_$SF!Xi&ej`qjx-7~pACKxX8|TF^$=iH7DXXlSR+B-Nwso1-({@x3(k9PG zgJCnun`Dq=$+)eHaY)ts;)m})WP?dwSA%kxx05O)$%=N|jzgNdO7dosrD<7DlK5AQ z+om4o<4Ky7RXHq&RaQ(!U7quHm^DQ?ZKg$?=YuvGHTg7a$3;76i=r4+Nj)ml;kZom zQ9Efy)hL-}p`wtsZ9}rU%X79wyS7%8c^7{g+Q-m0)|2lg zq3?(OI0P|%7Cz$o;bmA-JjQRsq4&ag9D29Z{BmjdYp-a37=E~3j65dUjNfm>yDnWH zQpIJ>KkT}Adza^Y*LCWTLjBU?4z%009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ l009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RlHH@E=(s9$Aga1) z8bdnb zs$1v&?>={(|NiXt+NWyob#-;~_;<(Wzy8+S|N7qH`{!JWca&xh;&pVHSM{+MF@xw_U@`^2aEZ@q9m zU%Y?)=%M1D`?z=Yo;QDP^p4LddU6AS>s|b%UHsZEeoA@X{{0W{;@{cDU){xjyNlne zJ0ILG@8i4p4|nm`ck$bFhlJa||J*KqWfy;W7ysohez&A=m-qZG{^BnF^Id%P*1Nx- zck!op@t^GC*LU%+=|J7i=OerL_jd8ucJUj#*!+jPc1r?SZa1O_aTKkkLA4ICgZ2eTa9_PSV!H`(y!Q1t@XBKx5ef{S)m(W;?ncf zJ}0N5Z73$*l(QaL6;X?EHm>N`YGIV#%u3buP?L|@=Ha*1+>9-5xz)CMi_KJL%Un

;8A_D7AW<1XN?|YxxjUOQwVpay2H^FnrwNN=|O6c$}7V-_RYBHLn~uVx4bE_)|^XTCf1dke&?o~>o;60F|RERx6BMJ`Bm+h z%E)@}V@-V~ z)R#4?z=!_yP!C_*R5`ZI#L!on-PUdSna8HGdNe+Tq^db*(3{1fs-R=ia^A8klPZk< zx+&+uv)-9#Rf(Lcv&&YMuWdDLu?MH>tfLon1cHsun6TwpwlR${Hf?6he#~P%y#H$5>MLzQMI8C8}r zm#NyHv0`?s%G|hA=B6q!qY#y)TD02EW^5~AYsYr_;C-R@Hu`?Qu8r+X4NBQSIj6)h|cM!u~|KZEj86m-;1;T=<|bAXGlHi znC3jIS5M}ZQHv$1ljt%|u{y7J5>xG4RUP$asEX<6tIsLNa=w+L^}*I`)jnDdKB>-z zp{Cukkz4U8_vqHL`bkSYn{JGcJvJS*qS|tFeo56Xw-r`(?NGd4yRD*LE4#L4ZRXI$ zZ+24&)8^Q`x_uK|Rl6%ub>m6<`bO4%SvAz@d+RB$9#!iO?OfH)2Gf#uZ5FlqHReby z*EXHA>Sa}QEPWjF`GWR)YeO%r&ZVK=J9*V&)wwjbqMjx+)pfJF`alg%hl6y08#=sB zov%Oc*Y%G|RS#HOSKr(>HA&;usWm&*$Iql1o5Z03Md_*~PE)6TqNKZe6=O>Y$9!Hb zZM0yNbQhZw>WJz{y|i(s_9*6!p_Y$Z2Y_Ixf+P3v&m(xz#nP%RO?Q6ZFrmsFCOnrr^JyBVzeVbLg zblvEc#rM(FdNfw68<5@_MR59)HG)6M=lkjjwA*VowGZ_^8Wi;Yt#lRR4?}oY9WvXT zLek!hnbQ_j53<_Xrb_z6`KRiwy@pw*{qr2hsaYs^H|}~2S;m+Q$-Wz2x9N9NA-lNJZ8iZhT2`w0NG1dKcq42 zrkn>K7+#0(u>W06M{l+1)v;?ZI~>ANM5g!9;I)~l-b7VdS=Sz z`Ox~erWEQ5>S-mUnON6sU}{*X>S~-(&wh0N+2fOjhnh&=d3>Tinhzhn@Oa~$4Yz`O zSNGnG-mUL6`F-BoKAiofM=!qoWG43P;T1d(KmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009IL_%|z{tKlC%o;qIt|CVEXxUlB%(AD5P5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zK;U0k;K?GK_paXa<~td!v8h$tum0EZCx5n!e^WONxV`_x$SJ`2X(Ww?4l<^ZBPAuiN^Ksph=+S3h zn*ZZaiviy_s5rS?dXFvE_I&#e6Qs?Ocj4?NYpS3GkCC>R8^?sGoD7OE{O} z%exe{Z1NUXbV-YbYfboMw3hb>hsExVq_jG?Nt`y5*^K04-L$T>UVJJ= zYtE&pT5!59es-6lmj5oQz$SVfL%p|hi*_|FvOQL@Tkk8*Vr|nh)>^dP4Wq^3ZOFc9 zJ?5p=xKF02>ULW3Y;$>Km*S;sho4N*olY^Dv(4pmyA&^7=K5rcY7wUtqdD7LUfrd5 z>5A|tQ}pLjJlkA8ze_P_NpC;YP)g9k@LPzXIxXp~rO`K6U5&ojGPJ~c)gtO{Gg^1N zdo5tD<;GVDT0Z<_ipt`&;@Rf%gN0TWKwAt28&WYirhKvg=7p z*=q^)X>)8^Dqg*ltE+0&`rwNB`6+rAPuInygK?(Qx&PWOMK}8( zF_%*3rc^>(+U|-?_Hb}pb<4RKmo?p`(=i%RiaUA+IzU5cg#y^}9m?S9rVs_~}H z=rqVxqw#yQVoL|gvemJ=--?!H8Tg_whW^6U713%P^lPR9Ai%RiqUHtYgMX%YB)m*}r zY+bgo+NSs4Vh=7%yL<@F#$cl}CTw|@ZA@c~J=CY{$2>8*s4kwK>8Ng>>$>lMXP2TR zYAr^2ERBJyg;9DlD^(5NRbz3s8k)DI1{7NqY;CKz*i3b{%+=~i#nUsLL-RY=T)w+Y zG4!5X@vCa+tw95`ts}>7)moFrYZ>cc+pd{cT5IWr(;nJ%9Yr&?Xx7OTPtSCe;@Rf% zy#&Y)XAC2U90gNWn_+o7tJU#pA)1`ljB$)KN?3WRqs(JQO*GARD#dhqrlSVx{J~nQ9QekER__EB9k1-_|I_Xf_+N+WyG{olehm zl;YXu^7<~t;f*ba6uKH~&ubfT#O{{SXwpkj*0T${3icBXldRS(DOXFm7&*REljjHF*{@N>hb(PCt#!>M3lgsXO<*INMJi z=yRisJKJ1-xJ$9L(ZXXgb;mB{K4SF2TU&Ffd3l#oOnH-E^v1VMRkg?DZ1a9?YGEf+ zJU6~mttHJ>ecBz)c`h~18bNzb5pi@yHJE=8Rr`MG(w)!x+t4wbQoqG?Qyev8TLfNNxIxtr3a`l6tD z{8TZC1+crhL_EC4IMq?UJqy0*$Gmns+z5gHQn;2 z#Hy4_UMAKh!+5G+)VO(aN}KeCXGWLnpYBrBSnQ_J8H^6N&i|B0SHmq`-J(BCX8P#G zY;)@TRE=cJoVK6=EUOFOG{-nu7sHtro%6XCef_gtifid?Gu4r#ubxp;*Qj|`)}FQ; zR1vpP>k2wm(4jE=_7z#+~LfsR(;Sj)lRBibyNFN_Y_j7rzT?>?oZZ5rFiZ@Kls2d z#jbO`JT=IT6*iqyMQe=H$%*>s5!91+*P}j%&|x+j8pF`26GE=Nbj^6wWKJCD98UL( zO7ZN0erA`V9i{3Mi4;mwx7T&dgJw6$sNYd0I`%aTA2(G8eW+tKT-qGejYo|vZqx3a zN->`97nS0{D!`pPbU_1GjSr`dq*G;MrY@>asPam>BvhI^1rW$2INk15ult80DTT+w&^_$uv(ihu57e{+H7^s2)J>W9a*ZZ7bgo}a{D+QqN! z;-{47?bm;J7yr&K{^~CN+g>6QP-a$dglO4*xo?!R{F|F^y==fSg=UeI~W z=i8UwcHrpq*-J0GIPTZ`F1^I^xL@DB^b+>tetrJZ>nV@q5_;gdwgAZJK1@Y16^-FJ2 zbW_fHcSye4;+m9i3iyyz$P4Tfx1ndv8YX)_0ox zzIo>GE`6^%T|JI(%2J^D--Bn5CHGH#^5N_+J$muwdED~B!!r*A5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**{>=&; zE}%I)o;qIt|K#!-T_ykcp{v1pAb block @@ -91,7 +91,7 @@ func (bb *BBoltHandler) InsertBlock(ctx context.Context, block Block) error { } // Get current latest block - latestBlock, err := bb.GetLatestBlock(ctx) + latestBlock, err := bb.GetLatestBlock() if err != nil { fmt.Printf("Error getting latest block: %v\n", err) return err @@ -132,7 +132,7 @@ func (bb *BBoltHandler) InsertBlock(ctx context.Context, block Block) error { return nil } -func (bb *BBoltHandler) GetBlockByHeight(ctx context.Context, height uint64) (*Block, error) { +func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*Block, error) { var block Block err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blocksBucket)) @@ -149,15 +149,15 @@ func (bb *BBoltHandler) GetBlockByHeight(ctx context.Context, height uint64) (*B return &block, nil } -func (bb *BBoltHandler) GetBlockStatusByHeight(ctx context.Context, height uint64) bool { - block, err := bb.GetBlockByHeight(ctx, height) +func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) bool { + block, err := bb.GetBlockByHeight(height) if err != nil { return false } return block.IsFinalized } -func (bb *BBoltHandler) GetBlockStatusByHash(ctx context.Context, hash string) bool { +func (bb *BBoltHandler) GetBlockStatusByHash(hash string) bool { // Fetch block number by hash var blockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { @@ -170,10 +170,10 @@ func (bb *BBoltHandler) GetBlockStatusByHash(ctx context.Context, hash string) b return false } - return bb.GetBlockStatusByHeight(ctx, blockHeight) + return bb.GetBlockStatusByHeight(blockHeight) } -func (bb *BBoltHandler) GetLatestBlock(ctx context.Context) (*Block, error) { +func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { var latestBlockHeight uint64 // Fetch latest block height @@ -200,10 +200,10 @@ func (bb *BBoltHandler) GetLatestBlock(ctx context.Context) (*Block, error) { } // Fetch latest block by height - return bb.GetBlockByHeight(ctx, latestBlockHeight) + return bb.GetBlockByHeight(latestBlockHeight) } -func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { +func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock() (*Block, error) { var latestBlockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(latestBlockBucket)) @@ -218,7 +218,7 @@ func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context fmt.Printf("Error getting latest block: %v\n", err) return nil, err } - return bb.GetBlockByHeight(ctx, latestBlockHeight) + return bb.GetBlockByHeight(latestBlockHeight) } func (bb *BBoltHandler) Close() error { diff --git a/verifier/demo/main.go b/verifier/demo/main.go deleted file mode 100644 index fb649ad..0000000 --- a/verifier/demo/main.go +++ /dev/null @@ -1,68 +0,0 @@ -package main - -import ( - "context" - "fmt" - "os" - "path/filepath" - "strconv" - "time" - - "github.com/babylonchain/babylon-finality-gadget/verifier/verifier" - "github.com/joho/godotenv" -) - -func main() { - ctx := context.Background() - - // Load .env file - cwd, err := os.Getwd() - if err != nil { - fmt.Printf("error getting current working directory: %v\n", err) - } - envFile := filepath.Join(cwd, ".env") - fmt.Printf("loading env file: %s\n", envFile) - err = godotenv.Load(envFile) - if err != nil { - fmt.Printf("error loading .env file: %v\n", err) - } - - // Import and parse env vars - L2_RPC_HOST := os.Getenv("L2_RPC_HOST") - BITCOIN_RPC_HOST := os.Getenv("BITCOIN_RPC_HOST") - DB_FILE_PATH := os.Getenv("DB_FILE_PATH") - FG_CONTRACT_ADDRESS := os.Getenv("FG_CONTRACT_ADDRESS") - BBN_CHAIN_ID := os.Getenv("BBN_CHAIN_ID") - BBN_RPC_ADDRESS := os.Getenv("BBN_RPC_ADDRESS") - POLL_INTERVAL_IN_SECS := os.Getenv("POLL_INTERVAL_IN_SECS") - - pollInterval, err := strconv.Atoi(POLL_INTERVAL_IN_SECS) - if err != nil { - fmt.Printf("error converting poll interval to int: %v\n", err) - } - serverPort := os.Getenv("SERVER_PORT") - if serverPort == "" { - serverPort = "8080" - } - - // Create verifier - vf, err := verifier.NewVerifier(ctx, &verifier.Config{ - L2RPCHost: L2_RPC_HOST, - BitcoinRPCHost: BITCOIN_RPC_HOST, - DBFilePath: DB_FILE_PATH, - FGContractAddress:FG_CONTRACT_ADDRESS, - BBNChainID: BBN_CHAIN_ID, - BBNRPCAddress: BBN_RPC_ADDRESS, - ServerPort: serverPort, - PollInterval: time.Second * time.Duration(pollInterval), - }) - if err != nil { - fmt.Printf("error creating verifier: %v\n", err) - } - - // Start processing blocks - err = vf.ProcessBlocks(ctx) - if err != nil { - fmt.Println(err) - } -} \ No newline at end of file diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go index 430f8ce..a8703f5 100644 --- a/verifier/server/handlers.go +++ b/verifier/server/handlers.go @@ -1,7 +1,6 @@ package server import ( - "context" "encoding/json" "fmt" "net/http" @@ -30,8 +29,7 @@ func (s *Server) getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) } // Fetch status from DB - ctx := context.Background() - isFinal := s.db.GetBlockStatusByHeight(ctx, uint64(blockHeight)) + isFinal := s.db.GetBlockStatusByHeight(uint64(blockHeight)) // Marshal and return status jsonResponse, err := json.Marshal(StatusResponse { @@ -57,8 +55,7 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { } // Fetch status from DB - ctx := context.Background() - isFinal := s.db.GetBlockStatusByHash(ctx, hash) + isFinal := s.db.GetBlockStatusByHash(hash) // Marshal and return status jsonResponse, err := json.Marshal(StatusResponse { @@ -76,8 +73,7 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { // Fetch status from DB - ctx := context.Background() - block, err := s.db.GetLatestConsecutivelyFinalizedBlock(ctx) + block, err := s.db.GetLatestConsecutivelyFinalizedBlock() if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Error getting latest block: %v\n", err) diff --git a/verifier/server/server.go b/verifier/server/server.go index deae520..d823372 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -1,7 +1,6 @@ package server import ( - "context" "log" "net/http" @@ -20,7 +19,7 @@ type ServerConfig struct { Port string } -func StartServer(ctx context.Context, cfg *ServerConfig) (*Server, error) { +func StartServer(cfg *ServerConfig) (*Server, error) { // Define server. s := &Server{ port: cfg.Port, diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go index 1556412..d26d180 100644 --- a/verifier/verifier/types.go +++ b/verifier/verifier/types.go @@ -21,17 +21,6 @@ type Verifier struct { currHeight uint64 } -type Config struct { - L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` - BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` - FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` - BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` - BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` - DBFilePath string `long:"db-file-path" description:"path to the DB file"` - ServerPort string `long:"server-port" description:"port to start the verifier server"` - PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` -} - type BlockInfo struct { Hash string Height uint64 diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 3c4d4ca..7555c5c 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -11,13 +11,13 @@ import ( "github.com/babylonchain/babylon-finality-gadget/sdk/client" sdkconfig "github.com/babylonchain/babylon-finality-gadget/sdk/config" "github.com/babylonchain/babylon-finality-gadget/sdk/cwclient" + "github.com/babylonchain/babylon-finality-gadget/verifier/config" "github.com/babylonchain/babylon-finality-gadget/verifier/db" - "github.com/babylonchain/babylon-finality-gadget/verifier/server" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" ) -func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { +func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { // Create finality gadget client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost @@ -37,27 +37,6 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { return nil, fmt.Errorf("failed to create OPStack L2 client: %w", err) } - // Create local DB for storing and querying blocks - db, err := db.NewBBoltHandler(ctx, cfg.DBFilePath) - if err != nil { - return nil, fmt.Errorf("failed to create DB handler: %w", err) - } - defer db.Close() - err = db.TryCreateInitialBuckets(ctx) - if err != nil { - return nil, fmt.Errorf("create initial buckets error: %w", err) - } - - // Start server - go func() { - if _, err := server.StartServer(ctx, &server.ServerConfig{ - Port: cfg.ServerPort, - Db: db, - }); err != nil { - fmt.Printf("error starting server: %v\n", err) - } - }() - // Create verifier return &Verifier{ SdkClient: sdkClient, @@ -68,16 +47,16 @@ func NewVerifier(ctx context.Context, cfg *Config) (*Verifier, error) { } // This function process blocks indefinitely, starting from the last finalized block. -func (vf *Verifier) ProcessBlocks(ctx context.Context) error { - return vf.ProcessNBlocks(ctx, -1) +func (vf *Verifier) ProcessBlocks() error { + return vf.ProcessNBlocks(-1) } // This function process n blocks, starting from the last finalized block. // n is the number of blocks to process, pass in -1 to process blocks indefinitely. // Passing in non-negative n is useful for testing. -func (vf *Verifier) ProcessNBlocks(ctx context.Context, n int) error { +func (vf *Verifier) ProcessNBlocks(n int) error { // Start service at last finalized block - err := vf.startService(ctx) + err := vf.startService() if err != nil { return fmt.Errorf("%v", err) } @@ -89,13 +68,13 @@ func (vf *Verifier) ProcessNBlocks(ctx context.Context, n int) error { if n > 0 && vf.currHeight == vf.startHeight + uint64(n - 1) { break } - block, err := vf.getBlockByNumber(ctx, int64(vf.currHeight + 1)) + block, err := vf.getBlockByNumber(int64(vf.currHeight + 1)) if err != nil { fmt.Printf("error getting new block: %v\n", err) continue } go func() { - vf.handleBlock(ctx, block) + vf.handleBlock(block) }() } @@ -103,15 +82,15 @@ func (vf *Verifier) ProcessNBlocks(ctx context.Context, n int) error { } // Start service at last finalized block -func (vf *Verifier) startService(ctx context.Context) error { +func (vf *Verifier) startService() error { // Query L2 node for last finalized block - block, err := vf.getLatestFinalizedBlock(ctx) + block, err := vf.getLatestFinalizedBlock() if err != nil { return fmt.Errorf("error getting last finalized block: %v", err) } // Query local DB for last block processed - localBlock, err := vf.Db.GetLatestBlock(ctx) + localBlock, err := vf.Db.GetLatestBlock() if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } @@ -130,7 +109,7 @@ func (vf *Verifier) startService(ctx context.Context) error { } // Check the block is finalized using sdk client - isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) + isFinal, err := vf.queryIsBlockBabylonFinalized(block) // If not finalized, throw error if !isFinal { return fmt.Errorf("block %d should be finalized according to client but is not", block.Height) @@ -139,7 +118,7 @@ func (vf *Verifier) startService(ctx context.Context) error { return fmt.Errorf("error checking block %d: %v", block.Height, err) } // If finalised, store the block in DB and set the last finalized block - err = vf.insertBlock(ctx, block) + err = vf.insertBlock(block) if err != nil { return fmt.Errorf("error storing block %d: %v", block.Height, err) } @@ -156,13 +135,13 @@ func (vf *Verifier) startService(ctx context.Context) error { } // Get last btc finalized block -func (vf *Verifier) getLatestFinalizedBlock(ctx context.Context) (*BlockInfo, error) { - return vf.getBlockByNumber(ctx, ethrpc.FinalizedBlockNumber.Int64()) +func (vf *Verifier) getLatestFinalizedBlock() (*BlockInfo, error) { + return vf.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } // Get block by number -func (vf *Verifier) getBlockByNumber(ctx context.Context, blockNumber int64) (*BlockInfo, error) { - header, err := vf.L2Client.HeaderByNumber(ctx, big.NewInt(blockNumber)) +func (vf *Verifier) getBlockByNumber(blockNumber int64) (*BlockInfo, error) { + header, err := vf.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err } @@ -173,18 +152,18 @@ func (vf *Verifier) getBlockByNumber(ctx context.Context, blockNumber int64) (*B }, nil } -func (vf *Verifier) handleBlock(ctx context.Context, block *BlockInfo) { +func (vf *Verifier) handleBlock(block *BlockInfo) { // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { // Check if block is finalized - isFinal, err := vf.queryIsBlockBabylonFinalized(ctx, block) + isFinal, err := vf.queryIsBlockBabylonFinalized(block) if err != nil { fmt.Printf("error checking block %d: %v\n", block.Height, err) return } if isFinal { - err = vf.insertBlock(ctx, block) + err = vf.insertBlock(block) if err != nil { fmt.Printf("error storing block %d: %v\n", block.Height, err) } @@ -196,7 +175,8 @@ func (vf *Verifier) handleBlock(ctx context.Context, block *BlockInfo) { } } -func (vf *Verifier) queryIsBlockBabylonFinalized(ctx context.Context, block *BlockInfo) (bool, error) { +func (vf *Verifier) queryIsBlockBabylonFinalized(block *BlockInfo) (bool, error) { + return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.Hash), BlockHeight: block.Height, @@ -204,11 +184,11 @@ func (vf *Verifier) queryIsBlockBabylonFinalized(ctx context.Context, block *Blo }) } -func (vf *Verifier) insertBlock(ctx context.Context, block *BlockInfo) error { +func (vf *Verifier) insertBlock(block *BlockInfo) error { // Lock mutex vf.Mutex.Lock() // Store block in DB - err := vf.Db.InsertBlock(ctx, db.Block{ + err := vf.Db.InsertBlock(db.Block{ BlockHeight: block.Height, BlockHash: block.Hash, BlockTimestamp: block.Timestamp, From 60275d9df2424490a76179c53d6011ffdd02c74b Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 13:45:11 +0800 Subject: [PATCH 27/93] feat: improve logging --- verifier/cmd/start.go | 3 ++- verifier/data.db | Bin 131072 -> 131072 bytes verifier/db/bbolt.go | 37 +++++++++++++++++----------------- verifier/db/postgres.go | 7 ++++--- verifier/verifier/verifier.go | 10 ++++----- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/verifier/cmd/start.go b/verifier/cmd/start.go index cef1000..13d4325 100644 --- a/verifier/cmd/start.go +++ b/verifier/cmd/start.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log" "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" @@ -63,7 +64,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { Port: cfg.ServerPort, Db: db, }); err != nil { - fmt.Printf("error starting server: %v\n", err) + log.Fatalf("Error starting server: %v\n", err) } }() diff --git a/verifier/data.db b/verifier/data.db index cf53eb8796f985eecba43306cfc1209e1e8c4187..5744257efdeecbcdca3149b44612241ce2c3a573 100644 GIT binary patch literal 131072 zcmeI*zl-L^9mnw}m-sG@e{i@m1RJyU6*C%XM&s(L#LcnBjUj>Cn;FgQZgRde**(W3 z1Pn>xf58}x$$yaUeiU}$KfBb~q?V|@CPgdeU;KpxpLeKZ~X!fI*q>;AJ z&StZnelab-`Sa_gLw0!*GKmPuQZ^Dz^_gEr;00Iag zfB*srAb>H`|JQ$S z{rb=U{MFu9`G^1l2q1s}0tg_000IagfB*srAb@ZCwR6-!bsvgtaudbG={#ufv+AP@+RA}xWasiA2e;d`Q--FMBVUHx znV_WVbz_SjoNqnKeOnssJ2`REP?EF3_JbQj@h-G- zF8kPdZR5~KRpg*IO(}ibdt=KWhfM9xLpjRAEJn%na=e_dgpgD3`oZ)?B1&^Qs6mf{ za^(~kO6zcJX}lap(~rm74RSt6rrwE&O1u5a z7oFcz_j+Rw_wg7(rZefa_Uo(C3+>k*RrL+&W%k#9R@HAwSG~XftEzrqy72w=&q;s2 zUw=~7`q~fIe^J$M%f|cLkGo=5 zeJ7uthj-qUb*^cQ^eWEWI5<5!DyR3t-P6D1;o$Z2KRw8Q8_6Z&qblOs>tr^fUy9f* zMSNUET-)`|MeNj4M7I?2NfmKzZ#)}OFGUpM*#mueyNbB>hI)BKuiS#7*Gr0rM^(hN z_v+b*3yShAv7~sXinz8LpN-heA86l5{`mtP>WC}v5VH}bU)lC<|KI8OW~tLTj8(+7 zH`UpQ?NY?0PUkRH5!XJa%|?_I^NNd?%TPsJ`{*_s(JnaqUyaY(#;YRWys2 zOQ|BReQ=$PxNwj5X7O@4t|G2|CZ3JBaF6!p^2_CJIF|>GqYM1;k>axH%0?dDrs*|V zj=wmMPfFwTs?0CRJl5N`(grs^4{phB=3tdA%Fk^2q1s}0tg_000IagfB*srAb^y+*5ALl**q`xiOk!9C{HeiXnyLEuy4wSyD<@8mY=X+ zzgg8ER`usq{asZn8GdoUy_2f`w5q?X>g(dLzx^9k{Xtbf+^g3Pc`YpCFx3y&4p+Qw z=kWI0F@>jgj@AxBJ?+=ywd2Z8dD7Yur>8tm)(#>&<&jbAyJ+G#dc9X&(_0xhKEzgQ z8R*_NxrsSNr}Ln_&#I3y*u8Z*H=&d~49Rt7YNxCn>vU@8c^G@yLi_Y(k*RrL+&W%k#9R@HAw zSG~XftEzrqy72w=&q;s2Uw=~7`q~fIe^J$M%f|cLkG)nkaPQjA@bZCsd)qFIEv($q z*uu9SRT0--C$kY3#uirY^09@-vqBUfR}t5Cy>k(}g^}x(TN;Y{){`pY+TM6J;=;)F z$}JAXeY=Xd_J(?SM6cX}qSs4`heuV!wfE}Thzp8dFDl-tBChSmXCpQX1DZFB1Dc0A z;>tV3Y((i-X2)D_mO7ooSVdfWQ=N_2E=64GbPiJ$aqV;3Y(z;huef-*3{}Lnk8ZOO z?NY?W%OzJ4*FI&;Mii)7MYDLhlq%xd2iMt%3-@Sm7B83MD&pE_;@OA`_h@e}zg+Hy z^L%!Gbb&wKuP>XfY~;~xnqHIT_>1%Sq%=;i%KVbdW4&!lKFD4F@OWxD-M@F1(}VNV z_wux+j7ug25I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009IL_(==Md!ZN8_35>R-OCH|ekl_I2q1s}0tg_000IagfB*srAbt+)q2`)3|wzN`M!(`{ipveo` z9l$EsqkMNw{@VuU?3`@ds(@x3Na1X#afg94GCz!Qvt`?7#>u+<5i-8JauQ2Yi%a5@ m^Ye;RlS@l7%ThtwKz3{lykWiRfQ-XX_sC9=N0vD-9smH#`CBdk diff --git a/verifier/db/bbolt.go b/verifier/db/bbolt.go index 0488a43..1f758e9 100644 --- a/verifier/db/bbolt.go +++ b/verifier/db/bbolt.go @@ -5,7 +5,7 @@ import ( "encoding/binary" "encoding/json" "errors" - "fmt" + "log" "time" bolt "go.etcd.io/bbolt" @@ -31,7 +31,7 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { // 0600 = read/write permission for owner only db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second}) if err != nil { - fmt.Printf("Error opening DB: %v\n", err) + log.Fatalf("Error opening DB: %v\n", err) return nil, err } @@ -41,12 +41,12 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { } func (bb *BBoltHandler) TryCreateInitialBuckets() error { - fmt.Println("creating initial buckets...") + log.Printf("Creating initial DB buckets...") return bb.db.Update(func(tx *bolt.Tx) error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} for _, bucket := range buckets { if err := tryCreateBucket(tx, bucket); err != nil { - fmt.Printf("Error creating bucket: %v\n", err) + log.Fatalf("Error creating bucket: %v\n", err) return err } } @@ -57,13 +57,13 @@ func (bb *BBoltHandler) TryCreateInitialBuckets() error { func tryCreateBucket(tx *bolt.Tx, bucketName string) error { _, err := tx.CreateBucketIfNotExists([]byte(bucketName)) if err != nil { - fmt.Printf("Error creating bucket: %v\n", err) + log.Fatalf("Error creating bucket: %v\n", err) } return err } func (bb *BBoltHandler) InsertBlock(block Block) error { - fmt.Printf("Inserting block %d to DB\n", block.BlockHeight) + log.Printf("Inserting block %d to DB...\n", block.BlockHeight) // Store mapping number -> block err := bb.db.Update(func(tx *bolt.Tx) error { @@ -76,7 +76,7 @@ func (bb *BBoltHandler) InsertBlock(block Block) error { return b.Put(key, blockBytes) }) if err != nil { - fmt.Printf("Error inserting block: %v\n", err) + log.Fatalf("Error inserting block: %v\n", err) return err } @@ -86,14 +86,14 @@ func (bb *BBoltHandler) InsertBlock(block Block) error { return b.Put([]byte(block.BlockHash), itob(block.BlockHeight)) }) if err != nil { - fmt.Printf("Error inserting block: %v\n", err) + log.Fatalf("Error inserting block: %v\n", err) return err } // Get current latest block latestBlock, err := bb.GetLatestBlock() if err != nil { - fmt.Printf("Error getting latest block: %v\n", err) + log.Fatalf("Error getting latest block: %v\n", err) return err } @@ -101,17 +101,16 @@ func (bb *BBoltHandler) InsertBlock(block Block) error { err = bb.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(latestBlockBucket)) if err != nil { - fmt.Printf("Error getting latest block: %v\n", err) + log.Fatalf("Error getting latest block: %v\n", err) return err } if latestBlock.BlockHeight < block.BlockHeight { - fmt.Printf("Updating latest block: %v\n", block.BlockHeight) return b.Put([]byte(latestBlockKey), itob(block.BlockHeight)) } return nil }) if err != nil { - fmt.Printf("Error updating latest block: %v\n", err) + log.Fatalf("Error updating latest block: %v\n", err) return err } @@ -125,7 +124,7 @@ func (bb *BBoltHandler) InsertBlock(block Block) error { return nil }) if err != nil { - fmt.Printf("Error updating latest block: %v\n", err) + log.Fatalf("Error updating latest block: %v\n", err) return err } @@ -143,7 +142,7 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*Block, error) { return json.Unmarshal(v, &block) }) if err != nil { - fmt.Printf("Error getting block by %d\n", err) + log.Fatalf("Error getting block by %d\n", err) return nil, err } return &block, nil @@ -166,7 +165,7 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) bool { return nil }) if err != nil { - fmt.Printf("Error getting block by hash: %v\n", err) + log.Fatalf("Error getting block by hash: %v\n", err) return false } @@ -195,7 +194,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { IsFinalized: false, }, nil } - fmt.Printf("Error getting latest block: %v\n", err) + log.Fatalf("Error getting latest block: %v\n", err) return nil, err } @@ -215,7 +214,7 @@ func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock() (*Block, error) { return nil }) if err != nil { - fmt.Printf("Error getting latest block: %v\n", err) + log.Fatalf("Error getting latest block: %v\n", err) return nil, err } return bb.GetBlockByHeight(latestBlockHeight) @@ -229,7 +228,7 @@ func itob(v uint64) []byte { buf := new(bytes.Buffer) err := binary.Write(buf, binary.BigEndian, v) if err != nil { - fmt.Printf("Error writing to buffer: %v\n", err) + log.Fatalf("Error writing to buffer: %v\n", err) } return buf.Bytes() } @@ -239,7 +238,7 @@ func btoi(b []byte) uint64 { buf := bytes.NewReader(b) err := binary.Read(buf, binary.BigEndian, &v) if err != nil { - fmt.Printf("Error reading from buffer: %v\n", err) + log.Fatalf("Error reading from buffer: %v\n", err) } return v } \ No newline at end of file diff --git a/verifier/db/postgres.go b/verifier/db/postgres.go index f4f7548..b8f4489 100644 --- a/verifier/db/postgres.go +++ b/verifier/db/postgres.go @@ -5,6 +5,7 @@ package db import ( "context" "fmt" + "log" "github.com/jackc/pgx/v5" ) @@ -67,7 +68,7 @@ func (pg *PostgresHandler) TryCreateInitialTables(ctx context.Context) error { } func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { - fmt.Printf("Inserting block %d into DB\n", block.BlockHeight) + log.Printf("Inserting block %d into DB\n", block.BlockHeight) // Start atomic insert tx tx, err := pg.conn.Begin(ctx) @@ -104,7 +105,7 @@ func (pg *PostgresHandler) GetBlockStatusByHeight(ctx context.Context, blockHeig var isFinalized bool err := pg.conn.QueryRow(ctx, getBlockStatusByHeightSql, blockHeight).Scan(&isFinalized) if err != nil { - fmt.Printf("GetBlockStatusByHeight: %v\n", err) + log.Fatalf("GetBlockStatusByHeight: %v\n", err) return false } @@ -116,7 +117,7 @@ func (pg *PostgresHandler) GetBlockStatusByHash(ctx context.Context, blockHash s err := pg.conn.QueryRow(ctx, getBlockStatusByHashSql, blockHash).Scan(&isFinalized) if err != nil { - fmt.Printf("GetBlockStatusByHash: %v\n", err) + log.Fatalf("GetBlockStatusByHash: %v\n", err) return false } diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 7555c5c..32b3689 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -4,6 +4,7 @@ import ( "context" "encoding/hex" "fmt" + "log" "math/big" "time" @@ -70,7 +71,7 @@ func (vf *Verifier) ProcessNBlocks(n int) error { } block, err := vf.getBlockByNumber(int64(vf.currHeight + 1)) if err != nil { - fmt.Printf("error getting new block: %v\n", err) + log.Fatalf("error getting new block: %v\n", err) continue } go func() { @@ -125,7 +126,7 @@ func (vf *Verifier) startService() error { } // Start service at block height - fmt.Printf("starting service at block %d\n", block.Height) + log.Printf("Starting verifier at block %d...\n", block.Height) // Set the start block and curr finalized block in memory vf.startHeight = block.Height @@ -159,13 +160,13 @@ func (vf *Verifier) handleBlock(block *BlockInfo) { // Check if block is finalized isFinal, err := vf.queryIsBlockBabylonFinalized(block) if err != nil { - fmt.Printf("error checking block %d: %v\n", block.Height, err) + log.Fatalf("Error checking block %d: %v\n", block.Height, err) return } if isFinal { err = vf.insertBlock(block) if err != nil { - fmt.Printf("error storing block %d: %v\n", block.Height, err) + log.Fatalf("Error storing block %d: %v\n", block.Height, err) } return } @@ -176,7 +177,6 @@ func (vf *Verifier) handleBlock(block *BlockInfo) { } func (vf *Verifier) queryIsBlockBabylonFinalized(block *BlockInfo) (bool, error) { - return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.Hash), BlockHeight: block.Height, From 6c982ae4dd9c8b3caa59ef0567441c94d51982ed Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 13:47:30 +0800 Subject: [PATCH 28/93] chore: consolidate verifier code --- verifier/cmd/cmd.go | 20 -------------------- verifier/cmd/main.go | 15 +++++++++++++++ verifier/verifier/types.go | 28 ---------------------------- verifier/verifier/verifier.go | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+), 48 deletions(-) delete mode 100644 verifier/cmd/cmd.go delete mode 100644 verifier/verifier/types.go diff --git a/verifier/cmd/cmd.go b/verifier/cmd/cmd.go deleted file mode 100644 index dad14d8..0000000 --- a/verifier/cmd/cmd.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/spf13/cobra" -) - -// Runs cmd with client context and returns an error. -func runEWithClientCtx( - fRunWithCtx func(ctx client.Context, cmd *cobra.Command, args []string) error, -) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - return fRunWithCtx(clientCtx, cmd, args) - } -} diff --git a/verifier/cmd/main.go b/verifier/cmd/main.go index 68b7872..7296404 100644 --- a/verifier/cmd/main.go +++ b/verifier/cmd/main.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -35,3 +36,17 @@ func main() { os.Exit(1) } } + +// Runs cmd with client context and returns an error. +func runEWithClientCtx( + fRunWithCtx func(ctx client.Context, cmd *cobra.Command, args []string) error, +) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + return fRunWithCtx(clientCtx, cmd, args) + } +} diff --git a/verifier/verifier/types.go b/verifier/verifier/types.go deleted file mode 100644 index d26d180..0000000 --- a/verifier/verifier/types.go +++ /dev/null @@ -1,28 +0,0 @@ -package verifier - -import ( - "sync" - "time" - - "github.com/babylonchain/babylon-finality-gadget/sdk/client" - "github.com/babylonchain/babylon-finality-gadget/verifier/db" - "github.com/ethereum/go-ethereum/ethclient" -) - -type Verifier struct { - SdkClient *client.SdkClient - L2Client *ethclient.Client - Db *db.BBoltHandler - - Mutex sync.Mutex - - PollInterval time.Duration - startHeight uint64 - currHeight uint64 -} - -type BlockInfo struct { - Hash string - Height uint64 - Timestamp uint64 -} \ No newline at end of file diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 32b3689..c129478 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "math/big" + "sync" "time" "github.com/babylonchain/babylon-finality-gadget/sdk/btcclient" @@ -18,6 +19,24 @@ import ( ethrpc "github.com/ethereum/go-ethereum/rpc" ) +type Verifier struct { + SdkClient *client.SdkClient + L2Client *ethclient.Client + Db *db.BBoltHandler + + Mutex sync.Mutex + + PollInterval time.Duration + startHeight uint64 + currHeight uint64 +} + +type BlockInfo struct { + Hash string + Height uint64 + Timestamp uint64 +} + func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { // Create finality gadget client btcConfig := btcclient.DefaultBTCConfig() From faa7df19f713e0af687490f14d339379505f21c4 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 13:52:00 +0800 Subject: [PATCH 29/93] fix: lint errors --- verifier/cmd/main.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/verifier/cmd/main.go b/verifier/cmd/main.go index 7296404..920fd7b 100644 --- a/verifier/cmd/main.go +++ b/verifier/cmd/main.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + "log" "os" "github.com/cosmos/cosmos-sdk/client" @@ -15,9 +15,6 @@ func NewRootCmd() *cobra.Command { Short: "vrf - Babylon OP Finality Gadget Verifier", Long: `vrf is a daemon to track consecutive quorum and query the Babylon BTC block finalization status of OP stack chains.`, SilenceErrors: false, - PersistentPreRun: func(cmd *cobra.Command, args []string) { - viper.BindPFlags(cmd.PersistentFlags()) - }, } return rootCmd @@ -26,13 +23,16 @@ func NewRootCmd() *cobra.Command { func main() { cmd := NewRootCmd() - cmd.PersistentFlags().String("cfg", "config.toml", "config file") - viper.BindPFlag("cfg", cmd.PersistentFlags().Lookup("cfg")) - cmd.AddCommand(CommandStart()) + cmd.PersistentFlags().String("cfg", "config.toml", "config file") + if err := viper.BindPFlag("cfg", cmd.PersistentFlags().Lookup("cfg")); err != nil { + log.Fatalf("Error binding flag: %s", err) + os.Exit(1) + } + if err := cmd.Execute(); err != nil { - fmt.Fprintf(os.Stderr, "Whoops. There was an error while executing your vrf CLI '%s'", err) + log.Fatalf("Error executing your vrf daemon: %s", err) os.Exit(1) } } From 18bc36c0430df81981b025785a79ade2f288972c Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 13:53:09 +0800 Subject: [PATCH 30/93] fix: handle server error --- verifier/server/server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/verifier/server/server.go b/verifier/server/server.go index d823372..e42d736 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -38,6 +38,7 @@ func StartServer(cfg *ServerConfig) (*Server, error) { log.Printf("Starting server on port %s...", cfg.Port) if err := http.ListenAndServe(":"+cfg.Port, router); err != nil { log.Fatalf("Could not start server: %s\n", err.Error()) + return nil, err } return s, nil From 0063e32b83a8c308a5bfadf9125ddbdc4e4f0053 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:10:03 +0800 Subject: [PATCH 31/93] fix: gracefully handle server shutdown --- verifier/cmd/start.go | 35 ++++++++++++++++++++++++++++------- verifier/data.db | Bin 131072 -> 131072 bytes verifier/server/server.go | 33 +++++++++++++++++++++------------ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/verifier/cmd/start.go b/verifier/cmd/start.go index 13d4325..8b4c761 100644 --- a/verifier/cmd/start.go +++ b/verifier/cmd/start.go @@ -3,6 +3,9 @@ package main import ( "fmt" "log" + "os" + "os/signal" + "syscall" "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" @@ -59,15 +62,33 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { } // Start server + s, err := server.Start(&server.ServerConfig{ + Port: cfg.ServerPort, + Db: db, + }) + if err != nil { + log.Fatalf("Error starting server: %v\n", err) + } + + // Set up channel to listen for interrupt signal + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) + + // Run verifier in a separate goroutine go func() { - if _, err := server.StartServer(&server.ServerConfig{ - Port: cfg.ServerPort, - Db: db, - }); err != nil { - log.Fatalf("Error starting server: %v\n", err) + if err := vrf.ProcessBlocks(); err != nil { + log.Fatalf("Error processing blocks: %v\n", err) } }() - // Start processing blocks - return vrf.ProcessBlocks() + // Wait for interrupt signal + sig := <-sigChan + if sig == os.Interrupt { + fmt.Print("\r") + } + + // Call Stop method when interrupt signal is received + s.Stop() + + return nil } \ No newline at end of file diff --git a/verifier/data.db b/verifier/data.db index 5744257efdeecbcdca3149b44612241ce2c3a573..80db1d196a2f3781497676d94270cbbbf9a1c15d 100644 GIT binary patch literal 131072 zcmeI*JB%bp8Nl)74loac5CVw+8EZuVl0o(AdYpa22?>(5Y=#JYuBxuOJ$!zMJ0k=l zCm^tqAR!?nL?mE4AtWb3NFa-d#5qn7U+?yu=Gxn>TaDzv{M)yl{dQ)0zW#MRx>x#Y zkB%<3kIs+p{{8WHuT9@Sd+~$o7Y`5qzkA)s=bw!8<3E4tzV?IHzxl5RFXS5p5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILcw~W(%&*+l^)KuH&({Lj+uO(H?|1e8b&lVA=T}dh zzVX{<_Fl@j2q1s}0tg_000IagfB*srAbWjC|+MU~H_wPx3>2~et3lDz&tnBew zi9Rv^&c>n$1Tg0y~;=e57={Wb_9~befi}-ho_?<=kC0RLPe}CUy z#6Mree_q7@S;R_KSlHj+*#a77hsOVeH{+gh+r5`}b=OoHZ7jvMnB_mEi*tG`*|$2_c(I?; zXG~}@nzX8|8#iWcN7Z$(H78YV7;3E18?Ogrtx03;)tWh< z%C+Q&C?D>7P9ewEbtypviynjO#ShMv+O-vmAw)Thq0RZEL0(d_PLkJ{1$l_gH!sX3 zt5Cp`{BgC4yfa`9pmM}&dKeL>t?j0twT`J`J7dntWs^V=h&4rDI2tR!OQ1(Q66=dkFwJTxGJACnlvBR z+et-}ixCAcr^lI8(pYSimucSwpjg#|_wv5hQ}RLE-hGv(>0`@-vh#6`X&j0zP9BpQ zj2IY|i_<#h?oBgAY=ds2PN}I_Le^dyiV>tXN~0Zi`{^RAl$N$)bVxmkjni(F{pD1K zlB8|RVUNv<-Td>->I>te( zlC6?vD!Gb&cWUg~gt;A_-WZLO9@fV;*sS_!qBg#3If+e`u9KYS+FdV$v&xzwI}=4s zdZX<{dbHae*X>cdaQ99QNP0sVdN9(HU6kYR*~KDF-1br0s!`QTH%`XaqHOS1wXwT# z8pox-pFZ7;beq)WES4ak%GJ<^CMQF;7^BNVlC1I409+HhX>b^1? z(RHKKAV*%uUV}8oIEFEI>0nOA9??!(pkq;8I)yR4M;DXzeUv7xcH@Th0%<;S?yHT` z4uhQToLh}y>aJZ~Ge zIwxh3;-QoFYKm?v#jQc-q%KlC^g4MpMag1aakIOOixdyN6}|UD_hWL$6|1 zQxvFGMZ4Ku`Xa?cFZfqe+?b=2-Rv&67bzZk?Y^4g#vGmOW_LMTq)yyyDL%lBG+?f#t~?SAXSlB^RE8v+O* zfB*srAb=@iGs^3k#=*`qFCzCsc$Vs>i@5@z|!T4)c;>?nV3~Y>i@5>XwRx5_5W8`@@iFa zy;@k7!`iAAKB4}9UZY3G#r0}oS=DN*TKI(e{|AcH|6gUXx0N0}xb+@Q{r~%xfLv8v z@6pu%U#b58=6w6f0|E#jfB*srAb_J)%Va7eI0<=mlk^v3_b z(&dY|AZqGmr9QAQFfaloWmy>*K#E^+Lim6ACYv=F*7HI2F)%y;vK)Yz1BgLD0;tOY zNW=I6X#5T|{sA=p4>Z036RLR`Abu>81q;v=+(6?CFrymafyQq@LBSFzkqIgdl%S?LFbYf+VB}zA1{F;k6BdB+#DpIJ^HZrU diff --git a/verifier/server/server.go b/verifier/server/server.go index e42d736..13225c4 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -10,8 +10,8 @@ import ( ) type Server struct { - db *db.BBoltHandler - port string + server *http.Server + db *db.BBoltHandler } type ServerConfig struct { @@ -19,27 +19,36 @@ type ServerConfig struct { Port string } -func StartServer(cfg *ServerConfig) (*Server, error) { +func Start(cfg *ServerConfig) (*Server, error) { + // Create router. + router := mux.NewRouter().StrictSlash(true) + // Define server. s := &Server{ - port: cfg.Port, + server: &http.Server{ + Addr: ":" + cfg.Port, + Handler: router, + }, db: cfg.Db, } - // Create router. - router := mux.NewRouter().StrictSlash(true) - // Define routes. router.HandleFunc("/getBlockStatusByHeight", s.getBlockStatusByHeight) router.HandleFunc("/getBlockStatusByHash", s.getBlockStatusByHash) router.HandleFunc("/getLatest", s.getLatestConsecutivelyFinalizedBlock) - // Start server. - log.Printf("Starting server on port %s...", cfg.Port) - if err := http.ListenAndServe(":"+cfg.Port, router); err != nil { + // Start server in a goroutine. + go func() { + log.Printf("Starting server on port %s...", cfg.Port) + if err := http.ListenAndServe(":"+cfg.Port, router); err != nil { log.Fatalf("Could not start server: %s\n", err.Error()) - return nil, err - } + } + }() return s, nil +} + +func (s *Server) Stop() error { + log.Println("Stopping server...") + return s.server.Close() } \ No newline at end of file From 3970dc108320d778337bd5f5d5ab3ae4a37ae783 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:14:01 +0800 Subject: [PATCH 32/93] fix: gracefully shutdown verifier --- verifier/cmd/start.go | 1 + verifier/verifier/verifier.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/verifier/cmd/start.go b/verifier/cmd/start.go index 8b4c761..3363419 100644 --- a/verifier/cmd/start.go +++ b/verifier/cmd/start.go @@ -60,6 +60,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("error creating verifier: %v", err) } + defer vrf.Close() // Start server s, err := server.Start(&server.ServerConfig{ diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index c129478..ba7df17 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -222,4 +222,8 @@ func (vf *Verifier) insertBlock(block *BlockInfo) error { vf.Mutex.Unlock() return nil +} + +func (vf *Verifier) Close() { + vf.L2Client.Close() } \ No newline at end of file From c64b52026f640a398fda2574b39024317c19c95a Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:17:52 +0800 Subject: [PATCH 33/93] fix: remove ProcessNBlocks --- verifier/verifier/verifier.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index ba7df17..9528c6d 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -68,13 +68,6 @@ func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { // This function process blocks indefinitely, starting from the last finalized block. func (vf *Verifier) ProcessBlocks() error { - return vf.ProcessNBlocks(-1) -} - -// This function process n blocks, starting from the last finalized block. -// n is the number of blocks to process, pass in -1 to process blocks indefinitely. -// Passing in non-negative n is useful for testing. -func (vf *Verifier) ProcessNBlocks(n int) error { // Start service at last finalized block err := vf.startService() if err != nil { @@ -84,10 +77,6 @@ func (vf *Verifier) ProcessNBlocks(n int) error { // Start polling for new blocks at set interval ticker := time.NewTicker(vf.PollInterval) for range ticker.C { - // If n is positive and we have processed n blocks, stop the process - if n > 0 && vf.currHeight == vf.startHeight + uint64(n - 1) { - break - } block, err := vf.getBlockByNumber(int64(vf.currHeight + 1)) if err != nil { log.Fatalf("error getting new block: %v\n", err) From 4a400c8e33578229e1407c79af3908b2cf3e0c1f Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:18:09 +0800 Subject: [PATCH 34/93] fix: handle stop error --- verifier/cmd/start.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/verifier/cmd/start.go b/verifier/cmd/start.go index 3363419..2eac73a 100644 --- a/verifier/cmd/start.go +++ b/verifier/cmd/start.go @@ -89,7 +89,9 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { } // Call Stop method when interrupt signal is received - s.Stop() - + if err := s.Stop(); err != nil { + log.Fatalf("Error stopping server: %v\n", err) + return err + } return nil } \ No newline at end of file From b167bcdee9b5472668dd10e69a0011a949b7366c Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:30:03 +0800 Subject: [PATCH 35/93] fix: handle non-existent latest consecutively finalized block --- verifier/db/bbolt.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/verifier/db/bbolt.go b/verifier/db/bbolt.go index 1f758e9..923b218 100644 --- a/verifier/db/bbolt.go +++ b/verifier/db/bbolt.go @@ -214,6 +214,14 @@ func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock() (*Block, error) { return nil }) if err != nil { + // If no latest block has been stored yet, return empty block (block 0) + if errors.Is(err, ErrBlockNotFound) { + return &Block{ + BlockHeight: 0, + BlockHash: "", + IsFinalized: false, + }, nil + } log.Fatalf("Error getting latest block: %v\n", err) return nil, err } From a7ee7dc6ccf9d3040315ce147c34c30b494c15e6 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:30:56 +0800 Subject: [PATCH 36/93] chore: rm deprecated pg handler --- verifier/db/postgres.go | 153 ---------------------------------------- 1 file changed, 153 deletions(-) delete mode 100644 verifier/db/postgres.go diff --git a/verifier/db/postgres.go b/verifier/db/postgres.go deleted file mode 100644 index b8f4489..0000000 --- a/verifier/db/postgres.go +++ /dev/null @@ -1,153 +0,0 @@ -// DEPRECATED - use bbolt.go instead - -package db - -import ( - "context" - "fmt" - "log" - - "github.com/jackc/pgx/v5" -) - -type PostgresHandler struct { - conn *pgx.Conn -} - -const ( - createTablesSql = ` - CREATE TABLE IF NOT EXISTS blocks ( - block_height INTEGER PRIMARY KEY, - block_hash TEXT NOT NULL, - block_timestamp INTEGER NOT NULL, - is_finalized BOOLEAN NOT NULL - ); - CREATE INDEX IF NOT EXISTS blocks_hash_idx ON blocks (block_hash, block_timestamp); - ` - insertBlockSql = ` - INSERT INTO blocks (block_height, block_hash, block_timestamp, is_finalized) VALUES ($1, $2, $3, $4) - ` - getBlockStatusByHeightSql = ` - SELECT is_finalized FROM blocks WHERE block_height = $1 - ` - getBlockStatusByHashSql = ` - SELECT is_finalized FROM blocks WHERE block_hash = $1 - ` - getLatestBlockSql = ` - SELECT block_height, block_hash, block_timestamp, is_finalized FROM blocks ORDER BY block_height DESC LIMIT 1 - ` - getLatestConsecutivelyFinalizedBlockSql = ` - SELECT b.block_height, b.block_hash, b.block_timestamp, b.is_finalized - FROM blocks b - JOIN blocks prev ON b.block_height = prev.block_height + 1 - WHERE b.is_finalized = TRUE AND prev.is_finalized = TRUE - ORDER BY b.block_height DESC - LIMIT 1; - ` -) - -func NewPostgresHandler(ctx context.Context, connString string) (*PostgresHandler, error) { - conn, err := pgx.Connect(ctx, connString) - if err != nil { - return nil, err - } - - return &PostgresHandler{ - conn: conn, - }, nil -} - -func (pg *PostgresHandler) TryCreateInitialTables(ctx context.Context) error { - // Execute the SQL statements - _, err := pg.conn.Exec(ctx, createTablesSql) - if err != nil { - return fmt.Errorf("unable to execute SQL statements: %v", err) - } - - return nil -} - -func (pg *PostgresHandler) InsertBlock(ctx context.Context, block Block) error { - log.Printf("Inserting block %d into DB\n", block.BlockHeight) - - // Start atomic insert tx - tx, err := pg.conn.Begin(ctx) - if err != nil { - return fmt.Errorf("unable to start DB tx: %v", err) - } - - // Insert block - _, err = tx.Exec( - ctx, - insertBlockSql, - block.BlockHeight, - block.BlockHash, - block.BlockTimestamp, - block.IsFinalized, - ) - // Rollback tx if error - if err != nil { - if rollbackErr := tx.Rollback(ctx); rollbackErr != nil { - return fmt.Errorf("unable to insert block: %v, unable to rollback transaction: %v", err, rollbackErr) - } - return fmt.Errorf("unable to insert block: %v", err) - } - - // Commit tx if no error - if err := tx.Commit(ctx); err != nil { - return fmt.Errorf("unable to commit transaction: %v", err) - } - - return nil -} - -func (pg *PostgresHandler) GetBlockStatusByHeight(ctx context.Context, blockHeight uint64) bool { - var isFinalized bool - err := pg.conn.QueryRow(ctx, getBlockStatusByHeightSql, blockHeight).Scan(&isFinalized) - if err != nil { - log.Fatalf("GetBlockStatusByHeight: %v\n", err) - return false - } - - return isFinalized -} - -func (pg *PostgresHandler) GetBlockStatusByHash(ctx context.Context, blockHash string) bool { - var isFinalized bool - err := pg.conn.QueryRow(ctx, getBlockStatusByHashSql, blockHash).Scan(&isFinalized) - - if err != nil { - log.Fatalf("GetBlockStatusByHash: %v\n", err) - return false - } - - return isFinalized -} - -func (pg *PostgresHandler) GetLatestBlock(ctx context.Context) (*Block, error) { - var block Block - err := pg.conn.QueryRow(ctx, getLatestBlockSql).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) - if err != nil { - if err == pgx.ErrNoRows { - // If no rows are returned, return a block with BlockHeight = 0 - return &Block{BlockHeight: 0}, nil - } - return nil, fmt.Errorf("unable to get latest block: %v", err) - } - - return &block, nil -} - -func (pg *PostgresHandler) GetLatestConsecutivelyFinalizedBlock(ctx context.Context) (*Block, error) { - var block Block - err := pg.conn.QueryRow(ctx, getLatestConsecutivelyFinalizedBlockSql).Scan(&block.BlockHeight, &block.BlockHash, &block.BlockTimestamp, &block.IsFinalized) - if err != nil { - return nil, fmt.Errorf("unable to get latest consecutively finalized block: %v", err) - } - - return &block, nil -} - -func (pg *PostgresHandler) Close(ctx context.Context) { - pg.conn.Close(ctx) -} \ No newline at end of file From 43901f4d499f7accaaa33e8e2dc2743b69550928 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:37:09 +0800 Subject: [PATCH 37/93] chore: fix formatting --- verifier/cmd/main.go | 8 ++--- verifier/cmd/start.go | 6 ++-- verifier/db/bbolt.go | 24 +++++++------- verifier/db/models.go | 10 +++--- verifier/server/handlers.go | 7 ++-- verifier/server/server.go | 12 +++---- verifier/verifier/verifier.go | 62 +++++++++++++++++------------------ 7 files changed, 64 insertions(+), 65 deletions(-) diff --git a/verifier/cmd/main.go b/verifier/cmd/main.go index 920fd7b..67679c2 100644 --- a/verifier/cmd/main.go +++ b/verifier/cmd/main.go @@ -11,10 +11,10 @@ import ( func NewRootCmd() *cobra.Command { rootCmd := &cobra.Command{ - Use: "vrf", - Short: "vrf - Babylon OP Finality Gadget Verifier", - Long: `vrf is a daemon to track consecutive quorum and query the Babylon BTC block finalization status of OP stack chains.`, - SilenceErrors: false, + Use: "vrf", + Short: "vrf - Babylon OP Finality Gadget Verifier", + Long: `vrf is a daemon to track consecutive quorum and query the Babylon BTC block finalization status of OP stack chains.`, + SilenceErrors: false, } return rootCmd diff --git a/verifier/cmd/start.go b/verifier/cmd/start.go index 2eac73a..e1ae9b7 100644 --- a/verifier/cmd/start.go +++ b/verifier/cmd/start.go @@ -64,8 +64,8 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { // Start server s, err := server.Start(&server.ServerConfig{ - Port: cfg.ServerPort, - Db: db, + Port: cfg.ServerPort, + Db: db, }) if err != nil { log.Fatalf("Error starting server: %v\n", err) @@ -94,4 +94,4 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { return err } return nil -} \ No newline at end of file +} diff --git a/verifier/db/bbolt.go b/verifier/db/bbolt.go index 923b218..5a2d861 100644 --- a/verifier/db/bbolt.go +++ b/verifier/db/bbolt.go @@ -16,11 +16,11 @@ type BBoltHandler struct { } const ( - blocksBucket = "blocks" - blockHeightsBucket = "block_heights" - latestBlockBucket = "latest_block" - latestBlockKey = "latest" - latestConsecutiveBlockKey = "latest_consecutive" + blocksBucket = "blocks" + blockHeightsBucket = "block_heights" + latestBlockBucket = "latest_block" + latestBlockKey = "latest" + latestConsecutiveBlockKey = "latest_consecutive" ) var ( @@ -62,7 +62,7 @@ func tryCreateBucket(tx *bolt.Tx, bucketName string) error { return err } -func (bb *BBoltHandler) InsertBlock(block Block) error { +func (bb *BBoltHandler) InsertBlock(block *Block) error { log.Printf("Inserting block %d to DB...\n", block.BlockHeight) // Store mapping number -> block @@ -114,7 +114,7 @@ func (bb *BBoltHandler) InsertBlock(block Block) error { return err } - // Update latest consecutive block if it's the latest and it's consecutive to + // Update latest consecutive block if it's the latest and it's consecutive to // the previous one err = bb.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(latestBlockBucket)) @@ -190,14 +190,14 @@ func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { if errors.Is(err, ErrBlockNotFound) { return &Block{ BlockHeight: 0, - BlockHash: "", + BlockHash: "", IsFinalized: false, }, nil } log.Fatalf("Error getting latest block: %v\n", err) return nil, err } - + // Fetch latest block by height return bb.GetBlockByHeight(latestBlockHeight) } @@ -218,7 +218,7 @@ func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock() (*Block, error) { if errors.Is(err, ErrBlockNotFound) { return &Block{ BlockHeight: 0, - BlockHash: "", + BlockHash: "", IsFinalized: false, }, nil } @@ -239,7 +239,7 @@ func itob(v uint64) []byte { log.Fatalf("Error writing to buffer: %v\n", err) } return buf.Bytes() - } +} func btoi(b []byte) uint64 { var v uint64 @@ -249,4 +249,4 @@ func btoi(b []byte) uint64 { log.Fatalf("Error reading from buffer: %v\n", err) } return v -} \ No newline at end of file +} diff --git a/verifier/db/models.go b/verifier/db/models.go index 35ecb08..656330e 100644 --- a/verifier/db/models.go +++ b/verifier/db/models.go @@ -1,8 +1,8 @@ package db type Block struct { - BlockHash string `json:"block_hash" description:"block hash"` - BlockHeight uint64 `json:"block_height" description:"block height"` - BlockTimestamp uint64 `json:"block_timestamp" description:"block timestamp"` - IsFinalized bool `json:"is_finalized" description:"babylon block finality status"` -} \ No newline at end of file + BlockHash string `json:"block_hash" description:"block hash"` + BlockHeight uint64 `json:"block_height" description:"block height"` + BlockTimestamp uint64 `json:"block_timestamp" description:"block timestamp"` + IsFinalized bool `json:"is_finalized" description:"babylon block finality status"` +} diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go index a8703f5..8971035 100644 --- a/verifier/server/handlers.go +++ b/verifier/server/handlers.go @@ -32,7 +32,7 @@ func (s *Server) getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) isFinal := s.db.GetBlockStatusByHeight(uint64(blockHeight)) // Marshal and return status - jsonResponse, err := json.Marshal(StatusResponse { + jsonResponse, err := json.Marshal(StatusResponse{ IsFinalized: isFinal, }) if err != nil { @@ -53,12 +53,12 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Missing required params: hash\n") return } - + // Fetch status from DB isFinal := s.db.GetBlockStatusByHash(hash) // Marshal and return status - jsonResponse, err := json.Marshal(StatusResponse { + jsonResponse, err := json.Marshal(StatusResponse{ IsFinalized: isFinal, }) if err != nil { @@ -91,4 +91,3 @@ func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r * http.Error(w, "unable to write JSON response", http.StatusInternalServerError) } } - diff --git a/verifier/server/server.go b/verifier/server/server.go index 13225c4..8fd75fe 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -10,13 +10,13 @@ import ( ) type Server struct { - server *http.Server - db *db.BBoltHandler + server *http.Server + db *db.BBoltHandler } type ServerConfig struct { - Db *db.BBoltHandler - Port string + Db *db.BBoltHandler + Port string } func Start(cfg *ServerConfig) (*Server, error) { @@ -29,7 +29,7 @@ func Start(cfg *ServerConfig) (*Server, error) { Addr: ":" + cfg.Port, Handler: router, }, - db: cfg.Db, + db: cfg.Db, } // Define routes. @@ -51,4 +51,4 @@ func Start(cfg *ServerConfig) (*Server, error) { func (s *Server) Stop() error { log.Println("Stopping server...") return s.server.Close() -} \ No newline at end of file +} diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 9528c6d..0cde9c3 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -20,21 +20,21 @@ import ( ) type Verifier struct { - SdkClient *client.SdkClient - L2Client *ethclient.Client - Db *db.BBoltHandler + SdkClient *client.SdkClient + L2Client *ethclient.Client + Db *db.BBoltHandler - Mutex sync.Mutex + Mutex sync.Mutex - PollInterval time.Duration - startHeight uint64 - currHeight uint64 + PollInterval time.Duration + startHeight uint64 + currHeight uint64 } type BlockInfo struct { - Hash string - Height uint64 - Timestamp uint64 + Hash string + Height uint64 + Timestamp uint64 } func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { @@ -44,8 +44,8 @@ func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { sdkClient, err := client.NewClient(&sdkconfig.Config{ BTCConfig: btcConfig, ContractAddr: cfg.FGContractAddress, - ChainID: cfg.BBNChainID, - RPCAddr: cfg.BBNRPCAddress, + ChainID: cfg.BBNChainID, + RPCAddr: cfg.BBNRPCAddress, }) if err != nil { return nil, fmt.Errorf("error creating client: %w", err) @@ -59,9 +59,9 @@ func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { // Create verifier return &Verifier{ - SdkClient: sdkClient, - L2Client: l2Client, - Db: db, + SdkClient: sdkClient, + L2Client: l2Client, + Db: db, PollInterval: cfg.PollInterval, }, nil } @@ -107,16 +107,16 @@ func (vf *Verifier) startService() error { // if local chain tip is ahead of node, start service at latest block if localBlock.BlockHeight != 0 && localBlock.BlockHeight >= block.Height { block = &BlockInfo{ - Height: localBlock.BlockHeight, - Hash: localBlock.BlockHash, - Timestamp: localBlock.BlockTimestamp, + Height: localBlock.BlockHeight, + Hash: localBlock.BlockHash, + Timestamp: localBlock.BlockTimestamp, } } else { // throw if block height is 0 if block.Height == 0 { return fmt.Errorf("block height 0") } - + // Check the block is finalized using sdk client isFinal, err := vf.queryIsBlockBabylonFinalized(block) // If not finalized, throw error @@ -155,9 +155,9 @@ func (vf *Verifier) getBlockByNumber(blockNumber int64) (*BlockInfo, error) { return nil, err } return &BlockInfo{ - Height: header.Number.Uint64(), - Hash: hex.EncodeToString(header.Hash().Bytes()), - Timestamp: header.Time, + Height: header.Number.Uint64(), + Hash: hex.EncodeToString(header.Hash().Bytes()), + Timestamp: header.Time, }, nil } @@ -186,9 +186,9 @@ func (vf *Verifier) handleBlock(block *BlockInfo) { func (vf *Verifier) queryIsBlockBabylonFinalized(block *BlockInfo) (bool, error) { return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ - BlockHash: string(block.Hash), - BlockHeight: block.Height, - BlockTimestamp: block.Timestamp, + BlockHash: string(block.Hash), + BlockHeight: block.Height, + BlockTimestamp: block.Timestamp, }) } @@ -196,11 +196,11 @@ func (vf *Verifier) insertBlock(block *BlockInfo) error { // Lock mutex vf.Mutex.Lock() // Store block in DB - err := vf.Db.InsertBlock(db.Block{ - BlockHeight: block.Height, - BlockHash: block.Hash, - BlockTimestamp: block.Timestamp, - IsFinalized: true, + err := vf.Db.InsertBlock(&db.Block{ + BlockHeight: block.Height, + BlockHash: block.Hash, + BlockTimestamp: block.Timestamp, + IsFinalized: true, }) if err != nil { return err @@ -215,4 +215,4 @@ func (vf *Verifier) insertBlock(block *BlockInfo) error { func (vf *Verifier) Close() { vf.L2Client.Close() -} \ No newline at end of file +} From cf6073107e8654b502497822455427f509993ec8 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:40:02 +0800 Subject: [PATCH 38/93] fix: remove .db --- .gitignore | 3 ++- verifier/data.db | Bin 131072 -> 0 bytes 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 verifier/data.db diff --git a/.gitignore b/.gitignore index acce1e2..4baa48f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/target/ .DS_Store **/.env -**/.db \ No newline at end of file +**/*.db +*.db \ No newline at end of file diff --git a/verifier/data.db b/verifier/data.db deleted file mode 100644 index 80db1d196a2f3781497676d94270cbbbf9a1c15d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 zcmeI*JB%bp8Nl)74loac5CVw+8EZuVl0o(AdYpa22?>(5Y=#JYuBxuOJ$!zMJ0k=l zCm^tqAR!?nL?mE4AtWb3NFa-d#5qn7U+?yu=Gxn>TaDzv{M)yl{dQ)0zW#MRx>x#Y zkB%<3kIs+p{{8WHuT9@Sd+~$o7Y`5qzkA)s=bw!8<3E4tzV?IHzxl5RFXS5p5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILcw~W(%&*+l^)KuH&({Lj+uO(H?|1e8b&lVA=T}dh zzVX{<_Fl@j2q1s}0tg_000IagfB*srAbWjC|+MU~H_wPx3>2~et3lDz&tnBew zi9Rv^&c>n$1Tg0y~;=e57={Wb_9~befi}-ho_?<=kC0RLPe}CUy z#6Mree_q7@S;R_KSlHj+*#a77hsOVeH{+gh+r5`}b=OoHZ7jvMnB_mEi*tG`*|$2_c(I?; zXG~}@nzX8|8#iWcN7Z$(H78YV7;3E18?Ogrtx03;)tWh< z%C+Q&C?D>7P9ewEbtypviynjO#ShMv+O-vmAw)Thq0RZEL0(d_PLkJ{1$l_gH!sX3 zt5Cp`{BgC4yfa`9pmM}&dKeL>t?j0twT`J`J7dntWs^V=h&4rDI2tR!OQ1(Q66=dkFwJTxGJACnlvBR z+et-}ixCAcr^lI8(pYSimucSwpjg#|_wv5hQ}RLE-hGv(>0`@-vh#6`X&j0zP9BpQ zj2IY|i_<#h?oBgAY=ds2PN}I_Le^dyiV>tXN~0Zi`{^RAl$N$)bVxmkjni(F{pD1K zlB8|RVUNv<-Td>->I>te( zlC6?vD!Gb&cWUg~gt;A_-WZLO9@fV;*sS_!qBg#3If+e`u9KYS+FdV$v&xzwI}=4s zdZX<{dbHae*X>cdaQ99QNP0sVdN9(HU6kYR*~KDF-1br0s!`QTH%`XaqHOS1wXwT# z8pox-pFZ7;beq)WES4ak%GJ<^CMQF;7^BNVlC1I409+HhX>b^1? z(RHKKAV*%uUV}8oIEFEI>0nOA9??!(pkq;8I)yR4M;DXzeUv7xcH@Th0%<;S?yHT` z4uhQToLh}y>aJZ~Ge zIwxh3;-QoFYKm?v#jQc-q%KlC^g4MpMag1aakIOOixdyN6}|UD_hWL$6|1 zQxvFGMZ4Ku`Xa?cFZfqe+?b=2-Rv&67bzZk?Y^4g#vGmOW_LMTq)yyyDL%lBG+?f#t~?SAXSlB^RE8v+O* zfB*srAb=@iGs^3k#=*`qFCzCsc$Vs>i@5@z|!T4)c;>?nV3~Y>i@5>XwRx5_5W8`@@iFa zy;@k7!`iAAKB4}9UZY3G#r0}oS=DN*TKI(e{|AcH|6gUXx0N0}xb+@Q{r~%xfLv8v z@6pu%U#b58=6w6f0|E#jfB*srAb Date: Tue, 30 Jul 2024 14:43:08 +0800 Subject: [PATCH 39/93] chore: use relative path for db --- verifier/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier/config.toml b/verifier/config.toml index f3b2b1a..478880a 100644 --- a/verifier/config.toml +++ b/verifier/config.toml @@ -1,6 +1,6 @@ L2RPCHost = "https://mainnet.optimism.io" BitcoinRPCHost = "rpc.ankr.com/btc" -DBFilePath = "/Users/parkyeung/dev/babylon-finality-gadget/verifier/data.db" +DBFilePath = "data.db" FGContractAddress = "bbn1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqxxvh0f" BBNChainID = "euphrates-0.2.0" BBNRPCAddress = "https://rpc-euphrates.devnet.babylonchain.io" From 9a13ebb4fd351cc85eef508293a1d6237c6fd7ba Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:49:27 +0800 Subject: [PATCH 40/93] docs: update readme --- verifier/README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/verifier/README.md b/verifier/README.md index eb6eac4..f5dd90c 100644 --- a/verifier/README.md +++ b/verifier/README.md @@ -1,33 +1,33 @@ -# Babylon Verifier Program +# Babylon Verifier Daemon -This is a peripheral program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks via RESTful API endpoints. It is served as a Docker container for local use or hosted on a server. +This is a peripheral program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks via RESTful API endpoints. ## Running the daemon -To get started, clone the repository and navigate to the `/verifier` directory. +To get started, clone the repository. ```bash git clone https://github.com/babylonchain/babylon-finality-gadget.git -cd verifier ``` -Create a `.env` file in the `/verifier` directory with the following content: - -```bash -L2_RPC_HOST= -BITCOIN_RPC_HOST= -DB_FILE_PATH= -FG_CONTRACT_ADDRESS= -BBN_CHAIN_ID= -BBN_RPC_ADDRESS= -POLL_INTERVAL_IN_SECS= +Configure the `config.toml` file with the following content: + +```toml +L2RPCHost = # RPC URL of OP stack L2 chain +BitcoinRPCHost = # Bitcoin RPC URL +DBFilePath = # Path to local bbolt DB file +FGContractAddress = # Babylon finality gadget contract address +BBNChainID = # Babylon chain id +BBNRPCAddress = # Babylon RPC host URL +ServerPort = # Localhost port to serve the API +PollInterval = # Interval to poll for new L2 blocks ``` -To run the demo program: +To start the daemon, navigate to the `/verifier/cmd` directory: ```bash -cd verifier -go run demo/main.go +cd verifier/cmd +go run . start --cfg ../config.toml ``` From 00dd6dfb66ecd6fd59eb507fea21f4f0ee418fd8 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:49:34 +0800 Subject: [PATCH 41/93] chore: fix formatting --- verifier/config/config.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/verifier/config/config.go b/verifier/config/config.go index 76c2ec8..5ea85dd 100644 --- a/verifier/config/config.go +++ b/verifier/config/config.go @@ -7,14 +7,14 @@ import ( ) type Config struct { - L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` - BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` - FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` - BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` - BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` - DBFilePath string `long:"db-file-path" description:"path to the DB file"` - ServerPort string `long:"server-port" description:"port to start the verifier server"` - PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` + L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` + BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` + FGContractAddress string `long:"fg-contract-address" description:"BabylonChain op finality gadget contract address"` + BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` + BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` + DBFilePath string `long:"db-file-path" description:"path to the DB file"` + ServerPort string `long:"server-port" description:"port to start the verifier server"` + PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` } func Load(configPath string) (*Config, error) { @@ -22,13 +22,13 @@ func Load(configPath string) (*Config, error) { viper.SetConfigType("toml") if err := viper.ReadInConfig(); err != nil { - return nil, err + return nil, err } var config Config if err := viper.Unmarshal(&config); err != nil { - return nil, err + return nil, err } return &config, nil -} \ No newline at end of file +} From 71166c94a08a4e085e96c875dda88453bf8bcbdd Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 14:54:01 +0800 Subject: [PATCH 42/93] chore: clean unused deps --- go.mod | 3 --- go.sum | 8 -------- 2 files changed, 11 deletions(-) diff --git a/go.mod b/go.mod index 0bb71bb..efe8a63 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/cosmos/cosmos-sdk v0.50.6 github.com/ethereum/go-ethereum v1.13.15 github.com/gorilla/mux v1.8.1 - github.com/jackc/pgx/v5 v5.6.0 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 @@ -151,8 +150,6 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect diff --git a/go.sum b/go.sum index 4647e28..261baa6 100644 --- a/go.sum +++ b/go.sum @@ -791,14 +791,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= -github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= -github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= -github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= From f683157f22e35546ca95e8b39f6bdfc5a429bf65 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 21:38:38 +0800 Subject: [PATCH 43/93] feat: remove duplicate tracker for consecutively finalized block --- verifier/db/bbolt.go | 41 ----------------------------------- verifier/server/handlers.go | 4 ++-- verifier/server/server.go | 2 +- verifier/verifier/verifier.go | 1 - 4 files changed, 3 insertions(+), 45 deletions(-) diff --git a/verifier/db/bbolt.go b/verifier/db/bbolt.go index 5a2d861..d64fb5d 100644 --- a/verifier/db/bbolt.go +++ b/verifier/db/bbolt.go @@ -20,7 +20,6 @@ const ( blockHeightsBucket = "block_heights" latestBlockBucket = "latest_block" latestBlockKey = "latest" - latestConsecutiveBlockKey = "latest_consecutive" ) var ( @@ -114,20 +113,6 @@ func (bb *BBoltHandler) InsertBlock(block *Block) error { return err } - // Update latest consecutive block if it's the latest and it's consecutive to - // the previous one - err = bb.db.Update(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte(latestBlockBucket)) - if latestBlock.BlockHeight == block.BlockHeight-1 { - return b.Put([]byte(latestConsecutiveBlockKey), itob(block.BlockHeight)) - } - return nil - }) - if err != nil { - log.Fatalf("Error updating latest block: %v\n", err) - return err - } - return nil } @@ -202,32 +187,6 @@ func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { return bb.GetBlockByHeight(latestBlockHeight) } -func (bb *BBoltHandler) GetLatestConsecutivelyFinalizedBlock() (*Block, error) { - var latestBlockHeight uint64 - err := bb.db.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte(latestBlockBucket)) - v := b.Get([]byte(latestConsecutiveBlockKey)) - if v == nil { - return ErrBlockNotFound - } - latestBlockHeight = btoi(v) - return nil - }) - if err != nil { - // If no latest block has been stored yet, return empty block (block 0) - if errors.Is(err, ErrBlockNotFound) { - return &Block{ - BlockHeight: 0, - BlockHash: "", - IsFinalized: false, - }, nil - } - log.Fatalf("Error getting latest block: %v\n", err) - return nil, err - } - return bb.GetBlockByHeight(latestBlockHeight) -} - func (bb *BBoltHandler) Close() error { return bb.db.Close() } diff --git a/verifier/server/handlers.go b/verifier/server/handlers.go index 8971035..e8fe2a8 100644 --- a/verifier/server/handlers.go +++ b/verifier/server/handlers.go @@ -71,9 +71,9 @@ func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { } } -func (s *Server) getLatestConsecutivelyFinalizedBlock(w http.ResponseWriter, r *http.Request) { +func (s *Server) getLatestBlock(w http.ResponseWriter, r *http.Request) { // Fetch status from DB - block, err := s.db.GetLatestConsecutivelyFinalizedBlock() + block, err := s.db.GetLatestBlock() if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Error getting latest block: %v\n", err) diff --git a/verifier/server/server.go b/verifier/server/server.go index 8fd75fe..3c5552d 100644 --- a/verifier/server/server.go +++ b/verifier/server/server.go @@ -35,7 +35,7 @@ func Start(cfg *ServerConfig) (*Server, error) { // Define routes. router.HandleFunc("/getBlockStatusByHeight", s.getBlockStatusByHeight) router.HandleFunc("/getBlockStatusByHash", s.getBlockStatusByHash) - router.HandleFunc("/getLatest", s.getLatestConsecutivelyFinalizedBlock) + router.HandleFunc("/getLatest", s.getLatestBlock) // Start server in a goroutine. go func() { diff --git a/verifier/verifier/verifier.go b/verifier/verifier/verifier.go index 0cde9c3..21938b8 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier/verifier.go @@ -200,7 +200,6 @@ func (vf *Verifier) insertBlock(block *BlockInfo) error { BlockHeight: block.Height, BlockHash: block.Hash, BlockTimestamp: block.Timestamp, - IsFinalized: true, }) if err != nil { return err From 0fae16c139f4bfce8e847c63eb598d1dc9b1c4cc Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 21:45:45 +0800 Subject: [PATCH 44/93] chore: restructure verifier as part of sdk --- {verifier/cmd => cmd}/main.go | 0 {verifier/cmd => cmd}/start.go | 6 +++--- verifier/config.toml => config.toml | 0 {verifier/db => db}/bbolt.go | 0 {verifier/db => db}/models.go | 0 {verifier/server => server}/handlers.go | 0 {verifier/server => server}/server.go | 2 +- verifier/README.md | 4 ++-- verifier/{verifier => }/verifier.go | 2 +- 9 files changed, 7 insertions(+), 7 deletions(-) rename {verifier/cmd => cmd}/main.go (100%) rename {verifier/cmd => cmd}/start.go (91%) rename verifier/config.toml => config.toml (100%) rename {verifier/db => db}/bbolt.go (100%) rename {verifier/db => db}/models.go (100%) rename {verifier/server => server}/handlers.go (100%) rename {verifier/server => server}/server.go (94%) rename verifier/{verifier => }/verifier.go (98%) diff --git a/verifier/cmd/main.go b/cmd/main.go similarity index 100% rename from verifier/cmd/main.go rename to cmd/main.go diff --git a/verifier/cmd/start.go b/cmd/start.go similarity index 91% rename from verifier/cmd/start.go rename to cmd/start.go index e1ae9b7..9e2b8e1 100644 --- a/verifier/cmd/start.go +++ b/cmd/start.go @@ -10,10 +10,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" + "github.com/babylonchain/babylon-finality-gadget/db" + "github.com/babylonchain/babylon-finality-gadget/server" + "github.com/babylonchain/babylon-finality-gadget/verifier" "github.com/babylonchain/babylon-finality-gadget/verifier/config" - "github.com/babylonchain/babylon-finality-gadget/verifier/db" - "github.com/babylonchain/babylon-finality-gadget/verifier/server" - "github.com/babylonchain/babylon-finality-gadget/verifier/verifier" ) const ( diff --git a/verifier/config.toml b/config.toml similarity index 100% rename from verifier/config.toml rename to config.toml diff --git a/verifier/db/bbolt.go b/db/bbolt.go similarity index 100% rename from verifier/db/bbolt.go rename to db/bbolt.go diff --git a/verifier/db/models.go b/db/models.go similarity index 100% rename from verifier/db/models.go rename to db/models.go diff --git a/verifier/server/handlers.go b/server/handlers.go similarity index 100% rename from verifier/server/handlers.go rename to server/handlers.go diff --git a/verifier/server/server.go b/server/server.go similarity index 94% rename from verifier/server/server.go rename to server/server.go index 3c5552d..c995029 100644 --- a/verifier/server/server.go +++ b/server/server.go @@ -6,7 +6,7 @@ import ( "github.com/gorilla/mux" - "github.com/babylonchain/babylon-finality-gadget/verifier/db" + "github.com/babylonchain/babylon-finality-gadget/db" ) type Server struct { diff --git a/verifier/README.md b/verifier/README.md index f5dd90c..13d6b73 100644 --- a/verifier/README.md +++ b/verifier/README.md @@ -23,10 +23,10 @@ ServerPort = # Localhost port to serve the API PollInterval = # Interval to poll for new L2 blocks ``` -To start the daemon, navigate to the `/verifier/cmd` directory: +To start the daemon, navigate to the `/cmd` directory: ```bash -cd verifier/cmd +cd cmd go run . start --cfg ../config.toml ``` diff --git a/verifier/verifier/verifier.go b/verifier/verifier.go similarity index 98% rename from verifier/verifier/verifier.go rename to verifier/verifier.go index 21938b8..c2a3304 100644 --- a/verifier/verifier/verifier.go +++ b/verifier/verifier.go @@ -9,12 +9,12 @@ import ( "sync" "time" + "github.com/babylonchain/babylon-finality-gadget/db" "github.com/babylonchain/babylon-finality-gadget/sdk/btcclient" "github.com/babylonchain/babylon-finality-gadget/sdk/client" sdkconfig "github.com/babylonchain/babylon-finality-gadget/sdk/config" "github.com/babylonchain/babylon-finality-gadget/sdk/cwclient" "github.com/babylonchain/babylon-finality-gadget/verifier/config" - "github.com/babylonchain/babylon-finality-gadget/verifier/db" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" ) From 8ca6a6526ec566a0617a327145910c64a4628108 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 30 Jul 2024 22:01:22 +0800 Subject: [PATCH 45/93] fix: remove isFinalized bool from db type --- db/bbolt.go | 9 +++------ db/models.go | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/db/bbolt.go b/db/bbolt.go index d64fb5d..851298e 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -134,11 +134,8 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*Block, error) { } func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) bool { - block, err := bb.GetBlockByHeight(height) - if err != nil { - return false - } - return block.IsFinalized + _, err := bb.GetBlockByHeight(height) + return err == nil } func (bb *BBoltHandler) GetBlockStatusByHash(hash string) bool { @@ -176,7 +173,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { return &Block{ BlockHeight: 0, BlockHash: "", - IsFinalized: false, + BlockTimestamp: 0, }, nil } log.Fatalf("Error getting latest block: %v\n", err) diff --git a/db/models.go b/db/models.go index 656330e..a0980c6 100644 --- a/db/models.go +++ b/db/models.go @@ -4,5 +4,4 @@ type Block struct { BlockHash string `json:"block_hash" description:"block hash"` BlockHeight uint64 `json:"block_height" description:"block height"` BlockTimestamp uint64 `json:"block_timestamp" description:"block timestamp"` - IsFinalized bool `json:"is_finalized" description:"babylon block finality status"` } From f70295f29a7a5208c6602b0691eb403f2ca93f98 Mon Sep 17 00:00:00 2001 From: parketh Date: Wed, 31 Jul 2024 12:31:12 +0800 Subject: [PATCH 46/93] feat: refactor http -> grpc and rename verifier -> server --- client/rpcclient.go | 111 ++++ cmd/start.go | 49 +- config.toml | 2 +- db/bbolt.go | 39 +- {verifier => finalitygadget}/README.md | 2 +- {verifier => finalitygadget}/config/config.go | 2 +- .../finalitygadget.go | 132 ++-- finalitygadget/interface.go | 10 + go.mod | 8 +- go.sum | 6 +- proto/finalitygadget.pb.go | 619 ++++++++++++++++++ proto/finalitygadget.proto | 59 ++ proto/finalitygadget_grpc.pb.go | 267 ++++++++ server/handlers.go | 93 --- server/rpcserver.go | 92 +++ server/server.go | 125 +++- db/models.go => types/block.go | 2 +- 17 files changed, 1390 insertions(+), 228 deletions(-) create mode 100644 client/rpcclient.go rename {verifier => finalitygadget}/README.md (95%) rename {verifier => finalitygadget}/config/config.go (91%) rename verifier/verifier.go => finalitygadget/finalitygadget.go (52%) create mode 100644 finalitygadget/interface.go create mode 100644 proto/finalitygadget.pb.go create mode 100644 proto/finalitygadget.proto create mode 100644 proto/finalitygadget_grpc.pb.go delete mode 100644 server/handlers.go create mode 100644 server/rpcserver.go rename db/models.go => types/block.go (94%) diff --git a/client/rpcclient.go b/client/rpcclient.go new file mode 100644 index 0000000..959be37 --- /dev/null +++ b/client/rpcclient.go @@ -0,0 +1,111 @@ +package client + +import ( + "context" + "fmt" + + "github.com/babylonchain/babylon-finality-gadget/db" + "github.com/babylonchain/babylon-finality-gadget/proto" + "github.com/babylonchain/babylon-finality-gadget/types" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +type FinalityGadgetGrpcClient struct { + client proto.FinalityGadgetClient + conn *grpc.ClientConn + db *db.BBoltHandler +} + +func NewFinalityGadgetGrpcClient( + db *db.BBoltHandler, + remoteAddr string, +) (*FinalityGadgetGrpcClient, error) { + conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, fmt.Errorf("failed to build gRPC connection to %s: %w", remoteAddr, err) + } + + gClient := &FinalityGadgetGrpcClient{ + client: proto.NewFinalityGadgetClient(conn), + conn: conn, + db: db, + } + + if err := gClient.Ping(); err != nil { + return nil, fmt.Errorf("the finality gadget server is not responding: %w", err) + } + + return gClient, nil +} + +func (c *FinalityGadgetGrpcClient) Ping() error { + req := &proto.PingRequest{} + + _, err := c.client.Ping(context.Background(), req) + if err != nil { + return err + } + + return nil +} + +func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { + req := &proto.BlockInfo{ + BlockHash: block.BlockHash, + BlockHeight: block.BlockHeight, + BlockTimestamp: block.BlockTimestamp, + } + + res, err := c.client.InsertBlock(context.Background(), req) + if err != nil { + return false, err + } + + return res.Success, nil +} + +func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { + req := &proto.GetBlockStatusByHeightRequest{ + BlockHeight: height, + } + + res, err := c.client.GetBlockStatusByHeight(context.Background(), req) + if err != nil { + return false, err + } + + return res.IsFinalized, nil +} + +func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, error) { + req := &proto.GetBlockStatusByHashRequest{ + BlockHash: hash, + } + + res, err := c.client.GetBlockStatusByHash(context.Background(), req) + if err != nil { + return false, err + } + + return res.IsFinalized, nil +} + +func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { + req := &proto.GetLatestBlockRequest{} + + res, err := c.client.GetLatestBlock(context.Background(), req) + if err != nil { + return nil, err + } + + return &types.Block{ + BlockHash: res.BlockHash, + BlockHeight: res.BlockHeight, + BlockTimestamp: res.BlockTimestamp, + }, nil +} + +func (c *FinalityGadgetGrpcClient) Close() error { + return c.conn.Close() +} diff --git a/cmd/start.go b/cmd/start.go index 9e2b8e1..547075e 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -10,10 +10,12 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" + rpcclient "github.com/babylonchain/babylon-finality-gadget/client" "github.com/babylonchain/babylon-finality-gadget/db" + "github.com/babylonchain/babylon-finality-gadget/finalitygadget" + "github.com/babylonchain/babylon-finality-gadget/finalitygadget/config" "github.com/babylonchain/babylon-finality-gadget/server" - "github.com/babylonchain/babylon-finality-gadget/verifier" - "github.com/babylonchain/babylon-finality-gadget/verifier/config" + sig "github.com/lightningnetwork/lnd/signal" ) const ( @@ -55,20 +57,32 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { return fmt.Errorf("create initial buckets error: %w", err) } - // Create verifier - vrf, err := verifier.NewVerifier(cfg, db) + // Create finality gadget + fg, err := finalitygadget.NewFinalityGadget(cfg, db) if err != nil { - return fmt.Errorf("error creating verifier: %v", err) + log.Fatalf("Error creating finality gadget: %v\n", err) + return fmt.Errorf("error creating finality gadget: %v", err) } - defer vrf.Close() - // Start server - s, err := server.Start(&server.ServerConfig{ - Port: cfg.ServerPort, - Db: db, - }) + // Start grpc server + // Hook interceptor for os signals. + shutdownInterceptor, err := sig.Intercept() if err != nil { - log.Fatalf("Error starting server: %v\n", err) + return err + } + srv := server.NewFinalityGadgetServer(cfg, db, fg, shutdownInterceptor) + go func() { + if err := srv.RunUntilShutdown(); err != nil { + log.Fatalf("Finality gadget server error: %v\n", err) + } + }() + + // Create grpc client + hostAddr := "localhost:" + cfg.GRPCServerPort + client, err := rpcclient.NewFinalityGadgetGrpcClient(db, hostAddr) + if err != nil { + log.Fatalf("Error creating grpc client: %v\n", err) + return fmt.Errorf("error creating grpc client: %v", err) } // Set up channel to listen for interrupt signal @@ -77,7 +91,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { // Run verifier in a separate goroutine go func() { - if err := vrf.ProcessBlocks(); err != nil { + if err := fg.ProcessBlocks(); err != nil { log.Fatalf("Error processing blocks: %v\n", err) } }() @@ -88,10 +102,13 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { fmt.Print("\r") } - // Call Stop method when interrupt signal is received - if err := s.Stop(); err != nil { - log.Fatalf("Error stopping server: %v\n", err) + // Call Close method when interrupt signal is received + log.Printf("Closing finality gadget server...") + if err := client.Close(); err != nil { + log.Fatalf("Error stopping grpc client: %v\n", err) return err } + fg.Close() + return nil } diff --git a/config.toml b/config.toml index 478880a..338f0c8 100644 --- a/config.toml +++ b/config.toml @@ -4,5 +4,5 @@ DBFilePath = "data.db" FGContractAddress = "bbn1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqxxvh0f" BBNChainID = "euphrates-0.2.0" BBNRPCAddress = "https://rpc-euphrates.devnet.babylonchain.io" -ServerPort = "8080" +GRPCServerPort = "8080" PollInterval = "10s" \ No newline at end of file diff --git a/db/bbolt.go b/db/bbolt.go index 851298e..906cc77 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -8,6 +8,7 @@ import ( "log" "time" + "github.com/babylonchain/babylon-finality-gadget/types" bolt "go.etcd.io/bbolt" ) @@ -16,10 +17,10 @@ type BBoltHandler struct { } const ( - blocksBucket = "blocks" - blockHeightsBucket = "block_heights" - latestBlockBucket = "latest_block" - latestBlockKey = "latest" + blocksBucket = "blocks" + blockHeightsBucket = "block_heights" + latestBlockBucket = "latest_block" + latestBlockKey = "latest" ) var ( @@ -40,7 +41,7 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { } func (bb *BBoltHandler) TryCreateInitialBuckets() error { - log.Printf("Creating initial DB buckets...") + log.Printf("Initialising DB...") return bb.db.Update(func(tx *bolt.Tx) error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} for _, bucket := range buckets { @@ -61,7 +62,7 @@ func tryCreateBucket(tx *bolt.Tx, bucketName string) error { return err } -func (bb *BBoltHandler) InsertBlock(block *Block) error { +func (bb *BBoltHandler) InsertBlock(block *types.Block) error { log.Printf("Inserting block %d to DB...\n", block.BlockHeight) // Store mapping number -> block @@ -116,8 +117,8 @@ func (bb *BBoltHandler) InsertBlock(block *Block) error { return nil } -func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*Block, error) { - var block Block +func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { + var block types.Block err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blocksBucket)) v := b.Get(itob(height)) @@ -133,12 +134,18 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*Block, error) { return &block, nil } -func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) bool { +func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { _, err := bb.GetBlockByHeight(height) - return err == nil + if err != nil { + if errors.Is(err, ErrBlockNotFound) { + return false, nil + } + return false, err + } + return true, nil } -func (bb *BBoltHandler) GetBlockStatusByHash(hash string) bool { +func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { // Fetch block number by hash var blockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { @@ -148,13 +155,13 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) bool { }) if err != nil { log.Fatalf("Error getting block by hash: %v\n", err) - return false + return false, err } return bb.GetBlockStatusByHeight(blockHeight) } -func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { +func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { var latestBlockHeight uint64 // Fetch latest block height @@ -170,9 +177,9 @@ func (bb *BBoltHandler) GetLatestBlock() (*Block, error) { if err != nil { // If no latest block has been stored yet, return empty block (block 0) if errors.Is(err, ErrBlockNotFound) { - return &Block{ - BlockHeight: 0, - BlockHash: "", + return &types.Block{ + BlockHeight: 0, + BlockHash: "", BlockTimestamp: 0, }, nil } diff --git a/verifier/README.md b/finalitygadget/README.md similarity index 95% rename from verifier/README.md rename to finalitygadget/README.md index 13d6b73..1f39e77 100644 --- a/verifier/README.md +++ b/finalitygadget/README.md @@ -19,7 +19,7 @@ DBFilePath = # Path to local bbolt DB file FGContractAddress = # Babylon finality gadget contract address BBNChainID = # Babylon chain id BBNRPCAddress = # Babylon RPC host URL -ServerPort = # Localhost port to serve the API +GRPCServerPort = # Port to run the gRPC server on PollInterval = # Interval to poll for new L2 blocks ``` diff --git a/verifier/config/config.go b/finalitygadget/config/config.go similarity index 91% rename from verifier/config/config.go rename to finalitygadget/config/config.go index 5ea85dd..063f217 100644 --- a/verifier/config/config.go +++ b/finalitygadget/config/config.go @@ -13,7 +13,7 @@ type Config struct { BBNChainID string `long:"bbn-chain-id" description:"BabylonChain chain ID"` BBNRPCAddress string `long:"bbn-rpc-address" description:"BabylonChain chain RPC address"` DBFilePath string `long:"db-file-path" description:"path to the DB file"` - ServerPort string `long:"server-port" description:"port to start the verifier server"` + GRPCServerPort string `long:"grpc-server-port" description:"port of the gRPC server"` PollInterval time.Duration `long:"retry-interval" description:"interval in seconds to recheck Babylon finality of block"` } diff --git a/verifier/verifier.go b/finalitygadget/finalitygadget.go similarity index 52% rename from verifier/verifier.go rename to finalitygadget/finalitygadget.go index c2a3304..0b66ef7 100644 --- a/verifier/verifier.go +++ b/finalitygadget/finalitygadget.go @@ -1,4 +1,4 @@ -package verifier +package finalitygadget import ( "context" @@ -10,16 +10,19 @@ import ( "time" "github.com/babylonchain/babylon-finality-gadget/db" + "github.com/babylonchain/babylon-finality-gadget/finalitygadget/config" "github.com/babylonchain/babylon-finality-gadget/sdk/btcclient" "github.com/babylonchain/babylon-finality-gadget/sdk/client" sdkconfig "github.com/babylonchain/babylon-finality-gadget/sdk/config" "github.com/babylonchain/babylon-finality-gadget/sdk/cwclient" - "github.com/babylonchain/babylon-finality-gadget/verifier/config" + "github.com/babylonchain/babylon-finality-gadget/types" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" ) -type Verifier struct { +var _ IFinalityGadget = &FinalityGadget{} + +type FinalityGadget struct { SdkClient *client.SdkClient L2Client *ethclient.Client Db *db.BBoltHandler @@ -31,13 +34,7 @@ type Verifier struct { currHeight uint64 } -type BlockInfo struct { - Hash string - Height uint64 - Timestamp uint64 -} - -func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { +func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget, error) { // Create finality gadget client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost @@ -58,7 +55,7 @@ func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { } // Create verifier - return &Verifier{ + return &FinalityGadget{ SdkClient: sdkClient, L2Client: l2Client, Db: db, @@ -67,23 +64,23 @@ func NewVerifier(cfg *config.Config, db *db.BBoltHandler) (*Verifier, error) { } // This function process blocks indefinitely, starting from the last finalized block. -func (vf *Verifier) ProcessBlocks() error { +func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block - err := vf.startService() + err := s.startService() if err != nil { return fmt.Errorf("%v", err) } // Start polling for new blocks at set interval - ticker := time.NewTicker(vf.PollInterval) + ticker := time.NewTicker(s.PollInterval) for range ticker.C { - block, err := vf.getBlockByNumber(int64(vf.currHeight + 1)) + block, err := s.getBlockByNumber(int64(s.currHeight + 1)) if err != nil { log.Fatalf("error getting new block: %v\n", err) continue } go func() { - vf.handleBlock(block) + s.handleBlock(block) }() } @@ -91,127 +88,140 @@ func (vf *Verifier) ProcessBlocks() error { } // Start service at last finalized block -func (vf *Verifier) startService() error { +func (s *FinalityGadget) startService() error { // Query L2 node for last finalized block - block, err := vf.getLatestFinalizedBlock() + block, err := s.getLatestFinalizedBlock() if err != nil { return fmt.Errorf("error getting last finalized block: %v", err) } // Query local DB for last block processed - localBlock, err := vf.Db.GetLatestBlock() + localBlock, err := s.Db.GetLatestBlock() if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } // if local chain tip is ahead of node, start service at latest block - if localBlock.BlockHeight != 0 && localBlock.BlockHeight >= block.Height { - block = &BlockInfo{ - Height: localBlock.BlockHeight, - Hash: localBlock.BlockHash, - Timestamp: localBlock.BlockTimestamp, + if localBlock.BlockHeight != 0 && localBlock.BlockHeight >= block.BlockHeight { + block = &types.Block{ + BlockHeight: localBlock.BlockHeight, + BlockHash: localBlock.BlockHash, + BlockTimestamp: localBlock.BlockTimestamp, } } else { // throw if block height is 0 - if block.Height == 0 { + if block.BlockHeight == 0 { return fmt.Errorf("block height 0") } // Check the block is finalized using sdk client - isFinal, err := vf.queryIsBlockBabylonFinalized(block) + isFinal, err := s.queryIsBlockBabylonFinalized(block) // If not finalized, throw error if !isFinal { - return fmt.Errorf("block %d should be finalized according to client but is not", block.Height) + return fmt.Errorf("block %d should be finalized according to client but is not", block.BlockHeight) } if err != nil { - return fmt.Errorf("error checking block %d: %v", block.Height, err) + return fmt.Errorf("error checking block %d: %v", block.BlockHeight, err) } // If finalised, store the block in DB and set the last finalized block - err = vf.insertBlock(block) + err = s.InsertBlock(block) if err != nil { - return fmt.Errorf("error storing block %d: %v", block.Height, err) + return fmt.Errorf("error storing block %d: %v", block.BlockHeight, err) } } // Start service at block height - log.Printf("Starting verifier at block %d...\n", block.Height) + log.Printf("Starting verifier at block %d...\n", block.BlockHeight) // Set the start block and curr finalized block in memory - vf.startHeight = block.Height - vf.currHeight = block.Height + s.startHeight = block.BlockHeight + s.currHeight = block.BlockHeight return nil } // Get last btc finalized block -func (vf *Verifier) getLatestFinalizedBlock() (*BlockInfo, error) { - return vf.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) +func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { + return s.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } // Get block by number -func (vf *Verifier) getBlockByNumber(blockNumber int64) (*BlockInfo, error) { - header, err := vf.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) +func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { + header, err := s.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err } - return &BlockInfo{ - Height: header.Number.Uint64(), - Hash: hex.EncodeToString(header.Hash().Bytes()), - Timestamp: header.Time, + return &types.Block{ + BlockHeight: header.Number.Uint64(), + BlockHash: hex.EncodeToString(header.Hash().Bytes()), + BlockTimestamp: header.Time, }, nil } -func (vf *Verifier) handleBlock(block *BlockInfo) { +func (s *FinalityGadget) handleBlock(block *types.Block) { // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { // Check if block is finalized - isFinal, err := vf.queryIsBlockBabylonFinalized(block) + isFinal, err := s.queryIsBlockBabylonFinalized(block) if err != nil { - log.Fatalf("Error checking block %d: %v\n", block.Height, err) + log.Fatalf("Error checking block %d: %v\n", block.BlockHeight, err) return } if isFinal { - err = vf.insertBlock(block) + err = s.InsertBlock(block) if err != nil { - log.Fatalf("Error storing block %d: %v\n", block.Height, err) + log.Fatalf("Error storing block %d: %v\n", block.BlockHeight, err) } return } // Sleep for `PollInterval` seconds - time.Sleep(vf.PollInterval * time.Second) + time.Sleep(s.PollInterval * time.Second) } } -func (vf *Verifier) queryIsBlockBabylonFinalized(block *BlockInfo) (bool, error) { +func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { + return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ - BlockHash: string(block.Hash), - BlockHeight: block.Height, - BlockTimestamp: block.Timestamp, + BlockHash: string(block.BlockHash), + BlockHeight: block.BlockHeight, + BlockTimestamp: block.BlockTimestamp, }) } -func (vf *Verifier) insertBlock(block *BlockInfo) error { +func (s *FinalityGadget) InsertBlock(block *types.Block) error { // Lock mutex - vf.Mutex.Lock() + s.Mutex.Lock() // Store block in DB - err := vf.Db.InsertBlock(&db.Block{ - BlockHeight: block.Height, - BlockHash: block.Hash, - BlockTimestamp: block.Timestamp, + err := s.Db.InsertBlock(&types.Block{ + BlockHeight: block.BlockHeight, + BlockHash: block.BlockHash, + BlockTimestamp: block.BlockTimestamp, }) if err != nil { return err } // Set last finalized block in memory - vf.currHeight = block.Height + s.currHeight = block.BlockHeight // Unlock mutex - vf.Mutex.Unlock() + s.Mutex.Unlock() return nil } -func (vf *Verifier) Close() { - vf.L2Client.Close() +func (s *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { + return s.Db.GetBlockStatusByHeight(height) +} + +func (s *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { + return s.Db.GetBlockStatusByHash(hash) +} + +func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { + return s.Db.GetLatestBlock() +} + +func (s *FinalityGadget) Close() { + s.L2Client.Close() } diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go new file mode 100644 index 0000000..233093c --- /dev/null +++ b/finalitygadget/interface.go @@ -0,0 +1,10 @@ +package finalitygadget + +import "github.com/babylonchain/babylon-finality-gadget/types" + +type IFinalityGadget interface { + InsertBlock(block *types.Block) error + GetBlockStatusByHeight(height uint64) (bool, error) + GetBlockStatusByHash(hash string) (bool, error) + GetLatestBlock() (*types.Block, error) +} diff --git a/go.mod b/go.mod index efe8a63..a2d3d43 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,15 @@ require ( github.com/cometbft/cometbft v0.38.6 github.com/cosmos/cosmos-sdk v0.50.6 github.com/ethereum/go-ethereum v1.13.15 - github.com/gorilla/mux v1.8.1 + github.com/lightningnetwork/lnd v0.16.4-beta.rc1 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 go.etcd.io/bbolt v1.3.10 go.uber.org/mock v0.4.0 go.uber.org/zap v1.26.0 + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.34.1 ) require ( @@ -73,6 +75,7 @@ require ( github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.2 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect @@ -129,6 +132,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect @@ -231,8 +235,6 @@ require ( google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 // indirect - google.golang.org/grpc v1.64.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 261baa6..f4a0812 100644 --- a/go.sum +++ b/go.sum @@ -382,6 +382,8 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= @@ -857,6 +859,8 @@ github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/lightningnetwork/lnd v0.16.4-beta.rc1 h1:L8ktsv1lM5esVtiOlEtOBqU1dCoDckbm0FkcketBskQ= +github.com/lightningnetwork/lnd v0.16.4-beta.rc1/go.mod h1:sK9F98TpFuO/fjLCX4jEjc65qr2GZGs8IquVde1N46I= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= @@ -1149,8 +1153,8 @@ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/vulpine-io/io-test v1.0.0 h1:Ot8vMh+ssm1VWDAwJ3U4C5qG9aRnr5YfQFZPNZBAUGI= diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go new file mode 100644 index 0000000..636256f --- /dev/null +++ b/proto/finalitygadget.pb.go @@ -0,0 +1,619 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v4.25.3 +// source: proto/finalitygadget.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PingRequest) Reset() { + *x = PingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingRequest) ProtoMessage() {} + +func (x *PingRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. +func (*PingRequest) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{0} +} + +type PingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PingResponse) Reset() { + *x = PingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingResponse) ProtoMessage() {} + +func (x *PingResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. +func (*PingResponse) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} +} + +type BlockInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // block_hash is the hash of the block + BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + // block_height is the height of the block + BlockHeight uint64 `protobuf:"varint,2,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // block_timestamp is the unix timestamp of the block + BlockTimestamp uint64 `protobuf:"varint,3,opt,name=block_timestamp,json=blockTimestamp,proto3" json:"block_timestamp,omitempty"` +} + +func (x *BlockInfo) Reset() { + *x = BlockInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlockInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlockInfo) ProtoMessage() {} + +func (x *BlockInfo) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlockInfo.ProtoReflect.Descriptor instead. +func (*BlockInfo) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} +} + +func (x *BlockInfo) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *BlockInfo) GetBlockHeight() uint64 { + if x != nil { + return x.BlockHeight + } + return 0 +} + +func (x *BlockInfo) GetBlockTimestamp() uint64 { + if x != nil { + return x.BlockTimestamp + } + return 0 +} + +type InsertBlockResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // success is true if the block is successfully inserted + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *InsertBlockResponse) Reset() { + *x = InsertBlockResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InsertBlockResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InsertBlockResponse) ProtoMessage() {} + +func (x *InsertBlockResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InsertBlockResponse.ProtoReflect.Descriptor instead. +func (*InsertBlockResponse) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} +} + +func (x *InsertBlockResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type GetBlockStatusByHeightRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // block_height is the height of the block + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` +} + +func (x *GetBlockStatusByHeightRequest) Reset() { + *x = GetBlockStatusByHeightRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockStatusByHeightRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockStatusByHeightRequest) ProtoMessage() {} + +func (x *GetBlockStatusByHeightRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBlockStatusByHeightRequest.ProtoReflect.Descriptor instead. +func (*GetBlockStatusByHeightRequest) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{4} +} + +func (x *GetBlockStatusByHeightRequest) GetBlockHeight() uint64 { + if x != nil { + return x.BlockHeight + } + return 0 +} + +type GetBlockStatusByHashRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // block_hash is the hash of the block + BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` +} + +func (x *GetBlockStatusByHashRequest) Reset() { + *x = GetBlockStatusByHashRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockStatusByHashRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockStatusByHashRequest) ProtoMessage() {} + +func (x *GetBlockStatusByHashRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBlockStatusByHashRequest.ProtoReflect.Descriptor instead. +func (*GetBlockStatusByHashRequest) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{5} +} + +func (x *GetBlockStatusByHashRequest) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +type GetBlockStatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // is_finalized is true if the block is finalized + IsFinalized bool `protobuf:"varint,1,opt,name=is_finalized,json=isFinalized,proto3" json:"is_finalized,omitempty"` +} + +func (x *GetBlockStatusResponse) Reset() { + *x = GetBlockStatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockStatusResponse) ProtoMessage() {} + +func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBlockStatusResponse.ProtoReflect.Descriptor instead. +func (*GetBlockStatusResponse) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{6} +} + +func (x *GetBlockStatusResponse) GetIsFinalized() bool { + if x != nil { + return x.IsFinalized + } + return false +} + +type GetLatestBlockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetLatestBlockRequest) Reset() { + *x = GetLatestBlockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_finalitygadget_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLatestBlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLatestBlockRequest) ProtoMessage() {} + +func (x *GetLatestBlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_finalitygadget_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLatestBlockRequest.ProtoReflect.Descriptor instead. +func (*GetLatestBlockRequest) Descriptor() ([]byte, []int) { + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{7} +} + +var File_proto_finalitygadget_proto protoreflect.FileDescriptor + +var file_proto_finalitygadget_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x76, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, + 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x2f, 0x0a, 0x13, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x42, 0x0a, 0x1d, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, + 0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, + 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, + 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x32, 0xfa, 0x02, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x12, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x24, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, + 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, + 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, + 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x62, 0x79, + 0x6c, 0x6f, 0x6e, 0x2d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, + 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_proto_finalitygadget_proto_rawDescOnce sync.Once + file_proto_finalitygadget_proto_rawDescData = file_proto_finalitygadget_proto_rawDesc +) + +func file_proto_finalitygadget_proto_rawDescGZIP() []byte { + file_proto_finalitygadget_proto_rawDescOnce.Do(func() { + file_proto_finalitygadget_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_finalitygadget_proto_rawDescData) + }) + return file_proto_finalitygadget_proto_rawDescData +} + +var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_proto_finalitygadget_proto_goTypes = []interface{}{ + (*PingRequest)(nil), // 0: proto.PingRequest + (*PingResponse)(nil), // 1: proto.PingResponse + (*BlockInfo)(nil), // 2: proto.BlockInfo + (*InsertBlockResponse)(nil), // 3: proto.InsertBlockResponse + (*GetBlockStatusByHeightRequest)(nil), // 4: proto.GetBlockStatusByHeightRequest + (*GetBlockStatusByHashRequest)(nil), // 5: proto.GetBlockStatusByHashRequest + (*GetBlockStatusResponse)(nil), // 6: proto.GetBlockStatusResponse + (*GetLatestBlockRequest)(nil), // 7: proto.GetLatestBlockRequest +} +var file_proto_finalitygadget_proto_depIdxs = []int32{ + 0, // 0: proto.FinalityGadget.Ping:input_type -> proto.PingRequest + 2, // 1: proto.FinalityGadget.InsertBlock:input_type -> proto.BlockInfo + 4, // 2: proto.FinalityGadget.GetBlockStatusByHeight:input_type -> proto.GetBlockStatusByHeightRequest + 5, // 3: proto.FinalityGadget.GetBlockStatusByHash:input_type -> proto.GetBlockStatusByHashRequest + 7, // 4: proto.FinalityGadget.GetLatestBlock:input_type -> proto.GetLatestBlockRequest + 1, // 5: proto.FinalityGadget.Ping:output_type -> proto.PingResponse + 3, // 6: proto.FinalityGadget.InsertBlock:output_type -> proto.InsertBlockResponse + 6, // 7: proto.FinalityGadget.GetBlockStatusByHeight:output_type -> proto.GetBlockStatusResponse + 6, // 8: proto.FinalityGadget.GetBlockStatusByHash:output_type -> proto.GetBlockStatusResponse + 2, // 9: proto.FinalityGadget.GetLatestBlock:output_type -> proto.BlockInfo + 5, // [5:10] is the sub-list for method output_type + 0, // [0:5] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_finalitygadget_proto_init() } +func file_proto_finalitygadget_proto_init() { + if File_proto_finalitygadget_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_finalitygadget_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlockInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InsertBlockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockStatusByHeightRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockStatusByHashRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_finalitygadget_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLatestBlockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_finalitygadget_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_finalitygadget_proto_goTypes, + DependencyIndexes: file_proto_finalitygadget_proto_depIdxs, + MessageInfos: file_proto_finalitygadget_proto_msgTypes, + }.Build() + File_proto_finalitygadget_proto = out.File + file_proto_finalitygadget_proto_rawDesc = nil + file_proto_finalitygadget_proto_goTypes = nil + file_proto_finalitygadget_proto_depIdxs = nil +} diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto new file mode 100644 index 0000000..7829190 --- /dev/null +++ b/proto/finalitygadget.proto @@ -0,0 +1,59 @@ +syntax = "proto3"; + +package proto; + +option go_package = "github.com/babylonchain/babylon-finality-gadget/proto"; + +service FinalityGadget { + rpc Ping(PingRequest) returns (PingResponse); + + // InsertBlock inserts a new block into the finality gadget db + rpc InsertBlock(BlockInfo) returns (InsertBlockResponse); + + // GetBlockStatusByHeight returns the finality status of a block at given + // height + rpc GetBlockStatusByHeight(GetBlockStatusByHeightRequest) + returns (GetBlockStatusResponse); + + // GetBlockStatusByHash returns the finality status of a block with given hash + rpc GetBlockStatusByHash(GetBlockStatusByHashRequest) + returns (GetBlockStatusResponse); + + // GetLatestBlock returns the latest consecutively finalized block + rpc GetLatestBlock(GetLatestBlockRequest) returns (BlockInfo); +} + +message PingRequest {} + +message PingResponse {} + +message BlockInfo { + // block_hash is the hash of the block + string block_hash = 1; + // block_height is the height of the block + uint64 block_height = 2; + // block_timestamp is the unix timestamp of the block + uint64 block_timestamp = 3; +} + +message InsertBlockResponse { + // success is true if the block is successfully inserted + bool success = 1; +} + +message GetBlockStatusByHeightRequest { + // block_height is the height of the block + uint64 block_height = 1; +} + +message GetBlockStatusByHashRequest { + // block_hash is the hash of the block + string block_hash = 1; +} + +message GetBlockStatusResponse { + // is_finalized is true if the block is finalized + bool is_finalized = 1; +} + +message GetLatestBlockRequest {} \ No newline at end of file diff --git a/proto/finalitygadget_grpc.pb.go b/proto/finalitygadget_grpc.pb.go new file mode 100644 index 0000000..7ecaf7a --- /dev/null +++ b/proto/finalitygadget_grpc.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.3 +// source: proto/finalitygadget.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + FinalityGadget_Ping_FullMethodName = "/proto.FinalityGadget/Ping" + FinalityGadget_InsertBlock_FullMethodName = "/proto.FinalityGadget/InsertBlock" + FinalityGadget_GetBlockStatusByHeight_FullMethodName = "/proto.FinalityGadget/GetBlockStatusByHeight" + FinalityGadget_GetBlockStatusByHash_FullMethodName = "/proto.FinalityGadget/GetBlockStatusByHash" + FinalityGadget_GetLatestBlock_FullMethodName = "/proto.FinalityGadget/GetLatestBlock" +) + +// FinalityGadgetClient is the client API for FinalityGadget service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type FinalityGadgetClient interface { + Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) + // InsertBlock inserts a new block into the finality gadget db + InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) + // GetBlockStatusByHeight returns the finality status of a block at given + // height + GetBlockStatusByHeight(ctx context.Context, in *GetBlockStatusByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) + // GetBlockStatusByHash returns the finality status of a block with given hash + GetBlockStatusByHash(ctx context.Context, in *GetBlockStatusByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) + // GetLatestBlock returns the latest consecutively finalized block + GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*BlockInfo, error) +} + +type finalityGadgetClient struct { + cc grpc.ClientConnInterface +} + +func NewFinalityGadgetClient(cc grpc.ClientConnInterface) FinalityGadgetClient { + return &finalityGadgetClient{cc} +} + +func (c *finalityGadgetClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { + out := new(PingResponse) + err := c.cc.Invoke(ctx, FinalityGadget_Ping_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *finalityGadgetClient) InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) { + out := new(InsertBlockResponse) + err := c.cc.Invoke(ctx, FinalityGadget_InsertBlock_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *finalityGadgetClient) GetBlockStatusByHeight(ctx context.Context, in *GetBlockStatusByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { + out := new(GetBlockStatusResponse) + err := c.cc.Invoke(ctx, FinalityGadget_GetBlockStatusByHeight_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *finalityGadgetClient) GetBlockStatusByHash(ctx context.Context, in *GetBlockStatusByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { + out := new(GetBlockStatusResponse) + err := c.cc.Invoke(ctx, FinalityGadget_GetBlockStatusByHash_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *finalityGadgetClient) GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*BlockInfo, error) { + out := new(BlockInfo) + err := c.cc.Invoke(ctx, FinalityGadget_GetLatestBlock_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// FinalityGadgetServer is the server API for FinalityGadget service. +// All implementations must embed UnimplementedFinalityGadgetServer +// for forward compatibility +type FinalityGadgetServer interface { + Ping(context.Context, *PingRequest) (*PingResponse, error) + // InsertBlock inserts a new block into the finality gadget db + InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) + // GetBlockStatusByHeight returns the finality status of a block at given + // height + GetBlockStatusByHeight(context.Context, *GetBlockStatusByHeightRequest) (*GetBlockStatusResponse, error) + // GetBlockStatusByHash returns the finality status of a block with given hash + GetBlockStatusByHash(context.Context, *GetBlockStatusByHashRequest) (*GetBlockStatusResponse, error) + // GetLatestBlock returns the latest consecutively finalized block + GetLatestBlock(context.Context, *GetLatestBlockRequest) (*BlockInfo, error) + mustEmbedUnimplementedFinalityGadgetServer() +} + +// UnimplementedFinalityGadgetServer must be embedded to have forward compatible implementations. +type UnimplementedFinalityGadgetServer struct { +} + +func (UnimplementedFinalityGadgetServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") +} +func (UnimplementedFinalityGadgetServer) InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertBlock not implemented") +} +func (UnimplementedFinalityGadgetServer) GetBlockStatusByHeight(context.Context, *GetBlockStatusByHeightRequest) (*GetBlockStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockStatusByHeight not implemented") +} +func (UnimplementedFinalityGadgetServer) GetBlockStatusByHash(context.Context, *GetBlockStatusByHashRequest) (*GetBlockStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockStatusByHash not implemented") +} +func (UnimplementedFinalityGadgetServer) GetLatestBlock(context.Context, *GetLatestBlockRequest) (*BlockInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLatestBlock not implemented") +} +func (UnimplementedFinalityGadgetServer) mustEmbedUnimplementedFinalityGadgetServer() {} + +// UnsafeFinalityGadgetServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to FinalityGadgetServer will +// result in compilation errors. +type UnsafeFinalityGadgetServer interface { + mustEmbedUnimplementedFinalityGadgetServer() +} + +func RegisterFinalityGadgetServer(s grpc.ServiceRegistrar, srv FinalityGadgetServer) { + s.RegisterService(&FinalityGadget_ServiceDesc, srv) +} + +func _FinalityGadget_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FinalityGadgetServer).Ping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FinalityGadget_Ping_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FinalityGadgetServer).Ping(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FinalityGadget_InsertBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BlockInfo) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FinalityGadgetServer).InsertBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FinalityGadget_InsertBlock_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FinalityGadgetServer).InsertBlock(ctx, req.(*BlockInfo)) + } + return interceptor(ctx, in, info, handler) +} + +func _FinalityGadget_GetBlockStatusByHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockStatusByHeightRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FinalityGadgetServer).GetBlockStatusByHeight(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FinalityGadget_GetBlockStatusByHeight_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FinalityGadgetServer).GetBlockStatusByHeight(ctx, req.(*GetBlockStatusByHeightRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FinalityGadget_GetBlockStatusByHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockStatusByHashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FinalityGadgetServer).GetBlockStatusByHash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FinalityGadget_GetBlockStatusByHash_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FinalityGadgetServer).GetBlockStatusByHash(ctx, req.(*GetBlockStatusByHashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FinalityGadget_GetLatestBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLatestBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FinalityGadgetServer).GetLatestBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FinalityGadget_GetLatestBlock_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FinalityGadgetServer).GetLatestBlock(ctx, req.(*GetLatestBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// FinalityGadget_ServiceDesc is the grpc.ServiceDesc for FinalityGadget service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var FinalityGadget_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.FinalityGadget", + HandlerType: (*FinalityGadgetServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Ping", + Handler: _FinalityGadget_Ping_Handler, + }, + { + MethodName: "InsertBlock", + Handler: _FinalityGadget_InsertBlock_Handler, + }, + { + MethodName: "GetBlockStatusByHeight", + Handler: _FinalityGadget_GetBlockStatusByHeight_Handler, + }, + { + MethodName: "GetBlockStatusByHash", + Handler: _FinalityGadget_GetBlockStatusByHash_Handler, + }, + { + MethodName: "GetLatestBlock", + Handler: _FinalityGadget_GetLatestBlock_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/finalitygadget.proto", +} diff --git a/server/handlers.go b/server/handlers.go deleted file mode 100644 index e8fe2a8..0000000 --- a/server/handlers.go +++ /dev/null @@ -1,93 +0,0 @@ -package server - -import ( - "encoding/json" - "fmt" - "net/http" - "strconv" -) - -type StatusResponse struct { - IsFinalized bool `json:"isFinalized"` -} - -func (s *Server) getBlockStatusByHeight(w http.ResponseWriter, r *http.Request) { - // Fetch params and run validation check - blockHeightStr := r.URL.Query().Get("blockHeight") - if blockHeightStr == "" { - w.WriteHeader(http.StatusBadRequest) - fmt.Fprint(w, "Missing required params: blockHeight\n") - return - } - - // Parse params - blockHeight, err := strconv.Atoi(blockHeightStr) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - fmt.Fprint(w, "Invalid blockHeight\n") - return - } - - // Fetch status from DB - isFinal := s.db.GetBlockStatusByHeight(uint64(blockHeight)) - - // Marshal and return status - jsonResponse, err := json.Marshal(StatusResponse{ - IsFinalized: isFinal, - }) - if err != nil { - http.Error(w, "unable to marshal JSON response", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - if _, err := w.Write(jsonResponse); err != nil { - http.Error(w, "unable to write JSON response", http.StatusInternalServerError) - } -} - -func (s *Server) getBlockStatusByHash(w http.ResponseWriter, r *http.Request) { - // Fetch params and run validation check - hash := r.URL.Query().Get("hash") - if hash == "" { - w.WriteHeader(http.StatusBadRequest) - fmt.Fprint(w, "Missing required params: hash\n") - return - } - - // Fetch status from DB - isFinal := s.db.GetBlockStatusByHash(hash) - - // Marshal and return status - jsonResponse, err := json.Marshal(StatusResponse{ - IsFinalized: isFinal, - }) - if err != nil { - http.Error(w, "unable to marshal JSON response", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - if _, err := w.Write(jsonResponse); err != nil { - http.Error(w, "unable to write JSON response", http.StatusInternalServerError) - } -} - -func (s *Server) getLatestBlock(w http.ResponseWriter, r *http.Request) { - // Fetch status from DB - block, err := s.db.GetLatestBlock() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Error getting latest block: %v\n", err) - return - } - - // Marshal and return status - jsonResponse, err := json.Marshal(block) - if err != nil { - http.Error(w, "unable to marshal JSON response", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - if _, err := w.Write(jsonResponse); err != nil { - http.Error(w, "unable to write JSON response", http.StatusInternalServerError) - } -} diff --git a/server/rpcserver.go b/server/rpcserver.go new file mode 100644 index 0000000..71fe1d8 --- /dev/null +++ b/server/rpcserver.go @@ -0,0 +1,92 @@ +package server + +import ( + "context" + + "google.golang.org/grpc" + + "github.com/babylonchain/babylon-finality-gadget/finalitygadget" + "github.com/babylonchain/babylon-finality-gadget/proto" + "github.com/babylonchain/babylon-finality-gadget/types" +) + +// rpcServer is the main RPC server for the finality gadget daemon that handles +// gRPC incoming requests. +type rpcServer struct { + proto.UnimplementedFinalityGadgetServer + + fg finalitygadget.IFinalityGadget +} + +// newRPCServer creates a new RPC sever from the set of input dependencies. +func newRPCServer( + fg finalitygadget.IFinalityGadget, +) *rpcServer { + return &rpcServer{ + fg: fg, + } +} + +// RegisterWithGrpcServer registers the rpcServer with the passed root gRPC +// server. +func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { + // Register the main RPC server. + proto.RegisterFinalityGadgetServer(grpcServer, r) + return nil +} + +func (r *rpcServer) Ping(ctx context.Context, req *proto.PingRequest) (*proto.PingResponse, error) { + return &proto.PingResponse{}, nil +} + +// InsertBlock is an RPC method that inserts a block into the database. +func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { + err := r.fg.InsertBlock(&types.Block{ + BlockHash: req.BlockHash, + BlockHeight: req.BlockHeight, + BlockTimestamp: req.BlockTimestamp, + }) + + if err != nil { + return &proto.InsertBlockResponse{Success: false}, err + } + + return &proto.InsertBlockResponse{Success: true}, nil +} + +// GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. +func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBlockStatusByHeightRequest) (*proto.GetBlockStatusResponse, error) { + isFinalized, err := r.fg.GetBlockStatusByHeight(req.BlockHeight) + + if err != nil { + return nil, err + } + + return &proto.GetBlockStatusResponse{IsFinalized: isFinalized}, nil +} + +// GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. +func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBlockStatusByHashRequest) (*proto.GetBlockStatusResponse, error) { + isFinalized, err := r.fg.GetBlockStatusByHash(req.BlockHash) + + if err != nil { + return nil, err + } + + return &proto.GetBlockStatusResponse{IsFinalized: isFinalized}, nil +} + +// GetLatestBlock is an RPC method that returns the latest consecutively finalized block. +func (r *rpcServer) GetLatestBlock(ctx context.Context, req *proto.GetLatestBlockRequest) (*proto.BlockInfo, error) { + block, err := r.fg.GetLatestBlock() + + if err != nil { + return nil, err + } + + return &proto.BlockInfo{ + BlockHash: block.BlockHash, + BlockHeight: block.BlockHeight, + BlockTimestamp: block.BlockTimestamp, + }, nil +} diff --git a/server/server.go b/server/server.go index c995029..3d2e55d 100644 --- a/server/server.go +++ b/server/server.go @@ -1,54 +1,111 @@ package server import ( + "fmt" "log" - "net/http" - - "github.com/gorilla/mux" + "net" + "sync" + "sync/atomic" "github.com/babylonchain/babylon-finality-gadget/db" + "github.com/babylonchain/babylon-finality-gadget/finalitygadget" + "github.com/babylonchain/babylon-finality-gadget/finalitygadget/config" + "github.com/lightningnetwork/lnd/signal" + + "google.golang.org/grpc" ) +// Server is the main daemon construct for the EOTS manager server. It handles +// spinning up the RPC sever, the database, and any other components that the +// EOTS manager server needs to function. type Server struct { - server *http.Server - db *db.BBoltHandler + started int32 + + rpcServer *rpcServer + cfg *config.Config + db *db.BBoltHandler + interceptor signal.Interceptor + + quit chan struct{} } -type ServerConfig struct { - Db *db.BBoltHandler - Port string +// NewEOTSManagerServer creates a new server with the given config. +func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { + return &Server{ + cfg: cfg, + rpcServer: newRPCServer(fg), + db: db, + interceptor: sig, + quit: make(chan struct{}, 1), + } } -func Start(cfg *ServerConfig) (*Server, error) { - // Create router. - router := mux.NewRouter().StrictSlash(true) - - // Define server. - s := &Server{ - server: &http.Server{ - Addr: ":" + cfg.Port, - Handler: router, - }, - db: cfg.Db, +// RunUntilShutdown runs the main finality gadget server loop until a signal is +// received to shut down the process. +func (s *Server) RunUntilShutdown() error { + if atomic.AddInt32(&s.started, 1) != 1 { + return nil } - // Define routes. - router.HandleFunc("/getBlockStatusByHeight", s.getBlockStatusByHeight) - router.HandleFunc("/getBlockStatusByHash", s.getBlockStatusByHash) - router.HandleFunc("/getLatest", s.getLatestBlock) - - // Start server in a goroutine. - go func() { - log.Printf("Starting server on port %s...", cfg.Port) - if err := http.ListenAndServe(":"+cfg.Port, router); err != nil { - log.Fatalf("Could not start server: %s\n", err.Error()) - } + defer func() { + log.Printf("Closing database...") + s.db.Close() + log.Printf("Database closed") }() - return s, nil + listenAddr := "localhost:" + s.cfg.GRPCServerPort + // we create listeners from the RPCListeners defined + // in the config. + lis, err := net.Listen("tcp", listenAddr) + if err != nil { + return fmt.Errorf("failed to listen on %s: %w", listenAddr, err) + } + defer lis.Close() + + grpcServer := grpc.NewServer() + defer grpcServer.Stop() + + if err := s.rpcServer.RegisterWithGrpcServer(grpcServer); err != nil { + return fmt.Errorf("failed to register gRPC server: %w", err) + } + + // All the necessary components have been registered, so we can + // actually start listening for requests. + if err := s.startGrpcListen(grpcServer, []net.Listener{lis}); err != nil { + return fmt.Errorf("failed to start gRPC listener: %v", err) + } + + log.Printf("Finality gadget is active") + + // Wait for shutdown signal from either a graceful server stop or from + // the interrupt handler. + <-s.interceptor.ShutdownChannel() + + return nil } -func (s *Server) Stop() error { - log.Println("Stopping server...") - return s.server.Close() +// startGrpcListen starts the GRPC server on the passed listeners. +func (s *Server) startGrpcListen(grpcServer *grpc.Server, listeners []net.Listener) error { + + // Use a WaitGroup so we can be sure the instructions on how to input the + // password is the last thing to be printed to the console. + var wg sync.WaitGroup + + for _, lis := range listeners { + wg.Add(1) + go func(lis net.Listener) { + log.Printf("RPC server listening: %s", lis.Addr().String()) + + // Close the ready chan to indicate we are listening. + defer lis.Close() + + wg.Done() + _ = grpcServer.Serve(lis) + }(lis) + } + + // Wait for gRPC servers to be up running. + wg.Wait() + + return nil } diff --git a/db/models.go b/types/block.go similarity index 94% rename from db/models.go rename to types/block.go index a0980c6..23a0827 100644 --- a/db/models.go +++ b/types/block.go @@ -1,4 +1,4 @@ -package db +package types type Block struct { BlockHash string `json:"block_hash" description:"block hash"` From cc19f28c6127e31569a6642cb40b0c534b26eaa4 Mon Sep 17 00:00:00 2001 From: parketh Date: Wed, 31 Jul 2024 19:36:02 +0800 Subject: [PATCH 47/93] feat: refactor http -> grpc and rename verifier -> server --- cmd/start.go | 3 ++- finalitygadget/finalitygadget.go | 1 - server/server.go | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cmd/start.go b/cmd/start.go index 547075e..b4f55e5 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -72,7 +72,8 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { } srv := server.NewFinalityGadgetServer(cfg, db, fg, shutdownInterceptor) go func() { - if err := srv.RunUntilShutdown(); err != nil { + err = srv.RunUntilShutdown() + if err != nil { log.Fatalf("Finality gadget server error: %v\n", err) } }() diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 0b66ef7..1f29f3c 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -182,7 +182,6 @@ func (s *FinalityGadget) handleBlock(block *types.Block) { } func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.BlockHash), BlockHeight: block.BlockHeight, diff --git a/server/server.go b/server/server.go index 3d2e55d..c8ae6a9 100644 --- a/server/server.go +++ b/server/server.go @@ -19,14 +19,13 @@ import ( // spinning up the RPC sever, the database, and any other components that the // EOTS manager server needs to function. type Server struct { - started int32 + rpcServer *rpcServer + cfg *config.Config + db *db.BBoltHandler - rpcServer *rpcServer - cfg *config.Config - db *db.BBoltHandler + quit chan struct{} interceptor signal.Interceptor - - quit chan struct{} + started int32 } // NewEOTSManagerServer creates a new server with the given config. From 018e67e71f1181d39a322d20345242e9af1f2fee Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 1 Aug 2024 21:46:15 +0800 Subject: [PATCH 48/93] fix: deps --- client/rpcclient.go | 6 +++--- cmd/start.go | 10 +++++----- db/bbolt.go | 2 +- finalitygadget/README.md | 2 +- finalitygadget/finalitygadget.go | 14 +++++++------- finalitygadget/interface.go | 2 +- proto/finalitygadget.proto | 2 +- server/rpcserver.go | 6 +++--- server/server.go | 6 +++--- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 959be37..e12ed26 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - "github.com/babylonchain/babylon-finality-gadget/db" - "github.com/babylonchain/babylon-finality-gadget/proto" - "github.com/babylonchain/babylon-finality-gadget/types" + "github.com/babylonlabs-io/babylon-finality-gadget/db" + "github.com/babylonlabs-io/babylon-finality-gadget/proto" + "github.com/babylonlabs-io/babylon-finality-gadget/types" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) diff --git a/cmd/start.go b/cmd/start.go index b4f55e5..d6faca2 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -10,11 +10,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - rpcclient "github.com/babylonchain/babylon-finality-gadget/client" - "github.com/babylonchain/babylon-finality-gadget/db" - "github.com/babylonchain/babylon-finality-gadget/finalitygadget" - "github.com/babylonchain/babylon-finality-gadget/finalitygadget/config" - "github.com/babylonchain/babylon-finality-gadget/server" + rpcclient "github.com/babylonlabs-io/babylon-finality-gadget/client" + "github.com/babylonlabs-io/babylon-finality-gadget/db" + "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget" + "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/babylon-finality-gadget/server" sig "github.com/lightningnetwork/lnd/signal" ) diff --git a/db/bbolt.go b/db/bbolt.go index 906cc77..4f8e2d8 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -8,7 +8,7 @@ import ( "log" "time" - "github.com/babylonchain/babylon-finality-gadget/types" + "github.com/babylonlabs-io/babylon-finality-gadget/types" bolt "go.etcd.io/bbolt" ) diff --git a/finalitygadget/README.md b/finalitygadget/README.md index 1f39e77..d309dbc 100644 --- a/finalitygadget/README.md +++ b/finalitygadget/README.md @@ -7,7 +7,7 @@ This is a peripheral program that can be run by users of OP stack L2s to track c To get started, clone the repository. ```bash -git clone https://github.com/babylonchain/babylon-finality-gadget.git +git clone https://github.com/babylonlabs-io/babylon-finality-gadget.git ``` Configure the `config.toml` file with the following content: diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 1f29f3c..a9fa0bc 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -9,13 +9,13 @@ import ( "sync" "time" - "github.com/babylonchain/babylon-finality-gadget/db" - "github.com/babylonchain/babylon-finality-gadget/finalitygadget/config" - "github.com/babylonchain/babylon-finality-gadget/sdk/btcclient" - "github.com/babylonchain/babylon-finality-gadget/sdk/client" - sdkconfig "github.com/babylonchain/babylon-finality-gadget/sdk/config" - "github.com/babylonchain/babylon-finality-gadget/sdk/cwclient" - "github.com/babylonchain/babylon-finality-gadget/types" + "github.com/babylonlabs-io/babylon-finality-gadget/db" + "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/babylon-finality-gadget/sdk/btcclient" + "github.com/babylonlabs-io/babylon-finality-gadget/sdk/client" + sdkconfig "github.com/babylonlabs-io/babylon-finality-gadget/sdk/config" + "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/babylon-finality-gadget/types" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" ) diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go index 233093c..2c87d34 100644 --- a/finalitygadget/interface.go +++ b/finalitygadget/interface.go @@ -1,6 +1,6 @@ package finalitygadget -import "github.com/babylonchain/babylon-finality-gadget/types" +import "github.com/babylonlabs-io/babylon-finality-gadget/types" type IFinalityGadget interface { InsertBlock(block *types.Block) error diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index 7829190..6ae3d8c 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package proto; -option go_package = "github.com/babylonchain/babylon-finality-gadget/proto"; +option go_package = "github.com/babylonlabs-io/babylon-finality-gadget/proto"; service FinalityGadget { rpc Ping(PingRequest) returns (PingResponse); diff --git a/server/rpcserver.go b/server/rpcserver.go index 71fe1d8..88c53b2 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -5,9 +5,9 @@ import ( "google.golang.org/grpc" - "github.com/babylonchain/babylon-finality-gadget/finalitygadget" - "github.com/babylonchain/babylon-finality-gadget/proto" - "github.com/babylonchain/babylon-finality-gadget/types" + "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget" + "github.com/babylonlabs-io/babylon-finality-gadget/proto" + "github.com/babylonlabs-io/babylon-finality-gadget/types" ) // rpcServer is the main RPC server for the finality gadget daemon that handles diff --git a/server/server.go b/server/server.go index c8ae6a9..9687684 100644 --- a/server/server.go +++ b/server/server.go @@ -7,9 +7,9 @@ import ( "sync" "sync/atomic" - "github.com/babylonchain/babylon-finality-gadget/db" - "github.com/babylonchain/babylon-finality-gadget/finalitygadget" - "github.com/babylonchain/babylon-finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/babylon-finality-gadget/db" + "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget" + "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget/config" "github.com/lightningnetwork/lnd/signal" "google.golang.org/grpc" From 036cb072d0afac98a3c30c3c621c27202143fb5b Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 1 Aug 2024 23:16:37 +0800 Subject: [PATCH 49/93] fix: remove grpc server ping to fix name conflict --- client/rpcclient.go | 15 -- proto/finalitygadget.pb.go | 251 +++++++++----------------------- proto/finalitygadget.proto | 6 - proto/finalitygadget_grpc.pb.go | 37 ----- server/rpcserver.go | 4 - 5 files changed, 71 insertions(+), 242 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index e12ed26..812d123 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -32,24 +32,9 @@ func NewFinalityGadgetGrpcClient( db: db, } - if err := gClient.Ping(); err != nil { - return nil, fmt.Errorf("the finality gadget server is not responding: %w", err) - } - return gClient, nil } -func (c *FinalityGadgetGrpcClient) Ping() error { - req := &proto.PingRequest{} - - _, err := c.client.Ping(context.Background(), req) - if err != nil { - return err - } - - return nil -} - func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { req := &proto.BlockInfo{ BlockHash: block.BlockHash, diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go index 636256f..21bedbb 100644 --- a/proto/finalitygadget.pb.go +++ b/proto/finalitygadget.pb.go @@ -20,82 +20,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type PingRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *PingRequest) Reset() { - *x = PingRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PingRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingRequest) ProtoMessage() {} - -func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. -func (*PingRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{0} -} - -type PingResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *PingResponse) Reset() { - *x = PingResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PingResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingResponse) ProtoMessage() {} - -func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. -func (*PingResponse) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} -} - type BlockInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -112,7 +36,7 @@ type BlockInfo struct { func (x *BlockInfo) Reset() { *x = BlockInfo{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[2] + mi := &file_proto_finalitygadget_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -125,7 +49,7 @@ func (x *BlockInfo) String() string { func (*BlockInfo) ProtoMessage() {} func (x *BlockInfo) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[2] + mi := &file_proto_finalitygadget_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -138,7 +62,7 @@ func (x *BlockInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockInfo.ProtoReflect.Descriptor instead. func (*BlockInfo) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{0} } func (x *BlockInfo) GetBlockHash() string { @@ -174,7 +98,7 @@ type InsertBlockResponse struct { func (x *InsertBlockResponse) Reset() { *x = InsertBlockResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[3] + mi := &file_proto_finalitygadget_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -187,7 +111,7 @@ func (x *InsertBlockResponse) String() string { func (*InsertBlockResponse) ProtoMessage() {} func (x *InsertBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[3] + mi := &file_proto_finalitygadget_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -200,7 +124,7 @@ func (x *InsertBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InsertBlockResponse.ProtoReflect.Descriptor instead. func (*InsertBlockResponse) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} } func (x *InsertBlockResponse) GetSuccess() bool { @@ -222,7 +146,7 @@ type GetBlockStatusByHeightRequest struct { func (x *GetBlockStatusByHeightRequest) Reset() { *x = GetBlockStatusByHeightRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[4] + mi := &file_proto_finalitygadget_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -235,7 +159,7 @@ func (x *GetBlockStatusByHeightRequest) String() string { func (*GetBlockStatusByHeightRequest) ProtoMessage() {} func (x *GetBlockStatusByHeightRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[4] + mi := &file_proto_finalitygadget_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -248,7 +172,7 @@ func (x *GetBlockStatusByHeightRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockStatusByHeightRequest.ProtoReflect.Descriptor instead. func (*GetBlockStatusByHeightRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{4} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} } func (x *GetBlockStatusByHeightRequest) GetBlockHeight() uint64 { @@ -270,7 +194,7 @@ type GetBlockStatusByHashRequest struct { func (x *GetBlockStatusByHashRequest) Reset() { *x = GetBlockStatusByHashRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[5] + mi := &file_proto_finalitygadget_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -283,7 +207,7 @@ func (x *GetBlockStatusByHashRequest) String() string { func (*GetBlockStatusByHashRequest) ProtoMessage() {} func (x *GetBlockStatusByHashRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[5] + mi := &file_proto_finalitygadget_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -296,7 +220,7 @@ func (x *GetBlockStatusByHashRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockStatusByHashRequest.ProtoReflect.Descriptor instead. func (*GetBlockStatusByHashRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{5} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} } func (x *GetBlockStatusByHashRequest) GetBlockHash() string { @@ -318,7 +242,7 @@ type GetBlockStatusResponse struct { func (x *GetBlockStatusResponse) Reset() { *x = GetBlockStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[6] + mi := &file_proto_finalitygadget_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -331,7 +255,7 @@ func (x *GetBlockStatusResponse) String() string { func (*GetBlockStatusResponse) ProtoMessage() {} func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[6] + mi := &file_proto_finalitygadget_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -344,7 +268,7 @@ func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockStatusResponse.ProtoReflect.Descriptor instead. func (*GetBlockStatusResponse) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{6} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{4} } func (x *GetBlockStatusResponse) GetIsFinalized() bool { @@ -363,7 +287,7 @@ type GetLatestBlockRequest struct { func (x *GetLatestBlockRequest) Reset() { *x = GetLatestBlockRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[7] + mi := &file_proto_finalitygadget_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -376,7 +300,7 @@ func (x *GetLatestBlockRequest) String() string { func (*GetLatestBlockRequest) ProtoMessage() {} func (x *GetLatestBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[7] + mi := &file_proto_finalitygadget_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -389,7 +313,7 @@ func (x *GetLatestBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLatestBlockRequest.ProtoReflect.Descriptor instead. func (*GetLatestBlockRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{7} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{5} } var File_proto_finalitygadget_proto protoreflect.FileDescriptor @@ -397,37 +321,32 @@ var File_proto_finalitygadget_proto protoreflect.FileDescriptor var file_proto_finalitygadget_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x76, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x6f, 0x74, 0x6f, 0x22, 0x76, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x2f, 0x0a, 0x13, 0x49, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x42, 0x0a, 0x1d, + 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, + 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x22, 0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, - 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x2f, 0x0a, 0x13, 0x49, 0x6e, - 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x42, 0x0a, 0x1d, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, - 0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, - 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, - 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, - 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x32, 0xfa, 0x02, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x12, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, + 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x69, 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, + 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x32, 0xc9, 0x02, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, @@ -447,11 +366,11 @@ var file_proto_finalitygadget_proto_rawDesc = []byte{ 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, - 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, - 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x62, 0x79, - 0x6c, 0x6f, 0x6e, 0x2d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, - 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x62, 0x61, + 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x2d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, + 0x61, 0x64, 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -466,30 +385,26 @@ func file_proto_finalitygadget_proto_rawDescGZIP() []byte { return file_proto_finalitygadget_proto_rawDescData } -var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_proto_finalitygadget_proto_goTypes = []interface{}{ - (*PingRequest)(nil), // 0: proto.PingRequest - (*PingResponse)(nil), // 1: proto.PingResponse - (*BlockInfo)(nil), // 2: proto.BlockInfo - (*InsertBlockResponse)(nil), // 3: proto.InsertBlockResponse - (*GetBlockStatusByHeightRequest)(nil), // 4: proto.GetBlockStatusByHeightRequest - (*GetBlockStatusByHashRequest)(nil), // 5: proto.GetBlockStatusByHashRequest - (*GetBlockStatusResponse)(nil), // 6: proto.GetBlockStatusResponse - (*GetLatestBlockRequest)(nil), // 7: proto.GetLatestBlockRequest + (*BlockInfo)(nil), // 0: proto.BlockInfo + (*InsertBlockResponse)(nil), // 1: proto.InsertBlockResponse + (*GetBlockStatusByHeightRequest)(nil), // 2: proto.GetBlockStatusByHeightRequest + (*GetBlockStatusByHashRequest)(nil), // 3: proto.GetBlockStatusByHashRequest + (*GetBlockStatusResponse)(nil), // 4: proto.GetBlockStatusResponse + (*GetLatestBlockRequest)(nil), // 5: proto.GetLatestBlockRequest } var file_proto_finalitygadget_proto_depIdxs = []int32{ - 0, // 0: proto.FinalityGadget.Ping:input_type -> proto.PingRequest - 2, // 1: proto.FinalityGadget.InsertBlock:input_type -> proto.BlockInfo - 4, // 2: proto.FinalityGadget.GetBlockStatusByHeight:input_type -> proto.GetBlockStatusByHeightRequest - 5, // 3: proto.FinalityGadget.GetBlockStatusByHash:input_type -> proto.GetBlockStatusByHashRequest - 7, // 4: proto.FinalityGadget.GetLatestBlock:input_type -> proto.GetLatestBlockRequest - 1, // 5: proto.FinalityGadget.Ping:output_type -> proto.PingResponse - 3, // 6: proto.FinalityGadget.InsertBlock:output_type -> proto.InsertBlockResponse - 6, // 7: proto.FinalityGadget.GetBlockStatusByHeight:output_type -> proto.GetBlockStatusResponse - 6, // 8: proto.FinalityGadget.GetBlockStatusByHash:output_type -> proto.GetBlockStatusResponse - 2, // 9: proto.FinalityGadget.GetLatestBlock:output_type -> proto.BlockInfo - 5, // [5:10] is the sub-list for method output_type - 0, // [0:5] is the sub-list for method input_type + 0, // 0: proto.FinalityGadget.InsertBlock:input_type -> proto.BlockInfo + 2, // 1: proto.FinalityGadget.GetBlockStatusByHeight:input_type -> proto.GetBlockStatusByHeightRequest + 3, // 2: proto.FinalityGadget.GetBlockStatusByHash:input_type -> proto.GetBlockStatusByHashRequest + 5, // 3: proto.FinalityGadget.GetLatestBlock:input_type -> proto.GetLatestBlockRequest + 1, // 4: proto.FinalityGadget.InsertBlock:output_type -> proto.InsertBlockResponse + 4, // 5: proto.FinalityGadget.GetBlockStatusByHeight:output_type -> proto.GetBlockStatusResponse + 4, // 6: proto.FinalityGadget.GetBlockStatusByHash:output_type -> proto.GetBlockStatusResponse + 0, // 7: proto.FinalityGadget.GetLatestBlock:output_type -> proto.BlockInfo + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -502,30 +417,6 @@ func file_proto_finalitygadget_proto_init() { } if !protoimpl.UnsafeEnabled { file_proto_finalitygadget_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PingRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_finalitygadget_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PingResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlockInfo); i { case 0: return &v.state @@ -537,7 +428,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InsertBlockResponse); i { case 0: return &v.state @@ -549,7 +440,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockStatusByHeightRequest); i { case 0: return &v.state @@ -561,7 +452,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockStatusByHashRequest); i { case 0: return &v.state @@ -573,7 +464,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockStatusResponse); i { case 0: return &v.state @@ -585,7 +476,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetLatestBlockRequest); i { case 0: return &v.state @@ -604,7 +495,7 @@ func file_proto_finalitygadget_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_finalitygadget_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index 6ae3d8c..381060a 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -5,8 +5,6 @@ package proto; option go_package = "github.com/babylonlabs-io/babylon-finality-gadget/proto"; service FinalityGadget { - rpc Ping(PingRequest) returns (PingResponse); - // InsertBlock inserts a new block into the finality gadget db rpc InsertBlock(BlockInfo) returns (InsertBlockResponse); @@ -23,10 +21,6 @@ service FinalityGadget { rpc GetLatestBlock(GetLatestBlockRequest) returns (BlockInfo); } -message PingRequest {} - -message PingResponse {} - message BlockInfo { // block_hash is the hash of the block string block_hash = 1; diff --git a/proto/finalitygadget_grpc.pb.go b/proto/finalitygadget_grpc.pb.go index 7ecaf7a..5180f93 100644 --- a/proto/finalitygadget_grpc.pb.go +++ b/proto/finalitygadget_grpc.pb.go @@ -19,7 +19,6 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - FinalityGadget_Ping_FullMethodName = "/proto.FinalityGadget/Ping" FinalityGadget_InsertBlock_FullMethodName = "/proto.FinalityGadget/InsertBlock" FinalityGadget_GetBlockStatusByHeight_FullMethodName = "/proto.FinalityGadget/GetBlockStatusByHeight" FinalityGadget_GetBlockStatusByHash_FullMethodName = "/proto.FinalityGadget/GetBlockStatusByHash" @@ -30,7 +29,6 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type FinalityGadgetClient interface { - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) // InsertBlock inserts a new block into the finality gadget db InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) // GetBlockStatusByHeight returns the finality status of a block at given @@ -50,15 +48,6 @@ func NewFinalityGadgetClient(cc grpc.ClientConnInterface) FinalityGadgetClient { return &finalityGadgetClient{cc} } -func (c *finalityGadgetClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, FinalityGadget_Ping_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *finalityGadgetClient) InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) { out := new(InsertBlockResponse) err := c.cc.Invoke(ctx, FinalityGadget_InsertBlock_FullMethodName, in, out, opts...) @@ -99,7 +88,6 @@ func (c *finalityGadgetClient) GetLatestBlock(ctx context.Context, in *GetLatest // All implementations must embed UnimplementedFinalityGadgetServer // for forward compatibility type FinalityGadgetServer interface { - Ping(context.Context, *PingRequest) (*PingResponse, error) // InsertBlock inserts a new block into the finality gadget db InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) // GetBlockStatusByHeight returns the finality status of a block at given @@ -116,9 +104,6 @@ type FinalityGadgetServer interface { type UnimplementedFinalityGadgetServer struct { } -func (UnimplementedFinalityGadgetServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} func (UnimplementedFinalityGadgetServer) InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method InsertBlock not implemented") } @@ -144,24 +129,6 @@ func RegisterFinalityGadgetServer(s grpc.ServiceRegistrar, srv FinalityGadgetSer s.RegisterService(&FinalityGadget_ServiceDesc, srv) } -func _FinalityGadget_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(FinalityGadgetServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: FinalityGadget_Ping_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FinalityGadgetServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _FinalityGadget_InsertBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BlockInfo) if err := dec(in); err != nil { @@ -241,10 +208,6 @@ var FinalityGadget_ServiceDesc = grpc.ServiceDesc{ ServiceName: "proto.FinalityGadget", HandlerType: (*FinalityGadgetServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "Ping", - Handler: _FinalityGadget_Ping_Handler, - }, { MethodName: "InsertBlock", Handler: _FinalityGadget_InsertBlock_Handler, diff --git a/server/rpcserver.go b/server/rpcserver.go index 88c53b2..3fd97ad 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -35,10 +35,6 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { return nil } -func (r *rpcServer) Ping(ctx context.Context, req *proto.PingRequest) (*proto.PingResponse, error) { - return &proto.PingResponse{}, nil -} - // InsertBlock is an RPC method that inserts a block into the database. func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { err := r.fg.InsertBlock(&types.Block{ From 370fce1a50639180a7139d2cadd2c02776139c9e Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 10:52:42 +0100 Subject: [PATCH 50/93] debug: add logging --- client/rpcclient.go | 7 +++++++ db/bbolt.go | 8 ++++++++ finalitygadget/finalitygadget.go | 11 +++++++++++ server/rpcserver.go | 7 +++++++ server/server.go | 4 +++- 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 812d123..95bc55e 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -3,6 +3,7 @@ package client import ( "context" "fmt" + "log" "github.com/babylonlabs-io/babylon-finality-gadget/db" "github.com/babylonlabs-io/babylon-finality-gadget/proto" @@ -21,6 +22,7 @@ func NewFinalityGadgetGrpcClient( db *db.BBoltHandler, remoteAddr string, ) (*FinalityGadgetGrpcClient, error) { + log.Println("[rpcclient] NewFinalityGadgetGrpcClient()") conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, fmt.Errorf("failed to build gRPC connection to %s: %w", remoteAddr, err) @@ -36,6 +38,7 @@ func NewFinalityGadgetGrpcClient( } func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { + log.Println("[rpcclient] InsertBlock()") req := &proto.BlockInfo{ BlockHash: block.BlockHash, BlockHeight: block.BlockHeight, @@ -51,6 +54,7 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { + log.Println("[rpcclient] GetBlockStatusByHeight()") req := &proto.GetBlockStatusByHeightRequest{ BlockHeight: height, } @@ -64,6 +68,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, error) { + log.Println("[rpcclient] GetBlockStatusByHash()") req := &proto.GetBlockStatusByHashRequest{ BlockHash: hash, } @@ -77,6 +82,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, erro } func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { + log.Println("[rpcclient] GetLatestBlock()") req := &proto.GetLatestBlockRequest{} res, err := c.client.GetLatestBlock(context.Background(), req) @@ -92,5 +98,6 @@ func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { } func (c *FinalityGadgetGrpcClient) Close() error { + log.Println("[rpcclient] Close()") return c.conn.Close() } diff --git a/db/bbolt.go b/db/bbolt.go index 4f8e2d8..6996ef1 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -28,6 +28,7 @@ var ( ) func NewBBoltHandler(path string) (*BBoltHandler, error) { + log.Println("[bbolt] NewBBoltHandler()") // 0600 = read/write permission for owner only db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second}) if err != nil { @@ -41,6 +42,7 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { } func (bb *BBoltHandler) TryCreateInitialBuckets() error { + log.Println("[bbolt] TryCreateInitialBuckets()") log.Printf("Initialising DB...") return bb.db.Update(func(tx *bolt.Tx) error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} @@ -63,6 +65,7 @@ func tryCreateBucket(tx *bolt.Tx, bucketName string) error { } func (bb *BBoltHandler) InsertBlock(block *types.Block) error { + log.Println("[bbolt] InsertBlock()") log.Printf("Inserting block %d to DB...\n", block.BlockHeight) // Store mapping number -> block @@ -118,6 +121,7 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { } func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { + log.Println("[bbolt] GetBlockByHeight()") var block types.Block err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blocksBucket)) @@ -135,6 +139,7 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { } func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { + log.Println("[bbolt] GetBlockStatusByHeight()") _, err := bb.GetBlockByHeight(height) if err != nil { if errors.Is(err, ErrBlockNotFound) { @@ -146,6 +151,7 @@ func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { } func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { + log.Println("[bbolt] GetBlockStatusByHash()") // Fetch block number by hash var blockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { @@ -162,6 +168,7 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { } func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { + log.Println("[bbolt] GetLatestBlock()") var latestBlockHeight uint64 // Fetch latest block height @@ -192,6 +199,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { } func (bb *BBoltHandler) Close() error { + log.Println("[bbolt] Close()") return bb.db.Close() } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index a9fa0bc..882f384 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -65,6 +65,7 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget // This function process blocks indefinitely, starting from the last finalized block. func (s *FinalityGadget) ProcessBlocks() error { + log.Println("[finalitygadget] ProcessBlocks()") // Start service at last finalized block err := s.startService() if err != nil { @@ -89,6 +90,7 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block func (s *FinalityGadget) startService() error { + log.Println("[finalitygadget] startService()") // Query L2 node for last finalized block block, err := s.getLatestFinalizedBlock() if err != nil { @@ -142,6 +144,7 @@ func (s *FinalityGadget) startService() error { // Get last btc finalized block func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { + log.Println("[finalitygadget] getLatestFinalizedBlock()") return s.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } @@ -159,6 +162,7 @@ func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, erro } func (s *FinalityGadget) handleBlock(block *types.Block) { + log.Println("[finalitygadget] handleBlock()") // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { @@ -182,6 +186,8 @@ func (s *FinalityGadget) handleBlock(block *types.Block) { } func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { + log.Println("[finalitygadget] queryIsBlockBabylonFinalized()") + return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.BlockHash), BlockHeight: block.BlockHeight, @@ -190,6 +196,7 @@ func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool } func (s *FinalityGadget) InsertBlock(block *types.Block) error { + log.Println("[finalitygadget] InsertBlock()") // Lock mutex s.Mutex.Lock() // Store block in DB @@ -210,17 +217,21 @@ func (s *FinalityGadget) InsertBlock(block *types.Block) error { } func (s *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { + log.Println("[finalitygadget] GetBlockStatusByHeight()") return s.Db.GetBlockStatusByHeight(height) } func (s *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { + log.Println("[finalitygadget] GetBlockStatusByHash()") return s.Db.GetBlockStatusByHash(hash) } func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { + log.Println("[finalitygadget] GetLatestBlock()") return s.Db.GetLatestBlock() } func (s *FinalityGadget) Close() { + log.Println("[finalitygadget] Close()") s.L2Client.Close() } diff --git a/server/rpcserver.go b/server/rpcserver.go index 3fd97ad..7000db1 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -2,6 +2,7 @@ package server import ( "context" + "log" "google.golang.org/grpc" @@ -22,6 +23,7 @@ type rpcServer struct { func newRPCServer( fg finalitygadget.IFinalityGadget, ) *rpcServer { + log.Println("[rpcserver] newRPCServer()") return &rpcServer{ fg: fg, } @@ -30,6 +32,7 @@ func newRPCServer( // RegisterWithGrpcServer registers the rpcServer with the passed root gRPC // server. func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { + log.Println("[rpcserver] RegisterWithGrpcServer()") // Register the main RPC server. proto.RegisterFinalityGadgetServer(grpcServer, r) return nil @@ -37,6 +40,7 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { // InsertBlock is an RPC method that inserts a block into the database. func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { + log.Println("[rpcserver] InsertBlock()") err := r.fg.InsertBlock(&types.Block{ BlockHash: req.BlockHash, BlockHeight: req.BlockHeight, @@ -52,6 +56,7 @@ func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*pro // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBlockStatusByHeightRequest) (*proto.GetBlockStatusResponse, error) { + log.Println("[rpcserver] GetBlockStatusByHeight()") isFinalized, err := r.fg.GetBlockStatusByHeight(req.BlockHeight) if err != nil { @@ -63,6 +68,7 @@ func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBl // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBlockStatusByHashRequest) (*proto.GetBlockStatusResponse, error) { + log.Println("[rpcserver] GetBlockStatusByHash()") isFinalized, err := r.fg.GetBlockStatusByHash(req.BlockHash) if err != nil { @@ -74,6 +80,7 @@ func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBloc // GetLatestBlock is an RPC method that returns the latest consecutively finalized block. func (r *rpcServer) GetLatestBlock(ctx context.Context, req *proto.GetLatestBlockRequest) (*proto.BlockInfo, error) { + log.Println("[rpcserver] GetLatestBlock()") block, err := r.fg.GetLatestBlock() if err != nil { diff --git a/server/server.go b/server/server.go index 9687684..05ba7a9 100644 --- a/server/server.go +++ b/server/server.go @@ -30,6 +30,7 @@ type Server struct { // NewEOTSManagerServer creates a new server with the given config. func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { + log.Println("[server] NewFinalityGadgetServer()") return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), @@ -42,6 +43,7 @@ func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalit // RunUntilShutdown runs the main finality gadget server loop until a signal is // received to shut down the process. func (s *Server) RunUntilShutdown() error { + log.Println("[server] RunUntilShutdown()") if atomic.AddInt32(&s.started, 1) != 1 { return nil } @@ -85,7 +87,7 @@ func (s *Server) RunUntilShutdown() error { // startGrpcListen starts the GRPC server on the passed listeners. func (s *Server) startGrpcListen(grpcServer *grpc.Server, listeners []net.Listener) error { - + log.Println("[server] startGrpcListen()") // Use a WaitGroup so we can be sure the instructions on how to input the // password is the last thing to be printed to the console. var wg sync.WaitGroup From faab5345e1e55304bde134834cf17750238bd226 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 11:13:26 +0100 Subject: [PATCH 51/93] debug: add more logging and bug fixes --- finalitygadget/finalitygadget.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 882f384..5f20c9b 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -69,20 +69,23 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block err := s.startService() if err != nil { + log.Fatalf("error starting service: %v\n", err) return fmt.Errorf("%v", err) } // Start polling for new blocks at set interval ticker := time.NewTicker(s.PollInterval) + defer ticker.Stop() for range ticker.C { + log.Println("Processing new block...") block, err := s.getBlockByNumber(int64(s.currHeight + 1)) if err != nil { log.Fatalf("error getting new block: %v\n", err) continue } - go func() { + go func(block *types.Block) { s.handleBlock(block) - }() + }(block) } return nil @@ -94,12 +97,14 @@ func (s *FinalityGadget) startService() error { // Query L2 node for last finalized block block, err := s.getLatestFinalizedBlock() if err != nil { + log.Fatalf("error getting last finalized block: %v\n", err) return fmt.Errorf("error getting last finalized block: %v", err) } // Query local DB for last block processed localBlock, err := s.Db.GetLatestBlock() if err != nil { + log.Fatalf("error getting latest block from db: %v\n", err) return fmt.Errorf("error getting latest block from db: %v", err) } @@ -150,6 +155,7 @@ func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { // Get block by number func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { + log.Println("[finalitygadget] getBlockByNumber()") header, err := s.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err From 910f07b43e8d7d52cf0c441dd32a4dc3f38f1a56 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 11:18:07 +0100 Subject: [PATCH 52/93] debug: add err logging for rpc client --- client/rpcclient.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/rpcclient.go b/client/rpcclient.go index 95bc55e..8ba2e62 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -25,6 +25,7 @@ func NewFinalityGadgetGrpcClient( log.Println("[rpcclient] NewFinalityGadgetGrpcClient()") conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { + log.Printf("failed to build gRPC connection to %s: %v\n", remoteAddr, err) return nil, fmt.Errorf("failed to build gRPC connection to %s: %w", remoteAddr, err) } @@ -47,6 +48,7 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) res, err := c.client.InsertBlock(context.Background(), req) if err != nil { + log.Printf("failed to insert block %d: %v\n", block.BlockHeight, err) return false, err } @@ -61,6 +63,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, res, err := c.client.GetBlockStatusByHeight(context.Background(), req) if err != nil { + log.Printf("failed to get block status by height %d: %v\n", height, err) return false, err } @@ -75,6 +78,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, erro res, err := c.client.GetBlockStatusByHash(context.Background(), req) if err != nil { + log.Printf("failed to get block status by hash %s: %v\n", hash, err) return false, err } @@ -87,6 +91,7 @@ func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { res, err := c.client.GetLatestBlock(context.Background(), req) if err != nil { + log.Printf("failed to get latest block: %v\n", err) return nil, err } From fc7ba0f6fa20c925f936a2645f6ec99923e07889 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 11:29:36 +0100 Subject: [PATCH 53/93] debug: use fmt for logging --- client/rpcclient.go | 12 ++++++------ finalitygadget/finalitygadget.go | 22 +++++++++++----------- server/rpcserver.go | 14 +++++++------- server/server.go | 6 +++--- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 8ba2e62..4ab33d7 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -22,7 +22,7 @@ func NewFinalityGadgetGrpcClient( db *db.BBoltHandler, remoteAddr string, ) (*FinalityGadgetGrpcClient, error) { - log.Println("[rpcclient] NewFinalityGadgetGrpcClient()") + fmt.Println("[rpcclient] NewFinalityGadgetGrpcClient()") conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Printf("failed to build gRPC connection to %s: %v\n", remoteAddr, err) @@ -39,7 +39,7 @@ func NewFinalityGadgetGrpcClient( } func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { - log.Println("[rpcclient] InsertBlock()") + fmt.Println("[rpcclient] InsertBlock()") req := &proto.BlockInfo{ BlockHash: block.BlockHash, BlockHeight: block.BlockHeight, @@ -56,7 +56,7 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { - log.Println("[rpcclient] GetBlockStatusByHeight()") + fmt.Println("[rpcclient] GetBlockStatusByHeight()") req := &proto.GetBlockStatusByHeightRequest{ BlockHeight: height, } @@ -71,7 +71,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, error) { - log.Println("[rpcclient] GetBlockStatusByHash()") + fmt.Println("[rpcclient] GetBlockStatusByHash()") req := &proto.GetBlockStatusByHashRequest{ BlockHash: hash, } @@ -86,7 +86,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, erro } func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { - log.Println("[rpcclient] GetLatestBlock()") + fmt.Println("[rpcclient] GetLatestBlock()") req := &proto.GetLatestBlockRequest{} res, err := c.client.GetLatestBlock(context.Background(), req) @@ -103,6 +103,6 @@ func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { } func (c *FinalityGadgetGrpcClient) Close() error { - log.Println("[rpcclient] Close()") + fmt.Println("[rpcclient] Close()") return c.conn.Close() } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 5f20c9b..7348b41 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -65,7 +65,7 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget // This function process blocks indefinitely, starting from the last finalized block. func (s *FinalityGadget) ProcessBlocks() error { - log.Println("[finalitygadget] ProcessBlocks()") + fmt.Println("[finalitygadget] ProcessBlocks()") // Start service at last finalized block err := s.startService() if err != nil { @@ -93,7 +93,7 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block func (s *FinalityGadget) startService() error { - log.Println("[finalitygadget] startService()") + fmt.Println("[finalitygadget] startService()") // Query L2 node for last finalized block block, err := s.getLatestFinalizedBlock() if err != nil { @@ -149,13 +149,13 @@ func (s *FinalityGadget) startService() error { // Get last btc finalized block func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - log.Println("[finalitygadget] getLatestFinalizedBlock()") + fmt.Println("[finalitygadget] getLatestFinalizedBlock()") return s.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } // Get block by number func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { - log.Println("[finalitygadget] getBlockByNumber()") + fmt.Println("[finalitygadget] getBlockByNumber()") header, err := s.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err @@ -168,7 +168,7 @@ func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, erro } func (s *FinalityGadget) handleBlock(block *types.Block) { - log.Println("[finalitygadget] handleBlock()") + fmt.Println("[finalitygadget] handleBlock()") // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { @@ -192,7 +192,7 @@ func (s *FinalityGadget) handleBlock(block *types.Block) { } func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - log.Println("[finalitygadget] queryIsBlockBabylonFinalized()") + fmt.Println("[finalitygadget] queryIsBlockBabylonFinalized()") return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.BlockHash), @@ -202,7 +202,7 @@ func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool } func (s *FinalityGadget) InsertBlock(block *types.Block) error { - log.Println("[finalitygadget] InsertBlock()") + fmt.Println("[finalitygadget] InsertBlock()") // Lock mutex s.Mutex.Lock() // Store block in DB @@ -223,21 +223,21 @@ func (s *FinalityGadget) InsertBlock(block *types.Block) error { } func (s *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - log.Println("[finalitygadget] GetBlockStatusByHeight()") + fmt.Println("[finalitygadget] GetBlockStatusByHeight()") return s.Db.GetBlockStatusByHeight(height) } func (s *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - log.Println("[finalitygadget] GetBlockStatusByHash()") + fmt.Println("[finalitygadget] GetBlockStatusByHash()") return s.Db.GetBlockStatusByHash(hash) } func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { - log.Println("[finalitygadget] GetLatestBlock()") + fmt.Println("[finalitygadget] GetLatestBlock()") return s.Db.GetLatestBlock() } func (s *FinalityGadget) Close() { - log.Println("[finalitygadget] Close()") + fmt.Println("[finalitygadget] Close()") s.L2Client.Close() } diff --git a/server/rpcserver.go b/server/rpcserver.go index 7000db1..6b1508a 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -2,7 +2,7 @@ package server import ( "context" - "log" + "fmt" "google.golang.org/grpc" @@ -23,7 +23,7 @@ type rpcServer struct { func newRPCServer( fg finalitygadget.IFinalityGadget, ) *rpcServer { - log.Println("[rpcserver] newRPCServer()") + fmt.Println("[rpcserver] newRPCServer()") return &rpcServer{ fg: fg, } @@ -32,7 +32,7 @@ func newRPCServer( // RegisterWithGrpcServer registers the rpcServer with the passed root gRPC // server. func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { - log.Println("[rpcserver] RegisterWithGrpcServer()") + fmt.Println("[rpcserver] RegisterWithGrpcServer()") // Register the main RPC server. proto.RegisterFinalityGadgetServer(grpcServer, r) return nil @@ -40,7 +40,7 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { // InsertBlock is an RPC method that inserts a block into the database. func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { - log.Println("[rpcserver] InsertBlock()") + fmt.Println("[rpcserver] InsertBlock()") err := r.fg.InsertBlock(&types.Block{ BlockHash: req.BlockHash, BlockHeight: req.BlockHeight, @@ -56,7 +56,7 @@ func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*pro // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBlockStatusByHeightRequest) (*proto.GetBlockStatusResponse, error) { - log.Println("[rpcserver] GetBlockStatusByHeight()") + fmt.Println("[rpcserver] GetBlockStatusByHeight()") isFinalized, err := r.fg.GetBlockStatusByHeight(req.BlockHeight) if err != nil { @@ -68,7 +68,7 @@ func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBl // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBlockStatusByHashRequest) (*proto.GetBlockStatusResponse, error) { - log.Println("[rpcserver] GetBlockStatusByHash()") + fmt.Println("[rpcserver] GetBlockStatusByHash()") isFinalized, err := r.fg.GetBlockStatusByHash(req.BlockHash) if err != nil { @@ -80,7 +80,7 @@ func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBloc // GetLatestBlock is an RPC method that returns the latest consecutively finalized block. func (r *rpcServer) GetLatestBlock(ctx context.Context, req *proto.GetLatestBlockRequest) (*proto.BlockInfo, error) { - log.Println("[rpcserver] GetLatestBlock()") + fmt.Println("[rpcserver] GetLatestBlock()") block, err := r.fg.GetLatestBlock() if err != nil { diff --git a/server/server.go b/server/server.go index 05ba7a9..98c9e6d 100644 --- a/server/server.go +++ b/server/server.go @@ -30,7 +30,7 @@ type Server struct { // NewEOTSManagerServer creates a new server with the given config. func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { - log.Println("[server] NewFinalityGadgetServer()") + fmt.Println("[server] NewFinalityGadgetServer()") return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), @@ -43,7 +43,7 @@ func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalit // RunUntilShutdown runs the main finality gadget server loop until a signal is // received to shut down the process. func (s *Server) RunUntilShutdown() error { - log.Println("[server] RunUntilShutdown()") + fmt.Println("[server] RunUntilShutdown()") if atomic.AddInt32(&s.started, 1) != 1 { return nil } @@ -87,7 +87,7 @@ func (s *Server) RunUntilShutdown() error { // startGrpcListen starts the GRPC server on the passed listeners. func (s *Server) startGrpcListen(grpcServer *grpc.Server, listeners []net.Listener) error { - log.Println("[server] startGrpcListen()") + fmt.Println("[server] startGrpcListen()") // Use a WaitGroup so we can be sure the instructions on how to input the // password is the last thing to be printed to the console. var wg sync.WaitGroup From 48a40d0ed9b000e12ed6aeca9341afbbecbeb1dd Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 12:02:10 +0100 Subject: [PATCH 54/93] Revert "debug: use fmt for logging" This reverts commit fc7ba0f6fa20c925f936a2645f6ec99923e07889. --- client/rpcclient.go | 12 ++++++------ finalitygadget/finalitygadget.go | 22 +++++++++++----------- server/rpcserver.go | 14 +++++++------- server/server.go | 6 +++--- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 4ab33d7..8ba2e62 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -22,7 +22,7 @@ func NewFinalityGadgetGrpcClient( db *db.BBoltHandler, remoteAddr string, ) (*FinalityGadgetGrpcClient, error) { - fmt.Println("[rpcclient] NewFinalityGadgetGrpcClient()") + log.Println("[rpcclient] NewFinalityGadgetGrpcClient()") conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Printf("failed to build gRPC connection to %s: %v\n", remoteAddr, err) @@ -39,7 +39,7 @@ func NewFinalityGadgetGrpcClient( } func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { - fmt.Println("[rpcclient] InsertBlock()") + log.Println("[rpcclient] InsertBlock()") req := &proto.BlockInfo{ BlockHash: block.BlockHash, BlockHeight: block.BlockHeight, @@ -56,7 +56,7 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { - fmt.Println("[rpcclient] GetBlockStatusByHeight()") + log.Println("[rpcclient] GetBlockStatusByHeight()") req := &proto.GetBlockStatusByHeightRequest{ BlockHeight: height, } @@ -71,7 +71,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, error) { - fmt.Println("[rpcclient] GetBlockStatusByHash()") + log.Println("[rpcclient] GetBlockStatusByHash()") req := &proto.GetBlockStatusByHashRequest{ BlockHash: hash, } @@ -86,7 +86,7 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, erro } func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { - fmt.Println("[rpcclient] GetLatestBlock()") + log.Println("[rpcclient] GetLatestBlock()") req := &proto.GetLatestBlockRequest{} res, err := c.client.GetLatestBlock(context.Background(), req) @@ -103,6 +103,6 @@ func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { } func (c *FinalityGadgetGrpcClient) Close() error { - fmt.Println("[rpcclient] Close()") + log.Println("[rpcclient] Close()") return c.conn.Close() } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 7348b41..5f20c9b 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -65,7 +65,7 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget // This function process blocks indefinitely, starting from the last finalized block. func (s *FinalityGadget) ProcessBlocks() error { - fmt.Println("[finalitygadget] ProcessBlocks()") + log.Println("[finalitygadget] ProcessBlocks()") // Start service at last finalized block err := s.startService() if err != nil { @@ -93,7 +93,7 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block func (s *FinalityGadget) startService() error { - fmt.Println("[finalitygadget] startService()") + log.Println("[finalitygadget] startService()") // Query L2 node for last finalized block block, err := s.getLatestFinalizedBlock() if err != nil { @@ -149,13 +149,13 @@ func (s *FinalityGadget) startService() error { // Get last btc finalized block func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - fmt.Println("[finalitygadget] getLatestFinalizedBlock()") + log.Println("[finalitygadget] getLatestFinalizedBlock()") return s.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } // Get block by number func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { - fmt.Println("[finalitygadget] getBlockByNumber()") + log.Println("[finalitygadget] getBlockByNumber()") header, err := s.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err @@ -168,7 +168,7 @@ func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, erro } func (s *FinalityGadget) handleBlock(block *types.Block) { - fmt.Println("[finalitygadget] handleBlock()") + log.Println("[finalitygadget] handleBlock()") // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { @@ -192,7 +192,7 @@ func (s *FinalityGadget) handleBlock(block *types.Block) { } func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - fmt.Println("[finalitygadget] queryIsBlockBabylonFinalized()") + log.Println("[finalitygadget] queryIsBlockBabylonFinalized()") return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.BlockHash), @@ -202,7 +202,7 @@ func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool } func (s *FinalityGadget) InsertBlock(block *types.Block) error { - fmt.Println("[finalitygadget] InsertBlock()") + log.Println("[finalitygadget] InsertBlock()") // Lock mutex s.Mutex.Lock() // Store block in DB @@ -223,21 +223,21 @@ func (s *FinalityGadget) InsertBlock(block *types.Block) error { } func (s *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - fmt.Println("[finalitygadget] GetBlockStatusByHeight()") + log.Println("[finalitygadget] GetBlockStatusByHeight()") return s.Db.GetBlockStatusByHeight(height) } func (s *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - fmt.Println("[finalitygadget] GetBlockStatusByHash()") + log.Println("[finalitygadget] GetBlockStatusByHash()") return s.Db.GetBlockStatusByHash(hash) } func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { - fmt.Println("[finalitygadget] GetLatestBlock()") + log.Println("[finalitygadget] GetLatestBlock()") return s.Db.GetLatestBlock() } func (s *FinalityGadget) Close() { - fmt.Println("[finalitygadget] Close()") + log.Println("[finalitygadget] Close()") s.L2Client.Close() } diff --git a/server/rpcserver.go b/server/rpcserver.go index 6b1508a..7000db1 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -2,7 +2,7 @@ package server import ( "context" - "fmt" + "log" "google.golang.org/grpc" @@ -23,7 +23,7 @@ type rpcServer struct { func newRPCServer( fg finalitygadget.IFinalityGadget, ) *rpcServer { - fmt.Println("[rpcserver] newRPCServer()") + log.Println("[rpcserver] newRPCServer()") return &rpcServer{ fg: fg, } @@ -32,7 +32,7 @@ func newRPCServer( // RegisterWithGrpcServer registers the rpcServer with the passed root gRPC // server. func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { - fmt.Println("[rpcserver] RegisterWithGrpcServer()") + log.Println("[rpcserver] RegisterWithGrpcServer()") // Register the main RPC server. proto.RegisterFinalityGadgetServer(grpcServer, r) return nil @@ -40,7 +40,7 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { // InsertBlock is an RPC method that inserts a block into the database. func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { - fmt.Println("[rpcserver] InsertBlock()") + log.Println("[rpcserver] InsertBlock()") err := r.fg.InsertBlock(&types.Block{ BlockHash: req.BlockHash, BlockHeight: req.BlockHeight, @@ -56,7 +56,7 @@ func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*pro // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBlockStatusByHeightRequest) (*proto.GetBlockStatusResponse, error) { - fmt.Println("[rpcserver] GetBlockStatusByHeight()") + log.Println("[rpcserver] GetBlockStatusByHeight()") isFinalized, err := r.fg.GetBlockStatusByHeight(req.BlockHeight) if err != nil { @@ -68,7 +68,7 @@ func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBl // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBlockStatusByHashRequest) (*proto.GetBlockStatusResponse, error) { - fmt.Println("[rpcserver] GetBlockStatusByHash()") + log.Println("[rpcserver] GetBlockStatusByHash()") isFinalized, err := r.fg.GetBlockStatusByHash(req.BlockHash) if err != nil { @@ -80,7 +80,7 @@ func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBloc // GetLatestBlock is an RPC method that returns the latest consecutively finalized block. func (r *rpcServer) GetLatestBlock(ctx context.Context, req *proto.GetLatestBlockRequest) (*proto.BlockInfo, error) { - fmt.Println("[rpcserver] GetLatestBlock()") + log.Println("[rpcserver] GetLatestBlock()") block, err := r.fg.GetLatestBlock() if err != nil { diff --git a/server/server.go b/server/server.go index 98c9e6d..05ba7a9 100644 --- a/server/server.go +++ b/server/server.go @@ -30,7 +30,7 @@ type Server struct { // NewEOTSManagerServer creates a new server with the given config. func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { - fmt.Println("[server] NewFinalityGadgetServer()") + log.Println("[server] NewFinalityGadgetServer()") return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), @@ -43,7 +43,7 @@ func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalit // RunUntilShutdown runs the main finality gadget server loop until a signal is // received to shut down the process. func (s *Server) RunUntilShutdown() error { - fmt.Println("[server] RunUntilShutdown()") + log.Println("[server] RunUntilShutdown()") if atomic.AddInt32(&s.started, 1) != 1 { return nil } @@ -87,7 +87,7 @@ func (s *Server) RunUntilShutdown() error { // startGrpcListen starts the GRPC server on the passed listeners. func (s *Server) startGrpcListen(grpcServer *grpc.Server, listeners []net.Listener) error { - fmt.Println("[server] startGrpcListen()") + log.Println("[server] startGrpcListen()") // Use a WaitGroup so we can be sure the instructions on how to input the // password is the last thing to be printed to the console. var wg sync.WaitGroup From be767cb15ce6ab010ad3b979a20f9daadb8e8876 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 12:03:12 +0100 Subject: [PATCH 55/93] Revert "debug: add err logging for rpc client" This reverts commit 910f07b43e8d7d52cf0c441dd32a4dc3f38f1a56. --- client/rpcclient.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 8ba2e62..95bc55e 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -25,7 +25,6 @@ func NewFinalityGadgetGrpcClient( log.Println("[rpcclient] NewFinalityGadgetGrpcClient()") conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { - log.Printf("failed to build gRPC connection to %s: %v\n", remoteAddr, err) return nil, fmt.Errorf("failed to build gRPC connection to %s: %w", remoteAddr, err) } @@ -48,7 +47,6 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) res, err := c.client.InsertBlock(context.Background(), req) if err != nil { - log.Printf("failed to insert block %d: %v\n", block.BlockHeight, err) return false, err } @@ -63,7 +61,6 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, res, err := c.client.GetBlockStatusByHeight(context.Background(), req) if err != nil { - log.Printf("failed to get block status by height %d: %v\n", height, err) return false, err } @@ -78,7 +75,6 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, erro res, err := c.client.GetBlockStatusByHash(context.Background(), req) if err != nil { - log.Printf("failed to get block status by hash %s: %v\n", hash, err) return false, err } @@ -91,7 +87,6 @@ func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { res, err := c.client.GetLatestBlock(context.Background(), req) if err != nil { - log.Printf("failed to get latest block: %v\n", err) return nil, err } From 4b8d29260a39dbb63412ac0c1f24a404ca9bf543 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 12:03:23 +0100 Subject: [PATCH 56/93] Revert "debug: add more logging and bug fixes" This reverts commit faab5345e1e55304bde134834cf17750238bd226. --- finalitygadget/finalitygadget.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 5f20c9b..882f384 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -69,23 +69,20 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block err := s.startService() if err != nil { - log.Fatalf("error starting service: %v\n", err) return fmt.Errorf("%v", err) } // Start polling for new blocks at set interval ticker := time.NewTicker(s.PollInterval) - defer ticker.Stop() for range ticker.C { - log.Println("Processing new block...") block, err := s.getBlockByNumber(int64(s.currHeight + 1)) if err != nil { log.Fatalf("error getting new block: %v\n", err) continue } - go func(block *types.Block) { + go func() { s.handleBlock(block) - }(block) + }() } return nil @@ -97,14 +94,12 @@ func (s *FinalityGadget) startService() error { // Query L2 node for last finalized block block, err := s.getLatestFinalizedBlock() if err != nil { - log.Fatalf("error getting last finalized block: %v\n", err) return fmt.Errorf("error getting last finalized block: %v", err) } // Query local DB for last block processed localBlock, err := s.Db.GetLatestBlock() if err != nil { - log.Fatalf("error getting latest block from db: %v\n", err) return fmt.Errorf("error getting latest block from db: %v", err) } @@ -155,7 +150,6 @@ func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { // Get block by number func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { - log.Println("[finalitygadget] getBlockByNumber()") header, err := s.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err From e615f7a6917d8468d2045eb464f6683314505123 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 12:03:24 +0100 Subject: [PATCH 57/93] Revert "debug: add logging" This reverts commit 370fce1a50639180a7139d2cadd2c02776139c9e. --- client/rpcclient.go | 7 ------- db/bbolt.go | 8 -------- finalitygadget/finalitygadget.go | 11 ----------- server/rpcserver.go | 7 ------- server/server.go | 4 +--- 5 files changed, 1 insertion(+), 36 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 95bc55e..812d123 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -3,7 +3,6 @@ package client import ( "context" "fmt" - "log" "github.com/babylonlabs-io/babylon-finality-gadget/db" "github.com/babylonlabs-io/babylon-finality-gadget/proto" @@ -22,7 +21,6 @@ func NewFinalityGadgetGrpcClient( db *db.BBoltHandler, remoteAddr string, ) (*FinalityGadgetGrpcClient, error) { - log.Println("[rpcclient] NewFinalityGadgetGrpcClient()") conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, fmt.Errorf("failed to build gRPC connection to %s: %w", remoteAddr, err) @@ -38,7 +36,6 @@ func NewFinalityGadgetGrpcClient( } func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { - log.Println("[rpcclient] InsertBlock()") req := &proto.BlockInfo{ BlockHash: block.BlockHash, BlockHeight: block.BlockHeight, @@ -54,7 +51,6 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { - log.Println("[rpcclient] GetBlockStatusByHeight()") req := &proto.GetBlockStatusByHeightRequest{ BlockHeight: height, } @@ -68,7 +64,6 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, error) { - log.Println("[rpcclient] GetBlockStatusByHash()") req := &proto.GetBlockStatusByHashRequest{ BlockHash: hash, } @@ -82,7 +77,6 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, erro } func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { - log.Println("[rpcclient] GetLatestBlock()") req := &proto.GetLatestBlockRequest{} res, err := c.client.GetLatestBlock(context.Background(), req) @@ -98,6 +92,5 @@ func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { } func (c *FinalityGadgetGrpcClient) Close() error { - log.Println("[rpcclient] Close()") return c.conn.Close() } diff --git a/db/bbolt.go b/db/bbolt.go index 6996ef1..4f8e2d8 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -28,7 +28,6 @@ var ( ) func NewBBoltHandler(path string) (*BBoltHandler, error) { - log.Println("[bbolt] NewBBoltHandler()") // 0600 = read/write permission for owner only db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second}) if err != nil { @@ -42,7 +41,6 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { } func (bb *BBoltHandler) TryCreateInitialBuckets() error { - log.Println("[bbolt] TryCreateInitialBuckets()") log.Printf("Initialising DB...") return bb.db.Update(func(tx *bolt.Tx) error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} @@ -65,7 +63,6 @@ func tryCreateBucket(tx *bolt.Tx, bucketName string) error { } func (bb *BBoltHandler) InsertBlock(block *types.Block) error { - log.Println("[bbolt] InsertBlock()") log.Printf("Inserting block %d to DB...\n", block.BlockHeight) // Store mapping number -> block @@ -121,7 +118,6 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { } func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { - log.Println("[bbolt] GetBlockByHeight()") var block types.Block err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blocksBucket)) @@ -139,7 +135,6 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { } func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { - log.Println("[bbolt] GetBlockStatusByHeight()") _, err := bb.GetBlockByHeight(height) if err != nil { if errors.Is(err, ErrBlockNotFound) { @@ -151,7 +146,6 @@ func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { } func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { - log.Println("[bbolt] GetBlockStatusByHash()") // Fetch block number by hash var blockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { @@ -168,7 +162,6 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { } func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { - log.Println("[bbolt] GetLatestBlock()") var latestBlockHeight uint64 // Fetch latest block height @@ -199,7 +192,6 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { } func (bb *BBoltHandler) Close() error { - log.Println("[bbolt] Close()") return bb.db.Close() } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 882f384..a9fa0bc 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -65,7 +65,6 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget // This function process blocks indefinitely, starting from the last finalized block. func (s *FinalityGadget) ProcessBlocks() error { - log.Println("[finalitygadget] ProcessBlocks()") // Start service at last finalized block err := s.startService() if err != nil { @@ -90,7 +89,6 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start service at last finalized block func (s *FinalityGadget) startService() error { - log.Println("[finalitygadget] startService()") // Query L2 node for last finalized block block, err := s.getLatestFinalizedBlock() if err != nil { @@ -144,7 +142,6 @@ func (s *FinalityGadget) startService() error { // Get last btc finalized block func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - log.Println("[finalitygadget] getLatestFinalizedBlock()") return s.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } @@ -162,7 +159,6 @@ func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, erro } func (s *FinalityGadget) handleBlock(block *types.Block) { - log.Println("[finalitygadget] handleBlock()") // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { @@ -186,8 +182,6 @@ func (s *FinalityGadget) handleBlock(block *types.Block) { } func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - log.Println("[finalitygadget] queryIsBlockBabylonFinalized()") - return true, nil return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.BlockHash), BlockHeight: block.BlockHeight, @@ -196,7 +190,6 @@ func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool } func (s *FinalityGadget) InsertBlock(block *types.Block) error { - log.Println("[finalitygadget] InsertBlock()") // Lock mutex s.Mutex.Lock() // Store block in DB @@ -217,21 +210,17 @@ func (s *FinalityGadget) InsertBlock(block *types.Block) error { } func (s *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - log.Println("[finalitygadget] GetBlockStatusByHeight()") return s.Db.GetBlockStatusByHeight(height) } func (s *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - log.Println("[finalitygadget] GetBlockStatusByHash()") return s.Db.GetBlockStatusByHash(hash) } func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { - log.Println("[finalitygadget] GetLatestBlock()") return s.Db.GetLatestBlock() } func (s *FinalityGadget) Close() { - log.Println("[finalitygadget] Close()") s.L2Client.Close() } diff --git a/server/rpcserver.go b/server/rpcserver.go index 7000db1..3fd97ad 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -2,7 +2,6 @@ package server import ( "context" - "log" "google.golang.org/grpc" @@ -23,7 +22,6 @@ type rpcServer struct { func newRPCServer( fg finalitygadget.IFinalityGadget, ) *rpcServer { - log.Println("[rpcserver] newRPCServer()") return &rpcServer{ fg: fg, } @@ -32,7 +30,6 @@ func newRPCServer( // RegisterWithGrpcServer registers the rpcServer with the passed root gRPC // server. func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { - log.Println("[rpcserver] RegisterWithGrpcServer()") // Register the main RPC server. proto.RegisterFinalityGadgetServer(grpcServer, r) return nil @@ -40,7 +37,6 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { // InsertBlock is an RPC method that inserts a block into the database. func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { - log.Println("[rpcserver] InsertBlock()") err := r.fg.InsertBlock(&types.Block{ BlockHash: req.BlockHash, BlockHeight: req.BlockHeight, @@ -56,7 +52,6 @@ func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*pro // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBlockStatusByHeightRequest) (*proto.GetBlockStatusResponse, error) { - log.Println("[rpcserver] GetBlockStatusByHeight()") isFinalized, err := r.fg.GetBlockStatusByHeight(req.BlockHeight) if err != nil { @@ -68,7 +63,6 @@ func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBl // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBlockStatusByHashRequest) (*proto.GetBlockStatusResponse, error) { - log.Println("[rpcserver] GetBlockStatusByHash()") isFinalized, err := r.fg.GetBlockStatusByHash(req.BlockHash) if err != nil { @@ -80,7 +74,6 @@ func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBloc // GetLatestBlock is an RPC method that returns the latest consecutively finalized block. func (r *rpcServer) GetLatestBlock(ctx context.Context, req *proto.GetLatestBlockRequest) (*proto.BlockInfo, error) { - log.Println("[rpcserver] GetLatestBlock()") block, err := r.fg.GetLatestBlock() if err != nil { diff --git a/server/server.go b/server/server.go index 05ba7a9..9687684 100644 --- a/server/server.go +++ b/server/server.go @@ -30,7 +30,6 @@ type Server struct { // NewEOTSManagerServer creates a new server with the given config. func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { - log.Println("[server] NewFinalityGadgetServer()") return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), @@ -43,7 +42,6 @@ func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalit // RunUntilShutdown runs the main finality gadget server loop until a signal is // received to shut down the process. func (s *Server) RunUntilShutdown() error { - log.Println("[server] RunUntilShutdown()") if atomic.AddInt32(&s.started, 1) != 1 { return nil } @@ -87,7 +85,7 @@ func (s *Server) RunUntilShutdown() error { // startGrpcListen starts the GRPC server on the passed listeners. func (s *Server) startGrpcListen(grpcServer *grpc.Server, listeners []net.Listener) error { - log.Println("[server] startGrpcListen()") + // Use a WaitGroup so we can be sure the instructions on how to input the // password is the last thing to be printed to the console. var wg sync.WaitGroup From b187992477d3de8101ef675de9fc10fc96669070 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 12:08:40 +0100 Subject: [PATCH 58/93] feat: add method to delete local DB --- db/bbolt.go | 5 +++++ finalitygadget/finalitygadget.go | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/db/bbolt.go b/db/bbolt.go index 4f8e2d8..5ffda79 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "log" + "os" "time" "github.com/babylonlabs-io/babylon-finality-gadget/types" @@ -191,6 +192,10 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { return bb.GetBlockByHeight(latestBlockHeight) } +func (bb *BBoltHandler) DeleteDB() error { + return os.Remove(bb.db.Path()) +} + func (bb *BBoltHandler) Close() error { return bb.db.Close() } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index a9fa0bc..3b27897 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -221,6 +221,10 @@ func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { return s.Db.GetLatestBlock() } +func (s *FinalityGadget) DeleteDB() error { + return s.Db.DeleteDB() +} + func (s *FinalityGadget) Close() { s.L2Client.Close() } From c2b799ee30f55ed105a6807828d33fdf47865ffb Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 12:31:52 +0100 Subject: [PATCH 59/93] fix: delete db path --- cmd/start.go | 1 + db/bbolt.go | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/start.go b/cmd/start.go index d6faca2..0d7123a 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -110,6 +110,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { return err } fg.Close() + fg.DeleteDB() return nil } diff --git a/db/bbolt.go b/db/bbolt.go index 5ffda79..9a47a27 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -5,8 +5,10 @@ import ( "encoding/binary" "encoding/json" "errors" + "fmt" "log" "os" + "path/filepath" "time" "github.com/babylonlabs-io/babylon-finality-gadget/types" @@ -193,7 +195,14 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { } func (bb *BBoltHandler) DeleteDB() error { - return os.Remove(bb.db.Path()) + absPath, err := filepath.Abs(bb.db.Path()) + fmt.Println("absPath: ", absPath) + if err != nil { + log.Fatalf("failed to get db absolute path: %v\n", err) + return fmt.Errorf("failed to get db absolute path: %w", err) + } + + return os.Remove(absPath) } func (bb *BBoltHandler) Close() error { From 8e72d674fae9c6d99536f9f541d5da4fa21b0fd4 Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 13:57:27 +0100 Subject: [PATCH 60/93] feat: allow cancel ProcessBlocks with ctx --- cmd/start.go | 3 ++- finalitygadget/finalitygadget.go | 26 +++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/cmd/start.go b/cmd/start.go index 0d7123a..9858073 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "log" "os" @@ -92,7 +93,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { // Run verifier in a separate goroutine go func() { - if err := fg.ProcessBlocks(); err != nil { + if err := fg.ProcessBlocks(context.Background()); err != nil { log.Fatalf("Error processing blocks: %v\n", err) } }() diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 3b27897..6f2db68 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -64,7 +64,7 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget } // This function process blocks indefinitely, starting from the last finalized block. -func (s *FinalityGadget) ProcessBlocks() error { +func (s *FinalityGadget) ProcessBlocks(ctx context.Context) error { // Start service at last finalized block err := s.startService() if err != nil { @@ -73,18 +73,22 @@ func (s *FinalityGadget) ProcessBlocks() error { // Start polling for new blocks at set interval ticker := time.NewTicker(s.PollInterval) - for range ticker.C { - block, err := s.getBlockByNumber(int64(s.currHeight + 1)) - if err != nil { - log.Fatalf("error getting new block: %v\n", err) - continue + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return nil + case <-ticker.C: + block, err := s.getBlockByNumber(int64(s.currHeight + 1)) + if err != nil { + log.Fatalf("error getting new block: %v\n", err) + continue + } + go func() { + s.handleBlock(block) + }() } - go func() { - s.handleBlock(block) - }() } - - return nil } // Start service at last finalized block From fb077df2023cae8855cbc48ead66da84b933134b Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 14:14:14 +0100 Subject: [PATCH 61/93] chore: remove print --- db/bbolt.go | 1 - 1 file changed, 1 deletion(-) diff --git a/db/bbolt.go b/db/bbolt.go index 9a47a27..af612c5 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -196,7 +196,6 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { func (bb *BBoltHandler) DeleteDB() error { absPath, err := filepath.Abs(bb.db.Path()) - fmt.Println("absPath: ", absPath) if err != nil { log.Fatalf("failed to get db absolute path: %v\n", err) return fmt.Errorf("failed to get db absolute path: %w", err) From 47294043445127b5055185821686e5ffdc7a92e2 Mon Sep 17 00:00:00 2001 From: lesterli Date: Fri, 2 Aug 2024 11:38:03 +0800 Subject: [PATCH 62/93] update package name (#11) --- go.mod | 2 +- sdk/client/client.go | 10 +++++----- sdk/client/expected_clients.go | 2 +- sdk/client/interface.go | 2 +- sdk/client/query.go | 2 +- sdk/client/query_test.go | 6 +++--- sdk/config/config.go | 2 +- testutil/mock_btc_client.go | 2 +- testutil/mocks/expected_clients_mock.go | 2 +- testutil/mocks/sdkclient_mock.go | 2 +- testutil/random.go | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 0684031..25e44c1 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/babylonlabs-io/babylon-finality-gadget +module github.com/babylonlabs-io/finality-gadget go 1.21 diff --git a/sdk/client/client.go b/sdk/client/client.go index a3e0cb4..a1185c9 100644 --- a/sdk/client/client.go +++ b/sdk/client/client.go @@ -6,14 +6,14 @@ import ( bbncfg "github.com/babylonlabs-io/babylon/client/config" "go.uber.org/zap" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/bbnclient" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/btcclient" - sdkconfig "github.com/babylonlabs-io/babylon-finality-gadget/sdk/config" - "github.com/babylonlabs-io/babylon-finality-gadget/testutil" + "github.com/babylonlabs-io/finality-gadget/sdk/bbnclient" + "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" + sdkconfig "github.com/babylonlabs-io/finality-gadget/sdk/config" + "github.com/babylonlabs-io/finality-gadget/testutil" babylonClient "github.com/babylonlabs-io/babylon/client/client" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" ) // SdkClient is a client that can only perform queries to a Babylon node diff --git a/sdk/client/expected_clients.go b/sdk/client/expected_clients.go index 3ec339f..70c8955 100644 --- a/sdk/client/expected_clients.go +++ b/sdk/client/expected_clients.go @@ -1,7 +1,7 @@ package client import ( - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" ) diff --git a/sdk/client/interface.go b/sdk/client/interface.go index 56ea4da..0143fba 100644 --- a/sdk/client/interface.go +++ b/sdk/client/interface.go @@ -1,6 +1,6 @@ package client -import "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" +import "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" type ISdkClient interface { /* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget diff --git a/sdk/client/query.go b/sdk/client/query.go index ad02368..a4bc9c1 100644 --- a/sdk/client/query.go +++ b/sdk/client/query.go @@ -5,7 +5,7 @@ import ( "math" "strings" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" ) /* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget diff --git a/sdk/client/query_test.go b/sdk/client/query_test.go index 310311d..8067ac8 100644 --- a/sdk/client/query_test.go +++ b/sdk/client/query_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" - "github.com/babylonlabs-io/babylon-finality-gadget/testutil" - "github.com/babylonlabs-io/babylon-finality-gadget/testutil/mocks" + "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/testutil" + "github.com/babylonlabs-io/finality-gadget/testutil/mocks" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) diff --git a/sdk/config/config.go b/sdk/config/config.go index 5e7f089..728f546 100644 --- a/sdk/config/config.go +++ b/sdk/config/config.go @@ -3,7 +3,7 @@ package config import ( "fmt" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/btcclient" + "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" ) const ( diff --git a/testutil/mock_btc_client.go b/testutil/mock_btc_client.go index 955d833..a4a517f 100644 --- a/testutil/mock_btc_client.go +++ b/testutil/mock_btc_client.go @@ -1,7 +1,7 @@ package testutil import ( - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/btcclient" + "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" "github.com/stretchr/testify/mock" "go.uber.org/zap" ) diff --git a/testutil/mocks/expected_clients_mock.go b/testutil/mocks/expected_clients_mock.go index 896a647..b44c288 100644 --- a/testutil/mocks/expected_clients_mock.go +++ b/testutil/mocks/expected_clients_mock.go @@ -12,7 +12,7 @@ package mocks import ( reflect "reflect" - cwclient "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + cwclient "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" wire "github.com/btcsuite/btcd/wire" gomock "go.uber.org/mock/gomock" diff --git a/testutil/mocks/sdkclient_mock.go b/testutil/mocks/sdkclient_mock.go index 4507da6..8ea970d 100644 --- a/testutil/mocks/sdkclient_mock.go +++ b/testutil/mocks/sdkclient_mock.go @@ -12,7 +12,7 @@ package mocks import ( reflect "reflect" - cwclient "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + cwclient "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" gomock "go.uber.org/mock/gomock" ) diff --git a/testutil/random.go b/testutil/random.go index 258ea9a..3eb3a96 100644 --- a/testutil/random.go +++ b/testutil/random.go @@ -4,7 +4,7 @@ import ( "math/rand" "strings" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" "github.com/ethereum/go-ethereum/common" ) From 62491f1ef01a1442a33d5ba8b0ee12565255223f Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 21:24:11 +0100 Subject: [PATCH 63/93] fix: update package name --- client/rpcclient.go | 6 +++--- cmd/start.go | 10 +++++----- db/bbolt.go | 2 +- finalitygadget/README.md | 2 +- finalitygadget/finalitygadget.go | 14 +++++++------- finalitygadget/interface.go | 2 +- proto/finalitygadget.proto | 2 +- server/rpcserver.go | 6 +++--- server/server.go | 6 +++--- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 812d123..356ea6d 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - "github.com/babylonlabs-io/babylon-finality-gadget/db" - "github.com/babylonlabs-io/babylon-finality-gadget/proto" - "github.com/babylonlabs-io/babylon-finality-gadget/types" + "github.com/babylonlabs-io/finality-gadget/db" + "github.com/babylonlabs-io/finality-gadget/proto" + "github.com/babylonlabs-io/finality-gadget/types" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) diff --git a/cmd/start.go b/cmd/start.go index 9858073..78fb147 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -11,11 +11,11 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - rpcclient "github.com/babylonlabs-io/babylon-finality-gadget/client" - "github.com/babylonlabs-io/babylon-finality-gadget/db" - "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget" - "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget/config" - "github.com/babylonlabs-io/babylon-finality-gadget/server" + rpcclient "github.com/babylonlabs-io/finality-gadget/client" + "github.com/babylonlabs-io/finality-gadget/db" + "github.com/babylonlabs-io/finality-gadget/finalitygadget" + "github.com/babylonlabs-io/finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/finality-gadget/server" sig "github.com/lightningnetwork/lnd/signal" ) diff --git a/db/bbolt.go b/db/bbolt.go index af612c5..de20bac 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -11,7 +11,7 @@ import ( "path/filepath" "time" - "github.com/babylonlabs-io/babylon-finality-gadget/types" + "github.com/babylonlabs-io/finality-gadget/types" bolt "go.etcd.io/bbolt" ) diff --git a/finalitygadget/README.md b/finalitygadget/README.md index d309dbc..76ae220 100644 --- a/finalitygadget/README.md +++ b/finalitygadget/README.md @@ -7,7 +7,7 @@ This is a peripheral program that can be run by users of OP stack L2s to track c To get started, clone the repository. ```bash -git clone https://github.com/babylonlabs-io/babylon-finality-gadget.git +git clone https://github.com/babylonlabs-io/finality-gadget.git ``` Configure the `config.toml` file with the following content: diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 6f2db68..07938fb 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -9,13 +9,13 @@ import ( "sync" "time" - "github.com/babylonlabs-io/babylon-finality-gadget/db" - "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget/config" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/btcclient" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/client" - sdkconfig "github.com/babylonlabs-io/babylon-finality-gadget/sdk/config" - "github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient" - "github.com/babylonlabs-io/babylon-finality-gadget/types" + "github.com/babylonlabs-io/finality-gadget/db" + "github.com/babylonlabs-io/finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" + "github.com/babylonlabs-io/finality-gadget/sdk/client" + sdkconfig "github.com/babylonlabs-io/finality-gadget/sdk/config" + "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/types" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" ) diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go index 2c87d34..9cda5a0 100644 --- a/finalitygadget/interface.go +++ b/finalitygadget/interface.go @@ -1,6 +1,6 @@ package finalitygadget -import "github.com/babylonlabs-io/babylon-finality-gadget/types" +import "github.com/babylonlabs-io/finality-gadget/types" type IFinalityGadget interface { InsertBlock(block *types.Block) error diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index 381060a..d64c3d6 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package proto; -option go_package = "github.com/babylonlabs-io/babylon-finality-gadget/proto"; +option go_package = "github.com/babylonlabs-io/finality-gadget/proto"; service FinalityGadget { // InsertBlock inserts a new block into the finality gadget db diff --git a/server/rpcserver.go b/server/rpcserver.go index 3fd97ad..543ee74 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -5,9 +5,9 @@ import ( "google.golang.org/grpc" - "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget" - "github.com/babylonlabs-io/babylon-finality-gadget/proto" - "github.com/babylonlabs-io/babylon-finality-gadget/types" + "github.com/babylonlabs-io/finality-gadget/finalitygadget" + "github.com/babylonlabs-io/finality-gadget/proto" + "github.com/babylonlabs-io/finality-gadget/types" ) // rpcServer is the main RPC server for the finality gadget daemon that handles diff --git a/server/server.go b/server/server.go index 9687684..6b3e375 100644 --- a/server/server.go +++ b/server/server.go @@ -7,9 +7,9 @@ import ( "sync" "sync/atomic" - "github.com/babylonlabs-io/babylon-finality-gadget/db" - "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget" - "github.com/babylonlabs-io/babylon-finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/finality-gadget/db" + "github.com/babylonlabs-io/finality-gadget/finalitygadget" + "github.com/babylonlabs-io/finality-gadget/finalitygadget/config" "github.com/lightningnetwork/lnd/signal" "google.golang.org/grpc" From 4ff43c720b6afb51fb6d3828c85720e813e508dc Mon Sep 17 00:00:00 2001 From: parketh Date: Mon, 5 Aug 2024 22:09:50 +0100 Subject: [PATCH 64/93] fix: block status queries --- db/bbolt.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/db/bbolt.go b/db/bbolt.go index de20bac..c2b480c 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -49,7 +49,6 @@ func (bb *BBoltHandler) TryCreateInitialBuckets() error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} for _, bucket := range buckets { if err := tryCreateBucket(tx, bucket); err != nil { - log.Fatalf("Error creating bucket: %v\n", err) return err } } @@ -131,7 +130,6 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { return json.Unmarshal(v, &block) }) if err != nil { - log.Fatalf("Error getting block by %d\n", err) return nil, err } return &block, nil @@ -153,11 +151,17 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { var blockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blockHeightsBucket)) - blockHeight = btoi(b.Get([]byte(hash))) + res := b.Get([]byte(hash)) + if len(res) == 0 { + return ErrBlockNotFound + } + blockHeight = btoi(res) return nil }) if err != nil { - log.Fatalf("Error getting block by hash: %v\n", err) + if errors.Is(err, ErrBlockNotFound) { + return false, nil + } return false, err } From 02a49df6bfa4b6f9174369b5609e2cb386188392 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 10:13:58 +0100 Subject: [PATCH 65/93] feat: rename daemon and add build instructions --- Makefile | 7 ++++++- cmd/{ => opfgd}/main.go | 8 ++++---- cmd/{ => opfgd}/start.go | 8 ++++---- finalitygadget/README.md | 33 ++++++++++++++++++++++---------- finalitygadget/finalitygadget.go | 4 ++-- 5 files changed, 39 insertions(+), 21 deletions(-) rename cmd/{ => opfgd}/main.go (77%) rename cmd/{ => opfgd}/start.go (91%) diff --git a/Makefile b/Makefile index ae5c159..472b534 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ MOCKS_DIR=./testutil/mocks +OPFGD_PKG := github.com/babylonlabs-io/finality-gadget/cmd/opfgd + mock-gen: go install go.uber.org/mock/mockgen@latest mockgen -source=sdk/client/expected_clients.go -package mocks -destination $(MOCKS_DIR)/expected_clients_mock.go @@ -11,4 +13,7 @@ test: go test -race ./... -v lint: - golangci-lint run \ No newline at end of file + golangci-lint run + +install: + go install -trimpath $(OPFGD_PKG) \ No newline at end of file diff --git a/cmd/main.go b/cmd/opfgd/main.go similarity index 77% rename from cmd/main.go rename to cmd/opfgd/main.go index 67679c2..93066d0 100644 --- a/cmd/main.go +++ b/cmd/opfgd/main.go @@ -11,9 +11,9 @@ import ( func NewRootCmd() *cobra.Command { rootCmd := &cobra.Command{ - Use: "vrf", - Short: "vrf - Babylon OP Finality Gadget Verifier", - Long: `vrf is a daemon to track consecutive quorum and query the Babylon BTC block finalization status of OP stack chains.`, + Use: "opfgd", + Short: "opfgd - Babylon OP Finality Gadget", + Long: `opfgd is a daemon to track consecutive quorum and query the Babylon BTC block finalization status of OP stack chains.`, SilenceErrors: false, } @@ -32,7 +32,7 @@ func main() { } if err := cmd.Execute(); err != nil { - log.Fatalf("Error executing your vrf daemon: %s", err) + log.Fatalf("Error executing your opfgd daemon: %s", err) os.Exit(1) } } diff --git a/cmd/start.go b/cmd/opfgd/start.go similarity index 91% rename from cmd/start.go rename to cmd/opfgd/start.go index 78fb147..a329fd8 100644 --- a/cmd/start.go +++ b/cmd/opfgd/start.go @@ -27,9 +27,9 @@ const ( func CommandStart() *cobra.Command { var cmd = &cobra.Command{ Use: "start", - Short: "Start the finality gadget verifier daemon", - Long: `Start the finality gadget verifier daemon. Note that a config.toml file is required to start the daemon.`, - Example: `vrf start --cfg config.toml`, + Short: "Start the op finality gadget daemon", + Long: `Start the op finality gadget daemon. Note that a config.toml file is required to start the daemon.`, + Example: `opfgd start --cfg config.toml`, Args: cobra.NoArgs, RunE: runEWithClientCtx(runStartCmd), } @@ -91,7 +91,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) - // Run verifier in a separate goroutine + // Run finality gadget in a separate goroutine go func() { if err := fg.ProcessBlocks(context.Background()); err != nil { log.Fatalf("Error processing blocks: %v\n", err) diff --git a/finalitygadget/README.md b/finalitygadget/README.md index 76ae220..bb2c10e 100644 --- a/finalitygadget/README.md +++ b/finalitygadget/README.md @@ -1,8 +1,8 @@ -# Babylon Verifier Daemon +# Babylon Finality Gadget This is a peripheral program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks via RESTful API endpoints. -## Running the daemon +## Downloading and configuring the daemon To get started, clone the repository. @@ -23,19 +23,32 @@ GRPCServerPort = # Port to run the gRPC server on PollInterval = # Interval to poll for new L2 blocks ``` -To start the daemon, navigate to the `/cmd` directory: +### Building and installing the binary + +At the top-level directory of the project ```bash -cd cmd -go run . start --cfg ../config.toml +make install ``` - +The above command will build and install the `opfgd` binary to +`$GOPATH/bin`: - +export PATH=$HOME/go/bin:$PATH +echo 'export PATH=$HOME/go/bin:$PATH' >> ~/.profile +``` + +### Running the daemon + +To start the daemon, run: + +```bash +opfgd start --cfg config.toml +``` diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 07938fb..b7535e2 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -54,7 +54,7 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget return nil, fmt.Errorf("failed to create OPStack L2 client: %w", err) } - // Create verifier + // Create finality gadget return &FinalityGadget{ SdkClient: sdkClient, L2Client: l2Client, @@ -135,7 +135,7 @@ func (s *FinalityGadget) startService() error { } // Start service at block height - log.Printf("Starting verifier at block %d...\n", block.BlockHeight) + log.Printf("Starting finality gadget at block %d...\n", block.BlockHeight) // Set the start block and curr finalized block in memory s.startHeight = block.BlockHeight From e196544a3187fdd42fd41c44bac9f946160c584e Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 10:14:14 +0100 Subject: [PATCH 66/93] fix: always persist DB state --- cmd/opfgd/start.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/opfgd/start.go b/cmd/opfgd/start.go index a329fd8..1e52b00 100644 --- a/cmd/opfgd/start.go +++ b/cmd/opfgd/start.go @@ -111,7 +111,6 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { return err } fg.Close() - fg.DeleteDB() return nil } From 8e84098b9e42aea1432933b6a51366b13b9a5b58 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 10:56:11 +0100 Subject: [PATCH 67/93] chore: rename finality gadget --- finalitygadget/finalitygadget.go | 74 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index b7535e2..40dd639 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -64,43 +64,43 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget } // This function process blocks indefinitely, starting from the last finalized block. -func (s *FinalityGadget) ProcessBlocks(ctx context.Context) error { +func (fg *FinalityGadget) ProcessBlocks(ctx context.Context) error { // Start service at last finalized block - err := s.startService() + err := fg.startService() if err != nil { return fmt.Errorf("%v", err) } // Start polling for new blocks at set interval - ticker := time.NewTicker(s.PollInterval) + ticker := time.NewTicker(fg.PollInterval) defer ticker.Stop() for { select { case <-ctx.Done(): return nil case <-ticker.C: - block, err := s.getBlockByNumber(int64(s.currHeight + 1)) + block, err := fg.getBlockByNumber(int64(fg.currHeight + 1)) if err != nil { log.Fatalf("error getting new block: %v\n", err) continue } go func() { - s.handleBlock(block) + fg.handleBlock(block) }() } } } // Start service at last finalized block -func (s *FinalityGadget) startService() error { +func (fg *FinalityGadget) startService() error { // Query L2 node for last finalized block - block, err := s.getLatestFinalizedBlock() + block, err := fg.getLatestFinalizedBlock() if err != nil { return fmt.Errorf("error getting last finalized block: %v", err) } // Query local DB for last block processed - localBlock, err := s.Db.GetLatestBlock() + localBlock, err := fg.Db.GetLatestBlock() if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } @@ -119,7 +119,7 @@ func (s *FinalityGadget) startService() error { } // Check the block is finalized using sdk client - isFinal, err := s.queryIsBlockBabylonFinalized(block) + isFinal, err := fg.queryIsBlockBabylonFinalized(block) // If not finalized, throw error if !isFinal { return fmt.Errorf("block %d should be finalized according to client but is not", block.BlockHeight) @@ -128,7 +128,7 @@ func (s *FinalityGadget) startService() error { return fmt.Errorf("error checking block %d: %v", block.BlockHeight, err) } // If finalised, store the block in DB and set the last finalized block - err = s.InsertBlock(block) + err = fg.InsertBlock(block) if err != nil { return fmt.Errorf("error storing block %d: %v", block.BlockHeight, err) } @@ -138,20 +138,20 @@ func (s *FinalityGadget) startService() error { log.Printf("Starting finality gadget at block %d...\n", block.BlockHeight) // Set the start block and curr finalized block in memory - s.startHeight = block.BlockHeight - s.currHeight = block.BlockHeight + fg.startHeight = block.BlockHeight + fg.currHeight = block.BlockHeight return nil } // Get last btc finalized block -func (s *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - return s.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) +func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { + return fg.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) } // Get block by number -func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { - header, err := s.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) +func (fg *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { + header, err := fg.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err } @@ -162,18 +162,18 @@ func (s *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, erro }, nil } -func (s *FinalityGadget) handleBlock(block *types.Block) { +func (fg *FinalityGadget) handleBlock(block *types.Block) { // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { // Check if block is finalized - isFinal, err := s.queryIsBlockBabylonFinalized(block) + isFinal, err := fg.queryIsBlockBabylonFinalized(block) if err != nil { log.Fatalf("Error checking block %d: %v\n", block.BlockHeight, err) return } if isFinal { - err = s.InsertBlock(block) + err = fg.InsertBlock(block) if err != nil { log.Fatalf("Error storing block %d: %v\n", block.BlockHeight, err) } @@ -181,23 +181,23 @@ func (s *FinalityGadget) handleBlock(block *types.Block) { } // Sleep for `PollInterval` seconds - time.Sleep(s.PollInterval * time.Second) + time.Sleep(fg.PollInterval * time.Second) } } -func (vf *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - return vf.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ +func (fg *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { + return fg.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ BlockHash: string(block.BlockHash), BlockHeight: block.BlockHeight, BlockTimestamp: block.BlockTimestamp, }) } -func (s *FinalityGadget) InsertBlock(block *types.Block) error { +func (fg *FinalityGadget) InsertBlock(block *types.Block) error { // Lock mutex - s.Mutex.Lock() + fg.Mutex.Lock() // Store block in DB - err := s.Db.InsertBlock(&types.Block{ + err := fg.Db.InsertBlock(&types.Block{ BlockHeight: block.BlockHeight, BlockHash: block.BlockHash, BlockTimestamp: block.BlockTimestamp, @@ -206,29 +206,29 @@ func (s *FinalityGadget) InsertBlock(block *types.Block) error { return err } // Set last finalized block in memory - s.currHeight = block.BlockHeight + fg.currHeight = block.BlockHeight // Unlock mutex - s.Mutex.Unlock() + fg.Mutex.Unlock() return nil } -func (s *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - return s.Db.GetBlockStatusByHeight(height) +func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { + return fg.Db.GetBlockStatusByHeight(height) } -func (s *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - return s.Db.GetBlockStatusByHash(hash) +func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { + return fg.Db.GetBlockStatusByHash(hash) } -func (s *FinalityGadget) GetLatestBlock() (*types.Block, error) { - return s.Db.GetLatestBlock() +func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { + return fg.Db.GetLatestBlock() } -func (s *FinalityGadget) DeleteDB() error { - return s.Db.DeleteDB() +func (fg *FinalityGadget) DeleteDB() error { + return fg.Db.DeleteDB() } -func (s *FinalityGadget) Close() { - s.L2Client.Close() +func (fg *FinalityGadget) Close() { + fg.L2Client.Close() } From fd21437ad305f83e9e48f53a90a22e3bb4a9954c Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 10:56:29 +0100 Subject: [PATCH 68/93] feat: normalise block hash for querying --- finalitygadget/finalitygadget.go | 4 ++-- finalitygadget/utils.go | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 finalitygadget/utils.go diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 40dd639..1eb5351 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -199,7 +199,7 @@ func (fg *FinalityGadget) InsertBlock(block *types.Block) error { // Store block in DB err := fg.Db.InsertBlock(&types.Block{ BlockHeight: block.BlockHeight, - BlockHash: block.BlockHash, + BlockHash: normalizeBlockHash(block.BlockHash), BlockTimestamp: block.BlockTimestamp, }) if err != nil { @@ -218,7 +218,7 @@ func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { } func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - return fg.Db.GetBlockStatusByHash(hash) + return fg.Db.GetBlockStatusByHash(normalizeBlockHash(hash)) } func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { diff --git a/finalitygadget/utils.go b/finalitygadget/utils.go new file mode 100644 index 0000000..7fe4717 --- /dev/null +++ b/finalitygadget/utils.go @@ -0,0 +1,7 @@ +package finalitygadget + +import "github.com/ethereum/go-ethereum/common" + +func normalizeBlockHash(hash string) string { + return common.HexToHash(hash).Hex() +} From b6e4cf1fb390c0773714a6f7a7b47d8fcca6a0c2 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 11:11:48 +0100 Subject: [PATCH 69/93] test: add db unit tests --- db/bbolt_test.go | 186 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 db/bbolt_test.go diff --git a/db/bbolt_test.go b/db/bbolt_test.go new file mode 100644 index 0000000..e4d8ba1 --- /dev/null +++ b/db/bbolt_test.go @@ -0,0 +1,186 @@ +package db + +import ( + "os" + "testing" + + "github.com/babylonlabs-io/finality-gadget/types" + "github.com/stretchr/testify/assert" +) + +func setupDB(t *testing.T) (*BBoltHandler, func()) { + // Create temp test file. + tempFile, err := os.CreateTemp("", "test-*.db") + if err != nil { + t.Fatalf("Failed to create temp file: %v", err) + } + tempFile.Close() + + // Create a new BBoltHandler + db, err := NewBBoltHandler(tempFile.Name()) + if err != nil { + t.Fatalf("Failed to create BBoltHandler: %v", err) + } + + // Create initial buckets + err = db.TryCreateInitialBuckets() + if err != nil { + t.Fatalf("Failed to create initial buckets: %v", err) + } + + // Cleanup function to close DB and remove temp file + cleanup := func() { + db.Close() + db.DeleteDB() + } + + return db, cleanup +} + +func TestInsertBlock(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + + err := handler.InsertBlock(block) + assert.NoError(t, err) + + // Verify block was inserted + retrievedBlock, err := handler.GetBlockByHeight(block.BlockHeight) + assert.NoError(t, err) + assert.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + assert.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + assert.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHeight(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + // Insert a block + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + err := handler.InsertBlock(block) + assert.NoError(t, err) + + // Retrieve block by height + retrievedBlock, err := handler.GetBlockByHeight(block.BlockHeight) + assert.NoError(t, err) + assert.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + assert.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + assert.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHeightForNonExistentBlock(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + block, err := handler.GetBlockByHeight(1) + assert.Nil(t, block) + assert.Equal(t, ErrBlockNotFound, err) +} + +func TestGetBlockStatusByHeight(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + // Insert a block + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + err := handler.InsertBlock(block) + assert.NoError(t, err) + + // Retrieve block status by height + isFinalized, err := handler.GetBlockStatusByHeight(block.BlockHeight) + assert.NoError(t, err) + assert.Equal(t, isFinalized, true) +} + +func TestGetBlockStatusByHeightForNonExistentBlock(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + isFinalized, err := handler.GetBlockStatusByHeight(1) + assert.NoError(t, err) + assert.Equal(t, isFinalized, false) +} + +func TestGetBlockStatusByHash(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + // Insert a block + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + err := handler.InsertBlock(block) + assert.NoError(t, err) + + // Retrieve block status by hash + isFinalized, err := handler.GetBlockStatusByHash(block.BlockHash) + assert.NoError(t, err) + assert.Equal(t, isFinalized, true) +} + +func TestGetBlockStatusByHashForNonExistentBlock(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + isFinalized, err := handler.GetBlockStatusByHash("0x123") + assert.NoError(t, err) + assert.Equal(t, isFinalized, false) +} + +func TestGetLatestBlock(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + // Insert two blocks + first := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + second := &types.Block{ + BlockHeight: 2, + BlockHash: "0x456", + BlockTimestamp: 1050, + } + err := handler.InsertBlock(first) + assert.NoError(t, err) + err = handler.InsertBlock(second) + assert.NoError(t, err) + + // Retrieve latest block + latestBlock, err := handler.GetLatestBlock() + assert.NoError(t, err) + assert.Equal(t, latestBlock.BlockHeight, second.BlockHeight) + assert.Equal(t, latestBlock.BlockHash, second.BlockHash) + assert.Equal(t, latestBlock.BlockTimestamp, second.BlockTimestamp) +} + +func TestGetLatestBlockNonExistent(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + latestBlock, err := handler.GetLatestBlock() + assert.Equal(t, latestBlock, &types.Block{ + BlockHeight: 0, + BlockHash: "", + BlockTimestamp: 0, + }) + assert.NoError(t, err) +} From 8dfd9cbf10c5f01989a57854b85682134fa23a3c Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 12:25:33 +0100 Subject: [PATCH 70/93] feat: refactor repo and merge finalitygadget <> sdk --- README.md | 59 +++++++- {sdk/bbnclient => bbnclient}/bbnclient.go | 19 ++- .../bbnclient => bbnclient}/query_internal.go | 2 +- .../client.go => btcclient/btcclient.go | 19 ++- .../btcclient_test.go | 2 +- .../config.go => btcclient/btcconfig.go | 3 +- cmd/opfgd/start.go | 2 +- {finalitygadget/config => config}/config.go | 26 ++++ {sdk/cwclient => cwclient}/cwclient.go | 17 ++- {sdk/cwclient => cwclient}/query_internal.go | 5 +- finalitygadget/README.md | 54 ------- {sdk/client => finalitygadget}/errors.go | 2 +- finalitygadget/finalitygadget.go | 138 ++++++++---------- .../finalitygadget_test.go | 56 +++---- finalitygadget/interface.go | 10 -- {sdk/client => finalitygadget}/query.go | 76 +++++++--- sdk/client/client.go | 73 --------- sdk/config/config.go | 41 ------ sdk/cwclient/types.go | 7 - server/rpcserver.go | 5 +- server/server.go | 6 +- testutil/mock_btc_client.go | 18 +-- ...ients_mock.go => external_clients_mock.go} | 8 +- ...kclient_mock.go => finalitygadget_mock.go} | 8 +- testutil/random.go | 6 +- .../external_clients.go | 14 +- .../interface.go => types/finalitygadget.go | 22 ++- 27 files changed, 316 insertions(+), 382 deletions(-) rename {sdk/bbnclient => bbnclient}/bbnclient.go (84%) rename {sdk/bbnclient => bbnclient}/query_internal.go (97%) rename sdk/btcclient/client.go => btcclient/btcclient.go (82%) rename sdk/btcclient/client_test.go => btcclient/btcclient_test.go (95%) rename sdk/btcclient/config.go => btcclient/btcconfig.go (99%) rename {finalitygadget/config => config}/config.go (64%) rename {sdk/cwclient => cwclient}/cwclient.go (76%) rename {sdk/cwclient => cwclient}/query_internal.go (91%) delete mode 100644 finalitygadget/README.md rename {sdk/client => finalitygadget}/errors.go (90%) rename sdk/client/query_test.go => finalitygadget/finalitygadget_test.go (87%) delete mode 100644 finalitygadget/interface.go rename {sdk/client => finalitygadget}/query.go (69%) delete mode 100644 sdk/client/client.go delete mode 100644 sdk/config/config.go delete mode 100644 sdk/cwclient/types.go rename testutil/mocks/{expected_clients_mock.go => external_clients_mock.go} (97%) rename testutil/mocks/{sdkclient_mock.go => finalitygadget_mock.go} (92%) rename sdk/client/expected_clients.go => types/external_clients.go (75%) rename sdk/client/interface.go => types/finalitygadget.go (79%) diff --git a/README.md b/README.md index 7662e8c..bab7282 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,64 @@ # Babylon Finality Gadget -We proposed a [Babylon finality gadget](https://github.com/ethereum-optimism/specs/discussions/218) for OP-stack chains. The finality gadget depends on the EOTS data in a CosmWasm contract deployed on the Babylon chain. +The Babylon Finality Gadget is a program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks. -We have modified the OP-stack codebase to use the SDK in this codebase for additional finalty checks. +See our [proposal](https://github.com/ethereum-optimism/specs/discussions/218) on Optimism for more details. -In the future, we will also move the CosmWasm contract code here. +## Downloading and configuring the daemon -## Dependencies +To get started, clone the repository. -The SDK requires a BTC RPC client defined in https://github.com/btcsuite/btcd/tree/master/rpcclient. We wrap it in our own BTC Client to make it easier to use. +```bash +git clone https://github.com/babylonlabs-io/finality-gadget.git +``` + +Configure the `config.toml` file with the following content: + +```toml +L2RPCHost = # RPC URL of OP stack L2 chain +BitcoinRPCHost = # Bitcoin RPC URL +DBFilePath = # Path to local bbolt DB file +FGContractAddress = # Babylon finality gadget contract address +BBNChainID = # Babylon chain id +BBNRPCAddress = # Babylon RPC host URL +GRPCServerPort = # Port to run the gRPC server on +PollInterval = # Interval to poll for new L2 blocks +``` + +### Building and installing the binary + +At the top-level directory of the project + +```bash +make install +``` -## Usages +The above command will build and install the `opfgd` binary to +`$GOPATH/bin`: -To run tests +- `eotsd`: The daemon program for the EOTS manager. +- `fpd`: The daemon program for the finality-provider with overall commands. +If your shell cannot find the installed binaries, make sure `$GOPATH/bin` is in +the `$PATH` of your shell. Usually these commands will do the job + +```bash +export PATH=$HOME/go/bin:$PATH +echo 'export PATH=$HOME/go/bin:$PATH' >> ~/.profile +``` + +### Running the daemon + +To start the daemon, run: + +```bash +opfgd start --cfg config.toml ``` + +### Running tests + +To run tests: + +```bash make test ``` diff --git a/sdk/bbnclient/bbnclient.go b/bbnclient/bbnclient.go similarity index 84% rename from sdk/bbnclient/bbnclient.go rename to bbnclient/bbnclient.go index 9f813f7..e8d1b30 100644 --- a/sdk/bbnclient/bbnclient.go +++ b/bbnclient/bbnclient.go @@ -4,15 +4,18 @@ import ( "math" "github.com/babylonlabs-io/babylon/client/query" - "github.com/babylonlabs-io/babylon/x/btcstaking/types" + bbntypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/finality-gadget/types" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) -type Client struct { +type BabylonClient struct { *query.QueryClient } -func (bbnClient *Client) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { +var _ types.IBabylonClient = &BabylonClient{} + +func (bbnClient *BabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { pagination := &sdkquerytypes.PageRequest{} resp, err := bbnClient.QueryClient.QueryConsumerFinalityProviders(consumerId, pagination) if err != nil { @@ -27,7 +30,7 @@ func (bbnClient *Client) QueryAllFpBtcPubKeys(consumerId string) ([]string, erro return pkArr, nil } -func (bbnClient *Client) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) { +func (bbnClient *BabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) { totalPower := uint64(0) pagination := &sdkquerytypes.PageRequest{} // queries the BTCStaking module for all delegations of a finality provider @@ -58,7 +61,7 @@ func (bbnClient *Client) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uin return totalPower, nil } -func (bbnClient *Client) QueryMultiFpPower( +func (bbnClient *BabylonClient) QueryMultiFpPower( fpPubkeyHexList []string, btcHeight uint64, ) (map[string]uint64, error) { @@ -76,7 +79,7 @@ func (bbnClient *Client) QueryMultiFpPower( } // QueryEarliestActiveDelBtcHeight returns the earliest active BTC staking height -func (bbnClient *Client) QueryEarliestActiveDelBtcHeight(fpPkHexList []string) (uint64, error) { +func (bbnClient *BabylonClient) QueryEarliestActiveDelBtcHeight(fpPkHexList []string) (uint64, error) { allFpEarliestDelBtcHeight := uint64(math.MaxUint64) for _, fpPkHex := range fpPkHexList { @@ -92,7 +95,7 @@ func (bbnClient *Client) QueryEarliestActiveDelBtcHeight(fpPkHexList []string) ( return allFpEarliestDelBtcHeight, nil } -func (bbnClient *Client) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex string) (uint64, error) { +func (bbnClient *BabylonClient) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex string) (uint64, error) { pagination := &sdkquerytypes.PageRequest{ Limit: 100, } @@ -151,7 +154,7 @@ func (bbnClient *Client) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex string) ( // return math.MaxUint64 if the delegation is not active // // Note: the delegation can be unbounded and that's totally fine and shouldn't affect when the chain was activated -func getDelFirstActiveHeight(btcDel *types.BTCDelegationResponse, latestBtcHeight, kValue uint64, covQuorum uint32) uint64 { +func getDelFirstActiveHeight(btcDel *bbntypes.BTCDelegationResponse, latestBtcHeight, kValue uint64, covQuorum uint32) uint64 { activationHeight := btcDel.StartHeight + kValue // not activated yet if latestBtcHeight < activationHeight || uint32(len(btcDel.CovenantSigs)) < covQuorum { diff --git a/sdk/bbnclient/query_internal.go b/bbnclient/query_internal.go similarity index 97% rename from sdk/bbnclient/query_internal.go rename to bbnclient/query_internal.go index 1b80a1a..b017eb2 100644 --- a/sdk/bbnclient/query_internal.go +++ b/bbnclient/query_internal.go @@ -4,7 +4,7 @@ import btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" // we implemented exact logic as in GetStatus // https://github.com/babylonlabs-io/babylon-private/blob/3d8f190c9b0c0795f6546806e3b8582de716cd60/x/btcstaking/types/btc_delegation.go#L90-L111 -func (bbnClient *Client) isDelegationActive( +func (bbnClient *BabylonClient) isDelegationActive( btcDel *btcstakingtypes.BTCDelegationResponse, btcHeight uint64, ) (bool, error) { diff --git a/sdk/btcclient/client.go b/btcclient/btcclient.go similarity index 82% rename from sdk/btcclient/client.go rename to btcclient/btcclient.go index a0521ff..f736aff 100644 --- a/sdk/btcclient/client.go +++ b/btcclient/btcclient.go @@ -4,25 +4,28 @@ import ( "fmt" "github.com/avast/retry-go/v4" + "github.com/babylonlabs-io/finality-gadget/types" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/wire" "go.uber.org/zap" ) -type BTCClient struct { +type BitcoinClient struct { client *rpcclient.Client logger *zap.Logger cfg *BTCConfig } -func NewBTCClient(cfg *BTCConfig, logger *zap.Logger) (*BTCClient, error) { +var _ types.IBitcoinClient = &BitcoinClient{} + +func NewBitcoinClient(cfg *BTCConfig, logger *zap.Logger) (*BitcoinClient, error) { c, err := rpcclient.New(cfg.ToConnConfig(), nil) if err != nil { return nil, err } - return &BTCClient{ + return &BitcoinClient{ client: c, logger: logger, cfg: cfg, @@ -33,7 +36,7 @@ type BlockCountResponse struct { count int64 } -func (c *BTCClient) GetBlockCount() (uint64, error) { +func (c *BitcoinClient) GetBlockCount() (uint64, error) { callForBlockCount := func() (*BlockCountResponse, error) { count, err := c.client.GetBlockCount() if err != nil { @@ -51,7 +54,7 @@ func (c *BTCClient) GetBlockCount() (uint64, error) { return uint64(blockCount.count), nil } -func (c *BTCClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) { +func (c *BitcoinClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) { callForBlockHash := func() (*chainhash.Hash, error) { return c.client.GetBlockHash(int64(height)) } @@ -64,7 +67,7 @@ func (c *BTCClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) return blockHash, nil } -func (c *BTCClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { +func (c *BitcoinClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { callForBlockHeader := func() (*wire.BlockHeader, error) { return c.client.GetBlockHeader(blockHash) } @@ -77,7 +80,7 @@ func (c *BTCClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.Block return header, nil } -func (c *BTCClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { +func (c *BitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { // get the height of the most-work fully-validated chain blockHeight, err := c.GetBlockCount() if err != nil { @@ -113,7 +116,7 @@ func (c *BTCClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, e return lowerBound - 1, nil } -func (c *BTCClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { +func (c *BitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { // get block hash by height blockHash, err := c.GetBlockHashByHeight(height) if err != nil { diff --git a/sdk/btcclient/client_test.go b/btcclient/btcclient_test.go similarity index 95% rename from sdk/btcclient/client_test.go rename to btcclient/btcclient_test.go index 58d924d..ccab76e 100644 --- a/sdk/btcclient/client_test.go +++ b/btcclient/btcclient_test.go @@ -18,7 +18,7 @@ func TestBtcClient(t *testing.T) { // Create BTC client btcConfig := DefaultBTCConfig() - btc, err := NewBTCClient(btcConfig, logger) + btc, err := NewBitcoinClient(btcConfig, logger) require.Nil(t, err) // timestmap between block 848682 and 848683 diff --git a/sdk/btcclient/config.go b/btcclient/btcconfig.go similarity index 99% rename from sdk/btcclient/config.go rename to btcclient/btcconfig.go index 8a9f3f4..0f28e66 100644 --- a/sdk/btcclient/config.go +++ b/btcclient/btcconfig.go @@ -47,7 +47,6 @@ func DefaultBTCConfig() *BTCConfig { } } - func (cfg *BTCConfig) ToConnConfig() *rpcclient.ConnConfig { return &rpcclient.ConnConfig{ Host: cfg.RPCHost, @@ -60,4 +59,4 @@ func (cfg *BTCConfig) ToConnConfig() *rpcclient.ConnConfig { // we may need to re-consider it later if we need any notifications HTTPPostMode: true, } -} \ No newline at end of file +} diff --git a/cmd/opfgd/start.go b/cmd/opfgd/start.go index 1e52b00..1b97fb6 100644 --- a/cmd/opfgd/start.go +++ b/cmd/opfgd/start.go @@ -12,9 +12,9 @@ import ( "github.com/spf13/cobra" rpcclient "github.com/babylonlabs-io/finality-gadget/client" + "github.com/babylonlabs-io/finality-gadget/config" "github.com/babylonlabs-io/finality-gadget/db" "github.com/babylonlabs-io/finality-gadget/finalitygadget" - "github.com/babylonlabs-io/finality-gadget/finalitygadget/config" "github.com/babylonlabs-io/finality-gadget/server" sig "github.com/lightningnetwork/lnd/signal" ) diff --git a/finalitygadget/config/config.go b/config/config.go similarity index 64% rename from finalitygadget/config/config.go rename to config/config.go index 063f217..9214386 100644 --- a/finalitygadget/config/config.go +++ b/config/config.go @@ -1,11 +1,17 @@ package config import ( + "fmt" "time" "github.com/spf13/viper" ) +const ( + BabylonLocalnetChainID = "chain-test" + BabylonDevnetChainID = "euphrates-0.2.0" +) + type Config struct { L2RPCHost string `long:"l2-rpc-host" description:"rpc host address of the L2 node"` BitcoinRPCHost string `long:"bitcoin-rpc-host" description:"rpc host address of the bitcoin node"` @@ -32,3 +38,23 @@ func Load(configPath string) (*Config, error) { return &config, nil } + +func (config *Config) GetRpcAddr() (string, error) { + if config.BBNRPCAddress != "" { + return config.BBNRPCAddress, nil + } + return config.getDefaultRpcAddr() +} + +func (config *Config) getDefaultRpcAddr() (string, error) { + switch config.BBNChainID { + case BabylonLocalnetChainID: + // for the e2e test + return "http://127.0.0.1:26657", nil + case BabylonDevnetChainID: + return "https://rpc-euphrates.devnet.babylonchain.io/", nil + // TODO: add mainnet RPCs when available + default: + return "", fmt.Errorf("unrecognized chain id: %s", config.BBNChainID) + } +} diff --git a/sdk/cwclient/cwclient.go b/cwclient/cwclient.go similarity index 76% rename from sdk/cwclient/cwclient.go rename to cwclient/cwclient.go index 8d27ada..8091a52 100644 --- a/sdk/cwclient/cwclient.go +++ b/cwclient/cwclient.go @@ -3,23 +3,26 @@ package cwclient import ( "encoding/json" + "github.com/babylonlabs-io/finality-gadget/types" rpcclient "github.com/cometbft/cometbft/rpc/client" ) -type Client struct { +type CosmWasmClient struct { rpcclient.Client contractAddr string } -func NewClient(rpcClient rpcclient.Client, contractAddr string) *Client { - return &Client{ +var _ types.ICosmWasmClient = &CosmWasmClient{} + +func NewClient(rpcClient rpcclient.Client, contractAddr string) *CosmWasmClient { + return &CosmWasmClient{ Client: rpcClient, contractAddr: contractAddr, } } -func (cwClient *Client) QueryListOfVotedFinalityProviders( - queryParams *L2Block, +func (cwClient *CosmWasmClient) QueryListOfVotedFinalityProviders( + queryParams *types.Block, ) ([]string, error) { queryData, err := createBlockVotersQueryData(queryParams) if err != nil { @@ -39,7 +42,7 @@ func (cwClient *Client) QueryListOfVotedFinalityProviders( return *votedFpPkHexList, nil } -func (cwClient *Client) QueryConsumerId() (string, error) { +func (cwClient *CosmWasmClient) QueryConsumerId() (string, error) { queryData, err := createConfigQueryData() if err != nil { return "", err @@ -58,7 +61,7 @@ func (cwClient *Client) QueryConsumerId() (string, error) { return data.ConsumerId, nil } -func (cwClient *Client) QueryIsEnabled() (bool, error) { +func (cwClient *CosmWasmClient) QueryIsEnabled() (bool, error) { queryData, err := createIsEnabledQueryData() if err != nil { return false, err diff --git a/sdk/cwclient/query_internal.go b/cwclient/query_internal.go similarity index 91% rename from sdk/cwclient/query_internal.go rename to cwclient/query_internal.go index 1101637..0bd5bde 100644 --- a/sdk/cwclient/query_internal.go +++ b/cwclient/query_internal.go @@ -6,13 +6,14 @@ import ( "time" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/babylonlabs-io/finality-gadget/types" cosmosclient "github.com/cosmos/cosmos-sdk/client" ) // hardcode the timeout to 20 seconds. We can expose it to the params once needed const DefaultTimeout = 20 * time.Second -func createBlockVotersQueryData(queryParams *L2Block) ([]byte, error) { +func createBlockVotersQueryData(queryParams *types.Block) ([]byte, error) { queryData := ContractQueryMsgs{ BlockVoters: &blockVotersQuery{ Height: queryParams.BlockHeight, @@ -68,7 +69,7 @@ func createIsEnabledQueryData() ([]byte, error) { } // querySmartContractState queries the smart contract state given the contract address and query data -func (cwClient *Client) querySmartContractState( +func (cwClient *CosmWasmClient) querySmartContractState( queryData []byte, ) (*wasmtypes.QuerySmartContractStateResponse, error) { ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) diff --git a/finalitygadget/README.md b/finalitygadget/README.md deleted file mode 100644 index bb2c10e..0000000 --- a/finalitygadget/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Babylon Finality Gadget - -This is a peripheral program that can be run by users of OP stack L2s to track consecutive L2 block quorum and query the BTC-finalised status of blocks via RESTful API endpoints. - -## Downloading and configuring the daemon - -To get started, clone the repository. - -```bash -git clone https://github.com/babylonlabs-io/finality-gadget.git -``` - -Configure the `config.toml` file with the following content: - -```toml -L2RPCHost = # RPC URL of OP stack L2 chain -BitcoinRPCHost = # Bitcoin RPC URL -DBFilePath = # Path to local bbolt DB file -FGContractAddress = # Babylon finality gadget contract address -BBNChainID = # Babylon chain id -BBNRPCAddress = # Babylon RPC host URL -GRPCServerPort = # Port to run the gRPC server on -PollInterval = # Interval to poll for new L2 blocks -``` - -### Building and installing the binary - -At the top-level directory of the project - -```bash -make install -``` - -The above command will build and install the `opfgd` binary to -`$GOPATH/bin`: - -- `eotsd`: The daemon program for the EOTS manager. -- `fpd`: The daemon program for the finality-provider with overall commands. - -If your shell cannot find the installed binaries, make sure `$GOPATH/bin` is in -the `$PATH` of your shell. Usually these commands will do the job - -```bash -export PATH=$HOME/go/bin:$PATH -echo 'export PATH=$HOME/go/bin:$PATH' >> ~/.profile -``` - -### Running the daemon - -To start the daemon, run: - -```bash -opfgd start --cfg config.toml -``` diff --git a/sdk/client/errors.go b/finalitygadget/errors.go similarity index 90% rename from sdk/client/errors.go rename to finalitygadget/errors.go index 0edf760..6cf7d40 100644 --- a/sdk/client/errors.go +++ b/finalitygadget/errors.go @@ -1,4 +1,4 @@ -package client +package finalitygadget import "fmt" diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 1eb5351..7ea4aec 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -2,52 +2,78 @@ package finalitygadget import ( "context" - "encoding/hex" "fmt" "log" - "math/big" "sync" "time" + bbnClient "github.com/babylonlabs-io/babylon/client/client" + bbncfg "github.com/babylonlabs-io/babylon/client/config" + "github.com/babylonlabs-io/finality-gadget/bbnclient" + "github.com/babylonlabs-io/finality-gadget/btcclient" + "github.com/babylonlabs-io/finality-gadget/config" + "github.com/babylonlabs-io/finality-gadget/cwclient" "github.com/babylonlabs-io/finality-gadget/db" - "github.com/babylonlabs-io/finality-gadget/finalitygadget/config" - "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" - "github.com/babylonlabs-io/finality-gadget/sdk/client" - sdkconfig "github.com/babylonlabs-io/finality-gadget/sdk/config" - "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/testutil" "github.com/babylonlabs-io/finality-gadget/types" "github.com/ethereum/go-ethereum/ethclient" - ethrpc "github.com/ethereum/go-ethereum/rpc" + "go.uber.org/zap" ) -var _ IFinalityGadget = &FinalityGadget{} +var _ types.IFinalityGadget = &FinalityGadget{} type FinalityGadget struct { - SdkClient *client.SdkClient - L2Client *ethclient.Client - Db *db.BBoltHandler + btcClient types.IBitcoinClient + bbnClient types.IBabylonClient + cwClient types.ICosmWasmClient + l2Client *ethclient.Client - Mutex sync.Mutex + db *db.BBoltHandler + mutex sync.Mutex - PollInterval time.Duration + pollInterval time.Duration startHeight uint64 currHeight uint64 } func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget, error) { - // Create finality gadget client + // Create logger + logger, err := zap.NewProduction() + if err != nil { + return nil, err + } + + // Create bitcoin client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost - sdkClient, err := client.NewClient(&sdkconfig.Config{ - BTCConfig: btcConfig, - ContractAddr: cfg.FGContractAddress, - ChainID: cfg.BBNChainID, - RPCAddr: cfg.BBNRPCAddress, - }) + var btcClient types.IBitcoinClient + // Create BTC client + switch cfg.BBNChainID { + // TODO: once we set up our own local BTC devnet, we don't need to use this mock BTC client + case config.BabylonLocalnetChainID: + btcClient, err = testutil.NewMockBitcoinClient(btcConfig, logger) + default: + btcClient, err = btcclient.NewBitcoinClient(btcConfig, logger) + } if err != nil { - return nil, fmt.Errorf("error creating client: %w", err) + return nil, err } + // Create babylon client + bbnConfig := bbncfg.DefaultBabylonConfig() + bbnConfig.RPCAddr = cfg.BBNRPCAddress + bbnConfig.ChainID = cfg.BBNChainID + babylonClient, err := bbnClient.New( + &bbnConfig, + logger, + ) + if err != nil { + return nil, fmt.Errorf("failed to create Babylon client: %w", err) + } + + // Create cosmwasm client + cwClient := cwclient.NewClient(babylonClient.QueryClient.RPCClient, cfg.FGContractAddress) + // Create L2 client l2Client, err := ethclient.Dial(cfg.L2RPCHost) if err != nil { @@ -56,10 +82,12 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget // Create finality gadget return &FinalityGadget{ - SdkClient: sdkClient, - L2Client: l2Client, - Db: db, - PollInterval: cfg.PollInterval, + btcClient: btcClient, + bbnClient: &bbnclient.BabylonClient{QueryClient: babylonClient.QueryClient}, + cwClient: cwClient, + l2Client: l2Client, + db: db, + pollInterval: cfg.PollInterval, }, nil } @@ -72,7 +100,7 @@ func (fg *FinalityGadget) ProcessBlocks(ctx context.Context) error { } // Start polling for new blocks at set interval - ticker := time.NewTicker(fg.PollInterval) + ticker := time.NewTicker(fg.pollInterval) defer ticker.Stop() for { select { @@ -100,7 +128,7 @@ func (fg *FinalityGadget) startService() error { } // Query local DB for last block processed - localBlock, err := fg.Db.GetLatestBlock() + localBlock, err := fg.db.GetLatestBlock() if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } @@ -119,7 +147,7 @@ func (fg *FinalityGadget) startService() error { } // Check the block is finalized using sdk client - isFinal, err := fg.queryIsBlockBabylonFinalized(block) + isFinal, err := fg.QueryIsBlockBabylonFinalized(block) // If not finalized, throw error if !isFinal { return fmt.Errorf("block %d should be finalized according to client but is not", block.BlockHeight) @@ -144,30 +172,12 @@ func (fg *FinalityGadget) startService() error { return nil } -// Get last btc finalized block -func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - return fg.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) -} - -// Get block by number -func (fg *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { - header, err := fg.L2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) - if err != nil { - return nil, err - } - return &types.Block{ - BlockHeight: header.Number.Uint64(), - BlockHash: hex.EncodeToString(header.Hash().Bytes()), - BlockTimestamp: header.Time, - }, nil -} - func (fg *FinalityGadget) handleBlock(block *types.Block) { // while block is not finalized, recheck if block is finalized every `retryInterval` seconds // if finalized, store the block in DB and set the last finalized block for { // Check if block is finalized - isFinal, err := fg.queryIsBlockBabylonFinalized(block) + isFinal, err := fg.QueryIsBlockBabylonFinalized(block) if err != nil { log.Fatalf("Error checking block %d: %v\n", block.BlockHeight, err) return @@ -181,23 +191,15 @@ func (fg *FinalityGadget) handleBlock(block *types.Block) { } // Sleep for `PollInterval` seconds - time.Sleep(fg.PollInterval * time.Second) + time.Sleep(fg.pollInterval * time.Second) } } -func (fg *FinalityGadget) queryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - return fg.SdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{ - BlockHash: string(block.BlockHash), - BlockHeight: block.BlockHeight, - BlockTimestamp: block.BlockTimestamp, - }) -} - func (fg *FinalityGadget) InsertBlock(block *types.Block) error { // Lock mutex - fg.Mutex.Lock() + fg.mutex.Lock() // Store block in DB - err := fg.Db.InsertBlock(&types.Block{ + err := fg.db.InsertBlock(&types.Block{ BlockHeight: block.BlockHeight, BlockHash: normalizeBlockHash(block.BlockHash), BlockTimestamp: block.BlockTimestamp, @@ -208,27 +210,15 @@ func (fg *FinalityGadget) InsertBlock(block *types.Block) error { // Set last finalized block in memory fg.currHeight = block.BlockHeight // Unlock mutex - fg.Mutex.Unlock() + fg.mutex.Unlock() return nil } -func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - return fg.Db.GetBlockStatusByHeight(height) -} - -func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - return fg.Db.GetBlockStatusByHash(normalizeBlockHash(hash)) -} - -func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { - return fg.Db.GetLatestBlock() -} - func (fg *FinalityGadget) DeleteDB() error { - return fg.Db.DeleteDB() + return fg.db.DeleteDB() } func (fg *FinalityGadget) Close() { - fg.L2Client.Close() + fg.l2Client.Close() } diff --git a/sdk/client/query_test.go b/finalitygadget/finalitygadget_test.go similarity index 87% rename from sdk/client/query_test.go rename to finalitygadget/finalitygadget_test.go index 8067ac8..5a90b16 100644 --- a/sdk/client/query_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -1,4 +1,4 @@ -package client +package finalitygadget import ( "fmt" @@ -7,9 +7,9 @@ import ( "testing" "time" - "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" "github.com/babylonlabs-io/finality-gadget/testutil" "github.com/babylonlabs-io/finality-gadget/testutil/mocks" + "github.com/babylonlabs-io/finality-gadget/types" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -21,20 +21,20 @@ func TestFinalityGadgetDisabled(t *testing.T) { mockCwClient := mocks.NewMockICosmWasmClient(ctl) mockCwClient.EXPECT().QueryIsEnabled().Return(false, nil).Times(1) - mockSdkClient := &SdkClient{ + mockFinalityGadget := &FinalityGadget{ cwClient: mockCwClient, bbnClient: nil, btcClient: nil, } // check QueryIsBlockBabylonFinalized always returns true when finality gadget is not enabled - res, err := mockSdkClient.QueryIsBlockBabylonFinalized(cwclient.L2Block{}) + res, err := mockFinalityGadget.QueryIsBlockBabylonFinalized(&types.Block{}) require.NoError(t, err) require.True(t, res) } func TestQueryIsBlockBabylonFinalized(t *testing.T) { - blockWithHashUntrimmed := cwclient.L2Block{ + blockWithHashUntrimmed := types.Block{ BlockHash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", BlockHeight: 123, BlockTimestamp: 12345, @@ -49,7 +49,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { testCases := []struct { name string expectedErr error - queryParams *cwclient.L2Block + block *types.Block allFpPks []string fpPowers map[string]uint64 votedProviders []string @@ -58,7 +58,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }{ { name: "0% votes, expects false", - queryParams: &blockWithHashTrimmed, + block: &blockWithHashTrimmed, allFpPks: []string{"pk1", "pk2"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 300}, votedProviders: []string{}, @@ -68,7 +68,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "25% votes, expects false", - queryParams: &blockWithHashTrimmed, + block: &blockWithHashTrimmed, allFpPks: []string{"pk1", "pk2"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 300}, votedProviders: []string{"pk1"}, @@ -78,7 +78,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "exact 2/3 votes, expects true", - queryParams: &blockWithHashTrimmed, + block: &blockWithHashTrimmed, allFpPks: []string{"pk1", "pk2", "pk3"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 100, "pk3": 100}, votedProviders: []string{"pk1", "pk2"}, @@ -88,7 +88,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "75% votes, expects true", - queryParams: &blockWithHashTrimmed, + block: &blockWithHashTrimmed, allFpPks: []string{"pk1", "pk2"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 300}, votedProviders: []string{"pk2"}, @@ -98,7 +98,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "100% votes, expects true", - queryParams: &blockWithHashTrimmed, + block: &blockWithHashTrimmed, allFpPks: []string{"pk1", "pk2", "pk3"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 100, "pk3": 100}, votedProviders: []string{"pk1", "pk2", "pk3"}, @@ -108,7 +108,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "untrimmed block hash in input params, 75% votes, expects true", - queryParams: &blockWithHashUntrimmed, + block: &blockWithHashUntrimmed, allFpPks: []string{"pk1", "pk2", "pk3", "pk4"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 100, "pk3": 100, "pk4": 100}, votedProviders: []string{"pk1", "pk2", "pk3"}, @@ -118,7 +118,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "zero voting power, 100% votes, expects false", - queryParams: &blockWithHashUntrimmed, + block: &blockWithHashUntrimmed, allFpPks: []string{"pk1", "pk2", "pk3"}, fpPowers: map[string]uint64{"pk1": 0, "pk2": 0, "pk3": 0}, votedProviders: []string{"pk1", "pk2", "pk3"}, @@ -128,7 +128,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { }, { name: "Btc staking not activated, 100% votes, expects false", - queryParams: &blockWithHashUntrimmed, + block: &blockWithHashUntrimmed, allFpPks: []string{"pk1", "pk2", "pk3"}, fpPowers: map[string]uint64{"pk1": 100, "pk2": 100, "pk3": 100}, votedProviders: []string{"pk1", "pk2", "pk3"}, @@ -148,7 +148,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { mockCwClient.EXPECT().QueryConsumerId().Return(consumerChainID, nil).Times(1) mockBTCClient := mocks.NewMockIBitcoinClient(ctl) mockBTCClient.EXPECT(). - GetBlockHeightByTimestamp(tc.queryParams.BlockTimestamp). + GetBlockHeightByTimestamp(tc.block.BlockTimestamp). Return(BTCHeight, nil). Times(1) @@ -176,13 +176,13 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { } } - mockSdkClient := &SdkClient{ + mockFinalityGadget := &FinalityGadget{ cwClient: mockCwClient, bbnClient: mockBBNClient, btcClient: mockBTCClient, } - res, err := mockSdkClient.QueryIsBlockBabylonFinalized(*tc.queryParams) + res, err := mockFinalityGadget.QueryIsBlockBabylonFinalized(tc.block) require.Equal(t, tc.expectResult, res) require.Equal(t, tc.expectedErr, err) }) @@ -205,16 +205,16 @@ func TestQueryBlockRangeBabylonFinalized(t *testing.T) { name string expectedErr error expectResult *uint64 - queryBlocks []*cwclient.L2Block + queryBlocks []*types.Block }{ - {"empty query blocks", fmt.Errorf("no blocks provided"), nil, []*cwclient.L2Block{}}, - {"single block with finalized", nil, &blockA.BlockHeight, []*cwclient.L2Block{&blockA}}, - {"single block with error", fmt.Errorf("RPC rate limit error"), nil, []*cwclient.L2Block{&blockD}}, - {"non-consecutive blocks", fmt.Errorf("blocks are not consecutive"), nil, []*cwclient.L2Block{&blockA, &blockD}}, - {"the first two blocks are finalized and the last block has error", fmt.Errorf("RPC rate limit error"), &blockB.BlockHeight, []*cwclient.L2Block{&blockA, &blockB, &blockC}}, - {"all consecutive blocks are finalized", nil, &blockB.BlockHeight, []*cwclient.L2Block{&blockA, &blockB}}, - {"none of the block is finalized and the first block has error", fmt.Errorf("RPC rate limit error"), nil, []*cwclient.L2Block{&blockD, &blockE}}, - {"none of the block is finalized and the second block has error", nil, nil, []*cwclient.L2Block{&blockF, &blockG}}, + {"empty query blocks", fmt.Errorf("no blocks provided"), nil, []*types.Block{}}, + {"single block with finalized", nil, &blockA.BlockHeight, []*types.Block{&blockA}}, + {"single block with error", fmt.Errorf("RPC rate limit error"), nil, []*types.Block{&blockD}}, + {"non-consecutive blocks", fmt.Errorf("blocks are not consecutive"), nil, []*types.Block{&blockA, &blockD}}, + {"the first two blocks are finalized and the last block has error", fmt.Errorf("RPC rate limit error"), &blockB.BlockHeight, []*types.Block{&blockA, &blockB, &blockC}}, + {"all consecutive blocks are finalized", nil, &blockB.BlockHeight, []*types.Block{&blockA, &blockB}}, + {"none of the block is finalized and the first block has error", fmt.Errorf("RPC rate limit error"), nil, []*types.Block{&blockD, &blockE}}, + {"none of the block is finalized and the second block has error", nil, nil, []*types.Block{&blockF, &blockG}}, } for _, tc := range testCases { @@ -225,7 +225,7 @@ func TestQueryBlockRangeBabylonFinalized(t *testing.T) { mockCwClient := mocks.NewMockICosmWasmClient(ctl) mockBTCClient := mocks.NewMockIBitcoinClient(ctl) mockBBNClient := mocks.NewMockIBabylonClient(ctl) - mockSdkClient := &SdkClient{ + mockFinalityGadget := &FinalityGadget{ cwClient: mockCwClient, bbnClient: mockBBNClient, btcClient: mockBTCClient, @@ -253,7 +253,7 @@ func TestQueryBlockRangeBabylonFinalized(t *testing.T) { mockBBNClient.EXPECT().QueryAllFpBtcPubKeys("consumer-chain-id").Return([]string{"pk1", "pk2", "pk3"}, nil).AnyTimes() mockBBNClient.EXPECT().QueryMultiFpPower([]string{"pk1", "pk2", "pk3"}, gomock.Any()).Return(map[string]uint64{"pk1": 100, "pk2": 200, "pk3": 300}, nil).AnyTimes() - res, err := mockSdkClient.QueryBlockRangeBabylonFinalized(tc.queryBlocks) + res, err := mockFinalityGadget.QueryBlockRangeBabylonFinalized(tc.queryBlocks) require.Equal(t, tc.expectResult, res) require.Equal(t, tc.expectedErr, err) }) diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go deleted file mode 100644 index 9cda5a0..0000000 --- a/finalitygadget/interface.go +++ /dev/null @@ -1,10 +0,0 @@ -package finalitygadget - -import "github.com/babylonlabs-io/finality-gadget/types" - -type IFinalityGadget interface { - InsertBlock(block *types.Block) error - GetBlockStatusByHeight(height uint64) (bool, error) - GetBlockStatusByHash(hash string) (bool, error) - GetLatestBlock() (*types.Block, error) -} diff --git a/sdk/client/query.go b/finalitygadget/query.go similarity index 69% rename from sdk/client/query.go rename to finalitygadget/query.go index a4bc9c1..ad0b6a6 100644 --- a/sdk/client/query.go +++ b/finalitygadget/query.go @@ -1,13 +1,35 @@ -package client +package finalitygadget import ( + "context" + "encoding/hex" "fmt" "math" + "math/big" "strings" - "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/types" + ethrpc "github.com/ethereum/go-ethereum/rpc" ) +// Get last btc finalized block +func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { + return fg.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) +} + +// Get block by number +func (fg *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { + header, err := fg.l2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) + if err != nil { + return nil, err + } + return &types.Block{ + BlockHeight: header.Number.Uint64(), + BlockHash: hex.EncodeToString(header.Hash().Bytes()), + BlockTimestamp: header.Time, + }, nil +} + /* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget * * - if the finality gadget is not enabled, always return true @@ -24,12 +46,10 @@ import ( * - calculate voted voting power * - check if the voted voting power is more than 2/3 of the total voting power */ -func (sdkClient *SdkClient) QueryIsBlockBabylonFinalized( - queryParams cwclient.L2Block, -) (bool, error) { +func (fg *FinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool, error) { // check if the finality gadget is enabled // if not, always return true to pass through op derivation pipeline - isEnabled, err := sdkClient.cwClient.QueryIsEnabled() + isEnabled, err := fg.cwClient.QueryIsEnabled() if err != nil { return false, err } @@ -38,22 +58,22 @@ func (sdkClient *SdkClient) QueryIsBlockBabylonFinalized( } // trim prefix 0x for the L2 block hash - queryParams.BlockHash = strings.TrimPrefix(queryParams.BlockHash, "0x") + block.BlockHash = strings.TrimPrefix(block.BlockHash, "0x") // get all FPs pubkey for the consumer chain - allFpPks, err := sdkClient.queryAllFpBtcPubKeys() + allFpPks, err := fg.queryAllFpBtcPubKeys() if err != nil { return false, err } // convert the L2 timestamp to BTC height - btcblockHeight, err := sdkClient.btcClient.GetBlockHeightByTimestamp(queryParams.BlockTimestamp) + btcblockHeight, err := fg.btcClient.GetBlockHeightByTimestamp(block.BlockTimestamp) if err != nil { return false, err } // check whether the btc staking is actived - earliestDelHeight, err := sdkClient.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) + earliestDelHeight, err := fg.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) if err != nil { return false, err } @@ -62,7 +82,7 @@ func (sdkClient *SdkClient) QueryIsBlockBabylonFinalized( } // get all FPs voting power at this BTC height - allFpPower, err := sdkClient.bbnClient.QueryMultiFpPower(allFpPks, btcblockHeight) + allFpPower, err := fg.bbnClient.QueryMultiFpPower(allFpPks, btcblockHeight) if err != nil { return false, err } @@ -79,7 +99,7 @@ func (sdkClient *SdkClient) QueryIsBlockBabylonFinalized( } // get all FPs that voted this (L2 block height, L2 block hash) combination - votedFpPks, err := sdkClient.cwClient.QueryListOfVotedFinalityProviders(&queryParams) + votedFpPks, err := fg.cwClient.QueryListOfVotedFinalityProviders(block) if err != nil { return false, err } @@ -101,6 +121,18 @@ func (sdkClient *SdkClient) QueryIsBlockBabylonFinalized( return true, nil } +func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { + return fg.db.GetBlockStatusByHeight(height) +} + +func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { + return fg.db.GetBlockStatusByHash(normalizeBlockHash(hash)) +} + +func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { + return fg.db.GetLatestBlock() +} + /* QueryBlockRangeBabylonFinalized searches for a row of consecutive finalized blocks in the block range, and returns * the last finalized block height * @@ -115,8 +147,8 @@ func (sdkClient *SdkClient) QueryIsBlockBabylonFinalized( * Note: caller needs to make sure the given queryBlocks are consecutive (we don't check hashes inside this method) * and start from low to high */ -func (sdkClient *SdkClient) QueryBlockRangeBabylonFinalized( - queryBlocks []*cwclient.L2Block, +func (fg *FinalityGadget) QueryBlockRangeBabylonFinalized( + queryBlocks []*types.Block, ) (*uint64, error) { if len(queryBlocks) == 0 { return nil, fmt.Errorf("no blocks provided") @@ -129,7 +161,7 @@ func (sdkClient *SdkClient) QueryBlockRangeBabylonFinalized( } var finalizedBlockHeight *uint64 for _, block := range queryBlocks { - isFinalized, err := sdkClient.QueryIsBlockBabylonFinalized(*block) + isFinalized, err := fg.QueryIsBlockBabylonFinalized(block) if err != nil { return finalizedBlockHeight, err } @@ -158,14 +190,14 @@ func (sdkClient *SdkClient) QueryBlockRangeBabylonFinalized( * * returns math.MaxUint64, ErrBtcStakingNotActivated if the BTC staking is not activated */ -func (sdkClient *SdkClient) QueryBtcStakingActivatedTimestamp() (uint64, error) { - allFpPks, err := sdkClient.queryAllFpBtcPubKeys() +func (fg *FinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { + allFpPks, err := fg.queryAllFpBtcPubKeys() if err != nil { return math.MaxUint64, err } // check whether the btc staking is actived - earliestDelHeight, err := sdkClient.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) + earliestDelHeight, err := fg.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) if err != nil { return math.MaxUint64, err } @@ -176,22 +208,22 @@ func (sdkClient *SdkClient) QueryBtcStakingActivatedTimestamp() (uint64, error) } // get the timestamp of the BTC height - btcBlockTimestamp, err := sdkClient.btcClient.GetBlockTimestampByHeight(earliestDelHeight) + btcBlockTimestamp, err := fg.btcClient.GetBlockTimestampByHeight(earliestDelHeight) if err != nil { return math.MaxUint64, err } return btcBlockTimestamp, nil } -func (sdkClient *SdkClient) queryAllFpBtcPubKeys() ([]string, error) { +func (fg *FinalityGadget) queryAllFpBtcPubKeys() ([]string, error) { // get the consumer chain id - consumerId, err := sdkClient.cwClient.QueryConsumerId() + consumerId, err := fg.cwClient.QueryConsumerId() if err != nil { return nil, err } // get all the FPs pubkey for the consumer chain - allFpPks, err := sdkClient.bbnClient.QueryAllFpBtcPubKeys(consumerId) + allFpPks, err := fg.bbnClient.QueryAllFpBtcPubKeys(consumerId) if err != nil { return nil, err } diff --git a/sdk/client/client.go b/sdk/client/client.go deleted file mode 100644 index a1185c9..0000000 --- a/sdk/client/client.go +++ /dev/null @@ -1,73 +0,0 @@ -package client - -import ( - "fmt" - - bbncfg "github.com/babylonlabs-io/babylon/client/config" - "go.uber.org/zap" - - "github.com/babylonlabs-io/finality-gadget/sdk/bbnclient" - "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" - sdkconfig "github.com/babylonlabs-io/finality-gadget/sdk/config" - "github.com/babylonlabs-io/finality-gadget/testutil" - - babylonClient "github.com/babylonlabs-io/babylon/client/client" - - "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" -) - -// SdkClient is a client that can only perform queries to a Babylon node -// It only requires the client config to have `rpcAddr`, but not other fields -// such as keyring, chain ID, etc.. -type SdkClient struct { - bbnClient IBabylonClient - cwClient ICosmWasmClient - btcClient IBitcoinClient -} - -// NewClient creates a new BabylonFinalityGadgetClient according to the given config -func NewClient(config *sdkconfig.Config) (*SdkClient, error) { - rpcAddr, err := config.GetRpcAddr() - if err != nil { - return nil, err - } - - bbnConfig := bbncfg.DefaultBabylonConfig() - bbnConfig.RPCAddr = rpcAddr - - logger, err := zap.NewProduction() - if err != nil { - return nil, err - } - - // Note: We can just ignore the below info which is printed by bbnclient.New - // service injective.evm.v1beta1.Msg does not have cosmos.msg.v1.service proto annotation - babylonClient, err := babylonClient.New( - &bbnConfig, - logger, - ) - if err != nil { - return nil, fmt.Errorf("failed to create Babylon client: %w", err) - } - - var btcClient IBitcoinClient - // Create BTC client - switch config.ChainID { - // TODO: once we set up our own local BTC devnet, we don't need to use this mock BTC client - case sdkconfig.BabylonLocalnet: - btcClient, err = testutil.NewMockBTCClient(config.BTCConfig, logger) - default: - btcClient, err = btcclient.NewBTCClient(config.BTCConfig, logger) - } - if err != nil { - return nil, err - } - - cwClient := cwclient.NewClient(babylonClient.QueryClient.RPCClient, config.ContractAddr) - - return &SdkClient{ - bbnClient: &bbnclient.Client{QueryClient: babylonClient.QueryClient}, - cwClient: cwClient, - btcClient: btcClient, - }, nil -} diff --git a/sdk/config/config.go b/sdk/config/config.go deleted file mode 100644 index 728f546..0000000 --- a/sdk/config/config.go +++ /dev/null @@ -1,41 +0,0 @@ -package config - -import ( - "fmt" - - "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" -) - -const ( - BabylonLocalnet = "chain-test" - BabylonDevnet = "euphrates-0.2.0" -) - -// Config defines configuration for the Babylon query client -type Config struct { - BTCConfig *btcclient.BTCConfig - ContractAddr string // CosmWasm contract address - // TODO: add Config.Validate() to query chain ID (i.e. /status) from RPCAddr and compare - ChainID string // Chain ID of the Babylon chain (e.g. devnet, testnet, mainnet) - RPCAddr string // RPC address of the Babylon chain -} - -func (config *Config) GetRpcAddr() (string, error) { - if config.RPCAddr != "" { - return config.RPCAddr, nil - } - return config.getDefaultRpcAddr() -} - -func (config *Config) getDefaultRpcAddr() (string, error) { - switch config.ChainID { - case BabylonLocalnet: - // for the e2e test - return "http://127.0.0.1:26657", nil - case BabylonDevnet: - return "https://rpc-euphrates.devnet.babylonchain.io/", nil - // TODO: add mainnet RPCs when available - default: - return "", fmt.Errorf("unrecognized chain id: %s", config.ChainID) - } -} diff --git a/sdk/cwclient/types.go b/sdk/cwclient/types.go deleted file mode 100644 index aee5073..0000000 --- a/sdk/cwclient/types.go +++ /dev/null @@ -1,7 +0,0 @@ -package cwclient - -type L2Block struct { - BlockHash string `mapstructure:"block-hash"` - BlockHeight uint64 `mapstructure:"block-height"` - BlockTimestamp uint64 `mapstructure:"block-timestamp"` -} diff --git a/server/rpcserver.go b/server/rpcserver.go index 543ee74..df1b374 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -5,7 +5,6 @@ import ( "google.golang.org/grpc" - "github.com/babylonlabs-io/finality-gadget/finalitygadget" "github.com/babylonlabs-io/finality-gadget/proto" "github.com/babylonlabs-io/finality-gadget/types" ) @@ -15,12 +14,12 @@ import ( type rpcServer struct { proto.UnimplementedFinalityGadgetServer - fg finalitygadget.IFinalityGadget + fg types.IFinalityGadget } // newRPCServer creates a new RPC sever from the set of input dependencies. func newRPCServer( - fg finalitygadget.IFinalityGadget, + fg types.IFinalityGadget, ) *rpcServer { return &rpcServer{ fg: fg, diff --git a/server/server.go b/server/server.go index 6b3e375..9cd7564 100644 --- a/server/server.go +++ b/server/server.go @@ -7,9 +7,9 @@ import ( "sync" "sync/atomic" + "github.com/babylonlabs-io/finality-gadget/config" "github.com/babylonlabs-io/finality-gadget/db" - "github.com/babylonlabs-io/finality-gadget/finalitygadget" - "github.com/babylonlabs-io/finality-gadget/finalitygadget/config" + "github.com/babylonlabs-io/finality-gadget/types" "github.com/lightningnetwork/lnd/signal" "google.golang.org/grpc" @@ -29,7 +29,7 @@ type Server struct { } // NewEOTSManagerServer creates a new server with the given config. -func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { +func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg types.IFinalityGadget, sig signal.Interceptor) *Server { return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), diff --git a/testutil/mock_btc_client.go b/testutil/mock_btc_client.go index a4a517f..a457f13 100644 --- a/testutil/mock_btc_client.go +++ b/testutil/mock_btc_client.go @@ -1,27 +1,27 @@ package testutil import ( - "github.com/babylonlabs-io/finality-gadget/sdk/btcclient" + "github.com/babylonlabs-io/finality-gadget/btcclient" "github.com/stretchr/testify/mock" "go.uber.org/zap" ) // MockBtcClient is the mock implementation of BtcClient. -type MockBtcClient struct { - *btcclient.BTCClient +type MockBitcoinClient struct { + *btcclient.BitcoinClient mock.Mock } -func NewMockBTCClient(cfg *btcclient.BTCConfig, logger *zap.Logger) (*MockBtcClient, error) { - innerClient, err := btcclient.NewBTCClient(cfg, logger) +func NewMockBitcoinClient(cfg *btcclient.BTCConfig, logger *zap.Logger) (*MockBitcoinClient, error) { + innerClient, err := btcclient.NewBitcoinClient(cfg, logger) - return &MockBtcClient{ - BTCClient: innerClient, + return &MockBitcoinClient{ + BitcoinClient: innerClient, }, err } // GetBlockHeightByTimestamp overrides the BTCClient's GetBlockHeightByTimestamp method. -func (c *MockBtcClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { +func (c *MockBitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { // by default, kValue is 6 and wValue is 20 // // in out test, the two mock delegations has: @@ -37,6 +37,6 @@ func (c *MockBtcClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint6 // this is used to determine when the BTC staking is activated. return 0 to // simulate that the BTC staking is always activated -func (c *MockBtcClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { +func (c *MockBitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { return 0, nil } diff --git a/testutil/mocks/expected_clients_mock.go b/testutil/mocks/external_clients_mock.go similarity index 97% rename from testutil/mocks/expected_clients_mock.go rename to testutil/mocks/external_clients_mock.go index b44c288..374d3ef 100644 --- a/testutil/mocks/expected_clients_mock.go +++ b/testutil/mocks/external_clients_mock.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: sdk/client/expected_clients.go +// Source: types/client_interfaces.go // // Generated by this command: // -// mockgen -source=sdk/client/expected_clients.go -package mocks -destination ./testutil/mocks/expected_clients_mock.go +// mockgen -source=types/external_clients.go -package mocks -destination ./testutil/mocks/external_clients_mock.go // // Package mocks is a generated GoMock package. @@ -12,7 +12,7 @@ package mocks import ( reflect "reflect" - cwclient "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/types" chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" wire "github.com/btcsuite/btcd/wire" gomock "go.uber.org/mock/gomock" @@ -253,7 +253,7 @@ func (mr *MockICosmWasmClientMockRecorder) QueryIsEnabled() *gomock.Call { } // QueryListOfVotedFinalityProviders mocks base method. -func (m *MockICosmWasmClient) QueryListOfVotedFinalityProviders(queryParams *cwclient.L2Block) ([]string, error) { +func (m *MockICosmWasmClient) QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryListOfVotedFinalityProviders", queryParams) ret0, _ := ret[0].([]string) diff --git a/testutil/mocks/sdkclient_mock.go b/testutil/mocks/finalitygadget_mock.go similarity index 92% rename from testutil/mocks/sdkclient_mock.go rename to testutil/mocks/finalitygadget_mock.go index 8ea970d..64c8504 100644 --- a/testutil/mocks/sdkclient_mock.go +++ b/testutil/mocks/finalitygadget_mock.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -source=sdk/client/interface.go -package mocks -destination ./testutil/mocks/sdkclient_mock.go +// mockgen -source=types/finalitygadget.go -package mocks -destination ./testutil/mocks/finalitygadget_mock.go // // Package mocks is a generated GoMock package. @@ -12,7 +12,7 @@ package mocks import ( reflect "reflect" - cwclient "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/types" gomock "go.uber.org/mock/gomock" ) @@ -40,7 +40,7 @@ func (m *MockISdkClient) EXPECT() *MockISdkClientMockRecorder { } // QueryBlockRangeBabylonFinalized mocks base method. -func (m *MockISdkClient) QueryBlockRangeBabylonFinalized(queryBlocks []*cwclient.L2Block) (*uint64, error) { +func (m *MockISdkClient) QueryBlockRangeBabylonFinalized(queryBlocks []*types.Block) (*uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryBlockRangeBabylonFinalized", queryBlocks) ret0, _ := ret[0].(*uint64) @@ -70,7 +70,7 @@ func (mr *MockISdkClientMockRecorder) QueryBtcStakingActivatedTimestamp() *gomoc } // QueryIsBlockBabylonFinalized mocks base method. -func (m *MockISdkClient) QueryIsBlockBabylonFinalized(queryParams cwclient.L2Block) (bool, error) { +func (m *MockISdkClient) QueryIsBlockBabylonFinalized(queryParams types.Block) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryIsBlockBabylonFinalized", queryParams) ret0, _ := ret[0].(bool) diff --git a/testutil/random.go b/testutil/random.go index 3eb3a96..a755e6d 100644 --- a/testutil/random.go +++ b/testutil/random.go @@ -4,7 +4,7 @@ import ( "math/rand" "strings" - "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "github.com/babylonlabs-io/finality-gadget/types" "github.com/ethereum/go-ethereum/common" ) @@ -13,7 +13,7 @@ func RandomHash(rng *rand.Rand) (out common.Hash) { return } -func RandomL2Block(rng *rand.Rand) (out cwclient.L2Block, outWithHashTrimmed cwclient.L2Block) { +func RandomL2Block(rng *rand.Rand) (out types.Block, outWithHashTrimmed types.Block) { out.BlockHash = RandomHash(rng).String() out.BlockHeight = rng.Uint64() out.BlockTimestamp = rng.Uint64() @@ -22,7 +22,7 @@ func RandomL2Block(rng *rand.Rand) (out cwclient.L2Block, outWithHashTrimmed cwc return } -func GenL2Block(rng *rand.Rand, initBlock *cwclient.L2Block, l2BlockTime uint64, offset uint64) (out cwclient.L2Block, outWithHashTrimmed cwclient.L2Block) { +func GenL2Block(rng *rand.Rand, initBlock *types.Block, l2BlockTime uint64, offset uint64) (out types.Block, outWithHashTrimmed types.Block) { out.BlockHash = RandomHash(rng).String() out.BlockHeight = initBlock.BlockHeight + offset out.BlockTimestamp = initBlock.BlockTimestamp + offset*l2BlockTime diff --git a/sdk/client/expected_clients.go b/types/external_clients.go similarity index 75% rename from sdk/client/expected_clients.go rename to types/external_clients.go index 70c8955..68b8674 100644 --- a/sdk/client/expected_clients.go +++ b/types/external_clients.go @@ -1,9 +1,12 @@ -package client +package types import ( - "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" + "context" + "math/big" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" + eth "github.com/ethereum/go-ethereum/core/types" ) type IBabylonClient interface { @@ -22,7 +25,12 @@ type IBitcoinClient interface { } type ICosmWasmClient interface { - QueryListOfVotedFinalityProviders(queryParams *cwclient.L2Block) ([]string, error) + QueryListOfVotedFinalityProviders(queryParams *Block) ([]string, error) QueryConsumerId() (string, error) QueryIsEnabled() (bool, error) } + +type IEthL2Client interface { + HeaderByNumber(ctx context.Context, number *big.Int) (*eth.Header, error) + Close() +} diff --git a/sdk/client/interface.go b/types/finalitygadget.go similarity index 79% rename from sdk/client/interface.go rename to types/finalitygadget.go index 0143fba..a7ecfc0 100644 --- a/sdk/client/interface.go +++ b/types/finalitygadget.go @@ -1,8 +1,6 @@ -package client +package types -import "github.com/babylonlabs-io/finality-gadget/sdk/cwclient" - -type ISdkClient interface { +type IFinalityGadget interface { /* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget * * - if the finality gadget is not enabled, always return true @@ -19,7 +17,7 @@ type ISdkClient interface { * - calculate voted voting power * - check if the voted voting power is more than 2/3 of the total voting power */ - QueryIsBlockBabylonFinalized(queryParams cwclient.L2Block) (bool, error) + QueryIsBlockBabylonFinalized(block *Block) (bool, error) /* QueryBlockRangeBabylonFinalized searches for a row of consecutive finalized blocks in the block range, and returns * the last finalized block height @@ -35,7 +33,7 @@ type ISdkClient interface { * Note: caller needs to make sure the given queryBlocks are consecutive (we don't check hashes inside this method) * and start from low to high */ - QueryBlockRangeBabylonFinalized(queryBlocks []*cwclient.L2Block) (*uint64, error) + QueryBlockRangeBabylonFinalized(queryBlocks []*Block) (*uint64, error) /* QueryBtcStakingActivatedTimestamp returns the timestamp when the BTC staking is activated * @@ -54,4 +52,16 @@ type ISdkClient interface { * returns math.MaxUint64, ErrBtcStakingNotActivated if the BTC staking is not activated */ QueryBtcStakingActivatedTimestamp() (uint64, error) + + // InsertBlock inserts a btc finalized block into the local db + InsertBlock(block *Block) error + + // GetBlockStatusByHeight returns the btc finalization status of a block at given height by querying the local db + GetBlockStatusByHeight(height uint64) (bool, error) + + // GetBlockStatusByHash returns the btc finalization status of a block at given hash by querying the local db + GetBlockStatusByHash(hash string) (bool, error) + + // GetLatestBlock returns the latest finalized block by querying the local db + GetLatestBlock() (*Block, error) } From efe8b24e38c6fdef173b334823cca85d99446c4a Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 12:33:02 +0100 Subject: [PATCH 71/93] test: regenerate mocks --- testutil/mocks/external_clients_mock.go | 57 ++++++++++++- testutil/mocks/finalitygadget_mock.go | 105 ++++++++++++++++++------ 2 files changed, 137 insertions(+), 25 deletions(-) diff --git a/testutil/mocks/external_clients_mock.go b/testutil/mocks/external_clients_mock.go index 374d3ef..ffc5bd0 100644 --- a/testutil/mocks/external_clients_mock.go +++ b/testutil/mocks/external_clients_mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: types/client_interfaces.go +// Source: types/external_clients.go // // Generated by this command: // @@ -10,11 +10,14 @@ package mocks import ( + context "context" + big "math/big" reflect "reflect" - "github.com/babylonlabs-io/finality-gadget/types" + types "github.com/babylonlabs-io/finality-gadget/types" chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" wire "github.com/btcsuite/btcd/wire" + types0 "github.com/ethereum/go-ethereum/core/types" gomock "go.uber.org/mock/gomock" ) @@ -266,3 +269,53 @@ func (mr *MockICosmWasmClientMockRecorder) QueryListOfVotedFinalityProviders(que mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryListOfVotedFinalityProviders", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryListOfVotedFinalityProviders), queryParams) } + +// MockIEthL2Client is a mock of IEthL2Client interface. +type MockIEthL2Client struct { + ctrl *gomock.Controller + recorder *MockIEthL2ClientMockRecorder +} + +// MockIEthL2ClientMockRecorder is the mock recorder for MockIEthL2Client. +type MockIEthL2ClientMockRecorder struct { + mock *MockIEthL2Client +} + +// NewMockIEthL2Client creates a new mock instance. +func NewMockIEthL2Client(ctrl *gomock.Controller) *MockIEthL2Client { + mock := &MockIEthL2Client{ctrl: ctrl} + mock.recorder = &MockIEthL2ClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIEthL2Client) EXPECT() *MockIEthL2ClientMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockIEthL2Client) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockIEthL2ClientMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIEthL2Client)(nil).Close)) +} + +// HeaderByNumber mocks base method. +func (m *MockIEthL2Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types0.Header, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeaderByNumber", ctx, number) + ret0, _ := ret[0].(*types0.Header) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeaderByNumber indicates an expected call of HeaderByNumber. +func (mr *MockIEthL2ClientMockRecorder) HeaderByNumber(ctx, number any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByNumber", reflect.TypeOf((*MockIEthL2Client)(nil).HeaderByNumber), ctx, number) +} diff --git a/testutil/mocks/finalitygadget_mock.go b/testutil/mocks/finalitygadget_mock.go index 64c8504..7defdd9 100644 --- a/testutil/mocks/finalitygadget_mock.go +++ b/testutil/mocks/finalitygadget_mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: sdk/client/interface.go +// Source: types/finalitygadget.go // // Generated by this command: // @@ -12,35 +12,94 @@ package mocks import ( reflect "reflect" - "github.com/babylonlabs-io/finality-gadget/types" + types "github.com/babylonlabs-io/finality-gadget/types" gomock "go.uber.org/mock/gomock" ) -// MockISdkClient is a mock of ISdkClient interface. -type MockISdkClient struct { +// MockIFinalityGadget is a mock of IFinalityGadget interface. +type MockIFinalityGadget struct { ctrl *gomock.Controller - recorder *MockISdkClientMockRecorder + recorder *MockIFinalityGadgetMockRecorder } -// MockISdkClientMockRecorder is the mock recorder for MockISdkClient. -type MockISdkClientMockRecorder struct { - mock *MockISdkClient +// MockIFinalityGadgetMockRecorder is the mock recorder for MockIFinalityGadget. +type MockIFinalityGadgetMockRecorder struct { + mock *MockIFinalityGadget } -// NewMockISdkClient creates a new mock instance. -func NewMockISdkClient(ctrl *gomock.Controller) *MockISdkClient { - mock := &MockISdkClient{ctrl: ctrl} - mock.recorder = &MockISdkClientMockRecorder{mock} +// NewMockIFinalityGadget creates a new mock instance. +func NewMockIFinalityGadget(ctrl *gomock.Controller) *MockIFinalityGadget { + mock := &MockIFinalityGadget{ctrl: ctrl} + mock.recorder = &MockIFinalityGadgetMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockISdkClient) EXPECT() *MockISdkClientMockRecorder { +func (m *MockIFinalityGadget) EXPECT() *MockIFinalityGadgetMockRecorder { return m.recorder } +// GetBlockStatusByHash mocks base method. +func (m *MockIFinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockStatusByHash", hash) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockStatusByHash indicates an expected call of GetBlockStatusByHash. +func (mr *MockIFinalityGadgetMockRecorder) GetBlockStatusByHash(hash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHash", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockStatusByHash), hash) +} + +// GetBlockStatusByHeight mocks base method. +func (m *MockIFinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockStatusByHeight", height) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockStatusByHeight indicates an expected call of GetBlockStatusByHeight. +func (mr *MockIFinalityGadgetMockRecorder) GetBlockStatusByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHeight", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockStatusByHeight), height) +} + +// GetLatestBlock mocks base method. +func (m *MockIFinalityGadget) GetLatestBlock() (*types.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLatestBlock") + ret0, _ := ret[0].(*types.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLatestBlock indicates an expected call of GetLatestBlock. +func (mr *MockIFinalityGadgetMockRecorder) GetLatestBlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestBlock", reflect.TypeOf((*MockIFinalityGadget)(nil).GetLatestBlock)) +} + +// InsertBlock mocks base method. +func (m *MockIFinalityGadget) InsertBlock(block *types.Block) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InsertBlock", block) + ret0, _ := ret[0].(error) + return ret0 +} + +// InsertBlock indicates an expected call of InsertBlock. +func (mr *MockIFinalityGadgetMockRecorder) InsertBlock(block any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockIFinalityGadget)(nil).InsertBlock), block) +} + // QueryBlockRangeBabylonFinalized mocks base method. -func (m *MockISdkClient) QueryBlockRangeBabylonFinalized(queryBlocks []*types.Block) (*uint64, error) { +func (m *MockIFinalityGadget) QueryBlockRangeBabylonFinalized(queryBlocks []*types.Block) (*uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryBlockRangeBabylonFinalized", queryBlocks) ret0, _ := ret[0].(*uint64) @@ -49,13 +108,13 @@ func (m *MockISdkClient) QueryBlockRangeBabylonFinalized(queryBlocks []*types.Bl } // QueryBlockRangeBabylonFinalized indicates an expected call of QueryBlockRangeBabylonFinalized. -func (mr *MockISdkClientMockRecorder) QueryBlockRangeBabylonFinalized(queryBlocks any) *gomock.Call { +func (mr *MockIFinalityGadgetMockRecorder) QueryBlockRangeBabylonFinalized(queryBlocks any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBlockRangeBabylonFinalized", reflect.TypeOf((*MockISdkClient)(nil).QueryBlockRangeBabylonFinalized), queryBlocks) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBlockRangeBabylonFinalized", reflect.TypeOf((*MockIFinalityGadget)(nil).QueryBlockRangeBabylonFinalized), queryBlocks) } // QueryBtcStakingActivatedTimestamp mocks base method. -func (m *MockISdkClient) QueryBtcStakingActivatedTimestamp() (uint64, error) { +func (m *MockIFinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryBtcStakingActivatedTimestamp") ret0, _ := ret[0].(uint64) @@ -64,22 +123,22 @@ func (m *MockISdkClient) QueryBtcStakingActivatedTimestamp() (uint64, error) { } // QueryBtcStakingActivatedTimestamp indicates an expected call of QueryBtcStakingActivatedTimestamp. -func (mr *MockISdkClientMockRecorder) QueryBtcStakingActivatedTimestamp() *gomock.Call { +func (mr *MockIFinalityGadgetMockRecorder) QueryBtcStakingActivatedTimestamp() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBtcStakingActivatedTimestamp", reflect.TypeOf((*MockISdkClient)(nil).QueryBtcStakingActivatedTimestamp)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBtcStakingActivatedTimestamp", reflect.TypeOf((*MockIFinalityGadget)(nil).QueryBtcStakingActivatedTimestamp)) } // QueryIsBlockBabylonFinalized mocks base method. -func (m *MockISdkClient) QueryIsBlockBabylonFinalized(queryParams types.Block) (bool, error) { +func (m *MockIFinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryIsBlockBabylonFinalized", queryParams) + ret := m.ctrl.Call(m, "QueryIsBlockBabylonFinalized", block) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } // QueryIsBlockBabylonFinalized indicates an expected call of QueryIsBlockBabylonFinalized. -func (mr *MockISdkClientMockRecorder) QueryIsBlockBabylonFinalized(queryParams any) *gomock.Call { +func (mr *MockIFinalityGadgetMockRecorder) QueryIsBlockBabylonFinalized(block any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockBabylonFinalized", reflect.TypeOf((*MockISdkClient)(nil).QueryIsBlockBabylonFinalized), queryParams) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockBabylonFinalized", reflect.TypeOf((*MockIFinalityGadget)(nil).QueryIsBlockBabylonFinalized), block) } From 57516df656485816b5ba33fa439090526e0b4edd Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 13:41:47 +0100 Subject: [PATCH 72/93] chore: cleanup code and standardise client format --- bbnclient/bbnclient.go | 72 +++- bbnclient/interface.go | 8 + bbnclient/query_internal.go | 54 --- btcclient/btcclient.go | 15 +- btcclient/{btcconfig.go => config.go} | 0 btcclient/interface.go | 14 + client/rpcclient.go | 4 +- cmd/opfgd/start.go | 2 +- cwclient/cwclient.go | 97 +++++- cwclient/interface.go | 9 + cwclient/query_internal.go | 86 ----- db/bbolt.go | 32 +- db/bbolt_test.go | 2 +- db/interface.go | 14 + ethl2client/ethl2client.go | 43 +++ ethl2client/interface.go | 13 + finalitygadget/finalitygadget.go | 323 +++++++++++++++--- .../interface.go | 12 +- finalitygadget/query.go | 231 ------------- finalitygadget/utils.go | 7 - server/rpcserver.go | 5 +- server/server.go | 6 +- types/external_clients.go | 36 -- 23 files changed, 600 insertions(+), 485 deletions(-) create mode 100644 bbnclient/interface.go delete mode 100644 bbnclient/query_internal.go rename btcclient/{btcconfig.go => config.go} (100%) create mode 100644 btcclient/interface.go create mode 100644 cwclient/interface.go delete mode 100644 cwclient/query_internal.go create mode 100644 db/interface.go create mode 100644 ethl2client/ethl2client.go create mode 100644 ethl2client/interface.go rename types/finalitygadget.go => finalitygadget/interface.go (91%) delete mode 100644 finalitygadget/query.go delete mode 100644 finalitygadget/utils.go delete mode 100644 types/external_clients.go diff --git a/bbnclient/bbnclient.go b/bbnclient/bbnclient.go index e8d1b30..64b41f2 100644 --- a/bbnclient/bbnclient.go +++ b/bbnclient/bbnclient.go @@ -5,7 +5,6 @@ import ( "github.com/babylonlabs-io/babylon/client/query" bbntypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/babylonlabs-io/finality-gadget/types" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) @@ -13,7 +12,21 @@ type BabylonClient struct { *query.QueryClient } -var _ types.IBabylonClient = &BabylonClient{} +var _ IBabylonClient = &BabylonClient{} + +////////////////////////////// +// CONSTRUCTOR +////////////////////////////// + +func NewBabylonClient(queryClient *query.QueryClient) *BabylonClient { + return &BabylonClient{ + QueryClient: queryClient, + } +} + +////////////////////////////// +// METHODS +////////////////////////////// func (bbnClient *BabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { pagination := &sdkquerytypes.PageRequest{} @@ -147,6 +160,61 @@ func (bbnClient *BabylonClient) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex st return earliestBtcHeight, nil } +////////////////////////////// +// INTERNAL +////////////////////////////// + +// we implemented exact logic as in GetStatus +// https://github.com/babylonlabs-io/babylon-private/blob/3d8f190c9b0c0795f6546806e3b8582de716cd60/x/btcstaking/types/btc_delegation.go#L90-L111 +func (bbnClient *BabylonClient) isDelegationActive( + btcDel *bbntypes.BTCDelegationResponse, + btcHeight uint64, +) (bool, error) { + btccheckpointParams, err := bbnClient.QueryClient.BTCCheckpointParams() + if err != nil { + return false, err + } + btcstakingParams, err := bbnClient.QueryClient.BTCStakingParams() + if err != nil { + return false, err + } + kValue := btccheckpointParams.GetParams().BtcConfirmationDepth + wValue := btccheckpointParams.GetParams().CheckpointFinalizationTimeout + covQuorum := btcstakingParams.GetParams().CovenantQuorum + ud := btcDel.UndelegationResponse + + if len(ud.GetDelegatorUnbondingSigHex()) > 0 { + return false, nil + } + + // k is not involved in the `GetStatus` logic as Babylon will accept a BTC delegation request + // only when staking tx is k-deep on BTC. + // + // But the msg handler performs both checks 1) ensure staking tx is k-deep, and 2) ensure the + // staking tx's timelock has at least w BTC blocks left. + // (https://github.com/babylonlabs-io/babylon-private/blob/3d8f190c9b0c0795f6546806e3b8582de716cd60/x/btcstaking/keeper/msg_server.go#L283-L292) + // + // So after the msg handler accepts BTC delegation the 1st check is no longer needed + // the k-value check is added per + // + // So in our case, we need to check both to ensure the delegation is active + if btcHeight < btcDel.StartHeight+kValue || btcHeight+wValue > btcDel.EndHeight { + return false, nil + } + + if uint32(len(btcDel.CovenantSigs)) < covQuorum { + return false, nil + } + if len(ud.CovenantUnbondingSigList) < int(covQuorum) { + return false, nil + } + if len(ud.CovenantSlashingSigs) < int(covQuorum) { + return false, nil + } + + return true, nil +} + // The active delegation needs to satisfy: // 1) the staking tx is k-deep in Bitcoin, i.e., start_height + k // 2) it receives a quorum number of covenant committee signatures diff --git a/bbnclient/interface.go b/bbnclient/interface.go new file mode 100644 index 0000000..f22b492 --- /dev/null +++ b/bbnclient/interface.go @@ -0,0 +1,8 @@ +package bbnclient + +type IBabylonClient interface { + QueryAllFpBtcPubKeys(consumerId string) ([]string, error) + QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) + QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) + QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) +} diff --git a/bbnclient/query_internal.go b/bbnclient/query_internal.go deleted file mode 100644 index b017eb2..0000000 --- a/bbnclient/query_internal.go +++ /dev/null @@ -1,54 +0,0 @@ -package bbnclient - -import btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" - -// we implemented exact logic as in GetStatus -// https://github.com/babylonlabs-io/babylon-private/blob/3d8f190c9b0c0795f6546806e3b8582de716cd60/x/btcstaking/types/btc_delegation.go#L90-L111 -func (bbnClient *BabylonClient) isDelegationActive( - btcDel *btcstakingtypes.BTCDelegationResponse, - btcHeight uint64, -) (bool, error) { - btccheckpointParams, err := bbnClient.QueryClient.BTCCheckpointParams() - if err != nil { - return false, err - } - btcstakingParams, err := bbnClient.QueryClient.BTCStakingParams() - if err != nil { - return false, err - } - kValue := btccheckpointParams.GetParams().BtcConfirmationDepth - wValue := btccheckpointParams.GetParams().CheckpointFinalizationTimeout - covQuorum := btcstakingParams.GetParams().CovenantQuorum - ud := btcDel.UndelegationResponse - - if len(ud.GetDelegatorUnbondingSigHex()) > 0 { - return false, nil - } - - // k is not involved in the `GetStatus` logic as Babylon will accept a BTC delegation request - // only when staking tx is k-deep on BTC. - // - // But the msg handler performs both checks 1) ensure staking tx is k-deep, and 2) ensure the - // staking tx's timelock has at least w BTC blocks left. - // (https://github.com/babylonlabs-io/babylon-private/blob/3d8f190c9b0c0795f6546806e3b8582de716cd60/x/btcstaking/keeper/msg_server.go#L283-L292) - // - // So after the msg handler accepts BTC delegation the 1st check is no longer needed - // the k-value check is added per - // - // So in our case, we need to check both to ensure the delegation is active - if btcHeight < btcDel.StartHeight+kValue || btcHeight+wValue > btcDel.EndHeight { - return false, nil - } - - if uint32(len(btcDel.CovenantSigs)) < covQuorum { - return false, nil - } - if len(ud.CovenantUnbondingSigList) < int(covQuorum) { - return false, nil - } - if len(ud.CovenantSlashingSigs) < int(covQuorum) { - return false, nil - } - - return true, nil -} diff --git a/btcclient/btcclient.go b/btcclient/btcclient.go index f736aff..1021d64 100644 --- a/btcclient/btcclient.go +++ b/btcclient/btcclient.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/avast/retry-go/v4" - "github.com/babylonlabs-io/finality-gadget/types" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/wire" @@ -17,7 +16,11 @@ type BitcoinClient struct { cfg *BTCConfig } -var _ types.IBitcoinClient = &BitcoinClient{} +var _ IBitcoinClient = &BitcoinClient{} + +////////////////////////////// +// CONSTRUCTOR +////////////////////////////// func NewBitcoinClient(cfg *BTCConfig, logger *zap.Logger) (*BitcoinClient, error) { c, err := rpcclient.New(cfg.ToConnConfig(), nil) @@ -32,6 +35,10 @@ func NewBitcoinClient(cfg *BTCConfig, logger *zap.Logger) (*BitcoinClient, error }, nil } +////////////////////////////// +// METHODS +////////////////////////////// + type BlockCountResponse struct { count int64 } @@ -132,6 +139,10 @@ func (c *BitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) return uint64(blockHeader.Timestamp.Unix()), nil } +////////////////////////////// +// INTERNAL +////////////////////////////// + func clientCallWithRetry[T any]( call retry.RetryableFuncWithData[*T], logger *zap.Logger, cfg *BTCConfig, ) (*T, error) { diff --git a/btcclient/btcconfig.go b/btcclient/config.go similarity index 100% rename from btcclient/btcconfig.go rename to btcclient/config.go diff --git a/btcclient/interface.go b/btcclient/interface.go new file mode 100644 index 0000000..4d2ad7b --- /dev/null +++ b/btcclient/interface.go @@ -0,0 +1,14 @@ +package btcclient + +import ( + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" +) + +type IBitcoinClient interface { + GetBlockCount() (uint64, error) + GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) + GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) + GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) + GetBlockTimestampByHeight(height uint64) (uint64, error) +} diff --git a/client/rpcclient.go b/client/rpcclient.go index 356ea6d..d56cea2 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -14,11 +14,11 @@ import ( type FinalityGadgetGrpcClient struct { client proto.FinalityGadgetClient conn *grpc.ClientConn - db *db.BBoltHandler + db db.IDatabaseHandler } func NewFinalityGadgetGrpcClient( - db *db.BBoltHandler, + db db.IDatabaseHandler, remoteAddr string, ) (*FinalityGadgetGrpcClient, error) { conn, err := grpc.NewClient(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) diff --git a/cmd/opfgd/start.go b/cmd/opfgd/start.go index 1b97fb6..35c4b76 100644 --- a/cmd/opfgd/start.go +++ b/cmd/opfgd/start.go @@ -53,7 +53,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to create DB handler: %w", err) } defer db.Close() - err = db.TryCreateInitialBuckets() + err = db.CreateInitialSchema() if err != nil { return fmt.Errorf("create initial buckets error: %w", err) } diff --git a/cwclient/cwclient.go b/cwclient/cwclient.go index 8091a52..a4646a8 100644 --- a/cwclient/cwclient.go +++ b/cwclient/cwclient.go @@ -1,10 +1,14 @@ package cwclient import ( + "context" "encoding/json" + "time" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/babylonlabs-io/finality-gadget/types" rpcclient "github.com/cometbft/cometbft/rpc/client" + cosmosclient "github.com/cosmos/cosmos-sdk/client" ) type CosmWasmClient struct { @@ -12,15 +16,28 @@ type CosmWasmClient struct { contractAddr string } -var _ types.ICosmWasmClient = &CosmWasmClient{} +var _ ICosmWasmClient = &CosmWasmClient{} -func NewClient(rpcClient rpcclient.Client, contractAddr string) *CosmWasmClient { +const ( + // hardcode the timeout to 20 seconds. We can expose it to the params once needed + DefaultTimeout = 20 * time.Second +) + +////////////////////////////// +// CONSTRUCTOR +////////////////////////////// + +func NewCosmWasmClient(rpcClient rpcclient.Client, contractAddr string) *CosmWasmClient { return &CosmWasmClient{ Client: rpcClient, contractAddr: contractAddr, } } +////////////////////////////// +// METHODS +////////////////////////////// + func (cwClient *CosmWasmClient) QueryListOfVotedFinalityProviders( queryParams *types.Block, ) ([]string, error) { @@ -79,3 +96,79 @@ func (cwClient *CosmWasmClient) QueryIsEnabled() (bool, error) { return isEnabled, nil } + +////////////////////////////// +// INTERNAL +////////////////////////////// + +func createBlockVotersQueryData(queryParams *types.Block) ([]byte, error) { + queryData := ContractQueryMsgs{ + BlockVoters: &blockVotersQuery{ + Height: queryParams.BlockHeight, + Hash: queryParams.BlockHash, + }, + } + data, err := json.Marshal(queryData) + if err != nil { + return nil, err + } + return data, nil +} + +type contractConfigResponse struct { + ConsumerId string `json:"consumer_id"` + ActivatedHeight uint64 `json:"activated_height"` +} +type ContractQueryMsgs struct { + Config *contractConfig `json:"config,omitempty"` + BlockVoters *blockVotersQuery `json:"block_voters,omitempty"` + IsEnabled *isEnabledQuery `json:"is_enabled,omitempty"` +} + +type blockVotersQuery struct { + Hash string `json:"hash"` + Height uint64 `json:"height"` +} + +type isEnabledQuery struct{} + +type contractConfig struct{} + +func createConfigQueryData() ([]byte, error) { + queryData := ContractQueryMsgs{ + Config: &contractConfig{}, + } + data, err := json.Marshal(queryData) + if err != nil { + return nil, err + } + return data, nil +} + +func createIsEnabledQueryData() ([]byte, error) { + queryData := ContractQueryMsgs{ + IsEnabled: &isEnabledQuery{}, + } + data, err := json.Marshal(queryData) + if err != nil { + return nil, err + } + return data, nil +} + +// querySmartContractState queries the smart contract state given the contract address and query data +func (cwClient *CosmWasmClient) querySmartContractState( + queryData []byte, +) (*wasmtypes.QuerySmartContractStateResponse, error) { + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + + sdkClientCtx := cosmosclient.Context{Client: cwClient.Client} + wasmQueryClient := wasmtypes.NewQueryClient(sdkClientCtx) + + req := &wasmtypes.QuerySmartContractStateRequest{ + Address: cwClient.contractAddr, + QueryData: queryData, + } + return wasmQueryClient.SmartContractState(ctx, req) +} diff --git a/cwclient/interface.go b/cwclient/interface.go new file mode 100644 index 0000000..841a146 --- /dev/null +++ b/cwclient/interface.go @@ -0,0 +1,9 @@ +package cwclient + +import "github.com/babylonlabs-io/finality-gadget/types" + +type ICosmWasmClient interface { + QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) + QueryConsumerId() (string, error) + QueryIsEnabled() (bool, error) +} diff --git a/cwclient/query_internal.go b/cwclient/query_internal.go deleted file mode 100644 index 0bd5bde..0000000 --- a/cwclient/query_internal.go +++ /dev/null @@ -1,86 +0,0 @@ -package cwclient - -import ( - "context" - "encoding/json" - "time" - - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - "github.com/babylonlabs-io/finality-gadget/types" - cosmosclient "github.com/cosmos/cosmos-sdk/client" -) - -// hardcode the timeout to 20 seconds. We can expose it to the params once needed -const DefaultTimeout = 20 * time.Second - -func createBlockVotersQueryData(queryParams *types.Block) ([]byte, error) { - queryData := ContractQueryMsgs{ - BlockVoters: &blockVotersQuery{ - Height: queryParams.BlockHeight, - Hash: queryParams.BlockHash, - }, - } - data, err := json.Marshal(queryData) - if err != nil { - return nil, err - } - return data, nil -} - -type contractConfigResponse struct { - ConsumerId string `json:"consumer_id"` - ActivatedHeight uint64 `json:"activated_height"` -} -type ContractQueryMsgs struct { - Config *contractConfig `json:"config,omitempty"` - BlockVoters *blockVotersQuery `json:"block_voters,omitempty"` - IsEnabled *isEnabledQuery `json:"is_enabled,omitempty"` -} - -type blockVotersQuery struct { - Hash string `json:"hash"` - Height uint64 `json:"height"` -} - -type isEnabledQuery struct{} - -type contractConfig struct{} - -func createConfigQueryData() ([]byte, error) { - queryData := ContractQueryMsgs{ - Config: &contractConfig{}, - } - data, err := json.Marshal(queryData) - if err != nil { - return nil, err - } - return data, nil -} - -func createIsEnabledQueryData() ([]byte, error) { - queryData := ContractQueryMsgs{ - IsEnabled: &isEnabledQuery{}, - } - data, err := json.Marshal(queryData) - if err != nil { - return nil, err - } - return data, nil -} - -// querySmartContractState queries the smart contract state given the contract address and query data -func (cwClient *CosmWasmClient) querySmartContractState( - queryData []byte, -) (*wasmtypes.QuerySmartContractStateResponse, error) { - ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) - defer cancel() - - sdkClientCtx := cosmosclient.Context{Client: cwClient.Client} - wasmQueryClient := wasmtypes.NewQueryClient(sdkClientCtx) - - req := &wasmtypes.QuerySmartContractStateRequest{ - Address: cwClient.contractAddr, - QueryData: queryData, - } - return wasmQueryClient.SmartContractState(ctx, req) -} diff --git a/db/bbolt.go b/db/bbolt.go index c2b480c..6104ddd 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -19,6 +19,8 @@ type BBoltHandler struct { db *bolt.DB } +var _ IDatabaseHandler = &BBoltHandler{} + const ( blocksBucket = "blocks" blockHeightsBucket = "block_heights" @@ -30,6 +32,10 @@ var ( ErrBlockNotFound = errors.New("block not found") ) +////////////////////////////// +// CONSTRUCTOR +////////////////////////////// + func NewBBoltHandler(path string) (*BBoltHandler, error) { // 0600 = read/write permission for owner only db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second}) @@ -43,7 +49,11 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { }, nil } -func (bb *BBoltHandler) TryCreateInitialBuckets() error { +////////////////////////////// +// METHODS +////////////////////////////// + +func (bb *BBoltHandler) CreateInitialSchema() error { log.Printf("Initialising DB...") return bb.db.Update(func(tx *bolt.Tx) error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} @@ -56,14 +66,6 @@ func (bb *BBoltHandler) TryCreateInitialBuckets() error { }) } -func tryCreateBucket(tx *bolt.Tx, bucketName string) error { - _, err := tx.CreateBucketIfNotExists([]byte(bucketName)) - if err != nil { - log.Fatalf("Error creating bucket: %v\n", err) - } - return err -} - func (bb *BBoltHandler) InsertBlock(block *types.Block) error { log.Printf("Inserting block %d to DB...\n", block.BlockHeight) @@ -212,6 +214,18 @@ func (bb *BBoltHandler) Close() error { return bb.db.Close() } +////////////////////////////// +// INTERNAL +////////////////////////////// + +func tryCreateBucket(tx *bolt.Tx, bucketName string) error { + _, err := tx.CreateBucketIfNotExists([]byte(bucketName)) + if err != nil { + log.Fatalf("Error creating bucket: %v\n", err) + } + return err +} + func itob(v uint64) []byte { buf := new(bytes.Buffer) err := binary.Write(buf, binary.BigEndian, v) diff --git a/db/bbolt_test.go b/db/bbolt_test.go index e4d8ba1..ab8d4f7 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -23,7 +23,7 @@ func setupDB(t *testing.T) (*BBoltHandler, func()) { } // Create initial buckets - err = db.TryCreateInitialBuckets() + err = db.CreateInitialSchema() if err != nil { t.Fatalf("Failed to create initial buckets: %v", err) } diff --git a/db/interface.go b/db/interface.go new file mode 100644 index 0000000..0314809 --- /dev/null +++ b/db/interface.go @@ -0,0 +1,14 @@ +package db + +import "github.com/babylonlabs-io/finality-gadget/types" + +type IDatabaseHandler interface { + CreateInitialSchema() error + InsertBlock(block *types.Block) error + GetBlockByHeight(height uint64) (*types.Block, error) + GetBlockStatusByHeight(height uint64) (bool, error) + GetBlockStatusByHash(hash string) (bool, error) + GetLatestBlock() (*types.Block, error) + DeleteDB() error + Close() error +} diff --git a/ethl2client/ethl2client.go b/ethl2client/ethl2client.go new file mode 100644 index 0000000..c9e7936 --- /dev/null +++ b/ethl2client/ethl2client.go @@ -0,0 +1,43 @@ +package ethl2client + +import ( + "context" + "fmt" + "math/big" + + eth "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" +) + +var _ IEthL2Client = &EthL2Client{} + +type EthL2Client struct { + client *ethclient.Client +} + +////////////////////////////// +// CONSTRUCTOR +////////////////////////////// + +func NewEthL2Client(rpcHostAddr string) (*EthL2Client, error) { + l2Client, err := ethclient.Dial(rpcHostAddr) + if err != nil { + return nil, fmt.Errorf("failed to create ETH L2 client: %w", err) + } + + return &EthL2Client{ + client: l2Client, + }, nil +} + +////////////////////////////// +// METHODS +////////////////////////////// + +func (c *EthL2Client) HeaderByNumber(ctx context.Context, number *big.Int) (*eth.Header, error) { + return c.client.HeaderByNumber(ctx, number) +} + +func (c *EthL2Client) Close() { + c.client.Close() +} diff --git a/ethl2client/interface.go b/ethl2client/interface.go new file mode 100644 index 0000000..e5e8126 --- /dev/null +++ b/ethl2client/interface.go @@ -0,0 +1,13 @@ +package ethl2client + +import ( + "context" + "math/big" + + eth "github.com/ethereum/go-ethereum/core/types" +) + +type IEthL2Client interface { + HeaderByNumber(ctx context.Context, number *big.Int) (*eth.Header, error) + Close() +} diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 7ea4aec..271fd68 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -2,8 +2,12 @@ package finalitygadget import ( "context" + "encoding/hex" "fmt" "log" + "math" + "math/big" + "strings" "sync" "time" @@ -14,29 +18,34 @@ import ( "github.com/babylonlabs-io/finality-gadget/config" "github.com/babylonlabs-io/finality-gadget/cwclient" "github.com/babylonlabs-io/finality-gadget/db" + "github.com/babylonlabs-io/finality-gadget/ethl2client" "github.com/babylonlabs-io/finality-gadget/testutil" "github.com/babylonlabs-io/finality-gadget/types" - "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/common" + ethrpc "github.com/ethereum/go-ethereum/rpc" "go.uber.org/zap" ) -var _ types.IFinalityGadget = &FinalityGadget{} +var _ IFinalityGadget = &FinalityGadget{} type FinalityGadget struct { - btcClient types.IBitcoinClient - bbnClient types.IBabylonClient - cwClient types.ICosmWasmClient - l2Client *ethclient.Client + btcClient btcclient.IBitcoinClient + bbnClient bbnclient.IBabylonClient + cwClient cwclient.ICosmWasmClient + l2Client ethl2client.IEthL2Client - db *db.BBoltHandler + db db.IDatabaseHandler mutex sync.Mutex pollInterval time.Duration - startHeight uint64 currHeight uint64 } -func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget, error) { +////////////////////////////// +// CONSTRUCTOR +////////////////////////////// + +func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler) (*FinalityGadget, error) { // Create logger logger, err := zap.NewProduction() if err != nil { @@ -46,7 +55,7 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget // Create bitcoin client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost - var btcClient types.IBitcoinClient + var btcClient btcclient.IBitcoinClient // Create BTC client switch cfg.BBNChainID { // TODO: once we set up our own local BTC devnet, we don't need to use this mock BTC client @@ -67,23 +76,24 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget &bbnConfig, logger, ) + bbnClient := bbnclient.NewBabylonClient(babylonClient.QueryClient) if err != nil { return nil, fmt.Errorf("failed to create Babylon client: %w", err) } // Create cosmwasm client - cwClient := cwclient.NewClient(babylonClient.QueryClient.RPCClient, cfg.FGContractAddress) + cwClient := cwclient.NewCosmWasmClient(babylonClient.QueryClient.RPCClient, cfg.FGContractAddress) // Create L2 client - l2Client, err := ethclient.Dial(cfg.L2RPCHost) + l2Client, err := ethl2client.NewEthL2Client(cfg.L2RPCHost) if err != nil { - return nil, fmt.Errorf("failed to create OPStack L2 client: %w", err) + return nil, err } // Create finality gadget return &FinalityGadget{ btcClient: btcClient, - bbnClient: &bbnclient.BabylonClient{QueryClient: babylonClient.QueryClient}, + bbnClient: bbnClient, cwClient: cwClient, l2Client: l2Client, db: db, @@ -91,6 +101,195 @@ func NewFinalityGadget(cfg *config.Config, db *db.BBoltHandler) (*FinalityGadget }, nil } +////////////////////////////// +// METHODS +////////////////////////////// + +/* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget + * + * - if the finality gadget is not enabled, always return true + * - else, check if the given L2 block is finalized + * - return true if finalized, false if not finalized, and error if any + * + * - to check if the block is finalized, we need to: + * - get the consumer chain id + * - get all the FPs pubkey for the consumer chain + * - convert the L2 block timestamp to BTC height + * - get all FPs voting power at this BTC height + * - calculate total voting power + * - get all FPs that voted this L2 block with the same height and hash + * - calculate voted voting power + * - check if the voted voting power is more than 2/3 of the total voting power + */ +func (fg *FinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool, error) { + // check if the finality gadget is enabled + // if not, always return true to pass through op derivation pipeline + isEnabled, err := fg.cwClient.QueryIsEnabled() + if err != nil { + return false, err + } + if !isEnabled { + return true, nil + } + + // trim prefix 0x for the L2 block hash + block.BlockHash = strings.TrimPrefix(block.BlockHash, "0x") + + // get all FPs pubkey for the consumer chain + allFpPks, err := fg.queryAllFpBtcPubKeys() + if err != nil { + return false, err + } + + // convert the L2 timestamp to BTC height + btcblockHeight, err := fg.btcClient.GetBlockHeightByTimestamp(block.BlockTimestamp) + if err != nil { + return false, err + } + + // check whether the btc staking is actived + earliestDelHeight, err := fg.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) + if err != nil { + return false, err + } + if btcblockHeight < earliestDelHeight { + return false, ErrBtcStakingNotActivated + } + + // get all FPs voting power at this BTC height + allFpPower, err := fg.bbnClient.QueryMultiFpPower(allFpPks, btcblockHeight) + if err != nil { + return false, err + } + + // calculate total voting power + var totalPower uint64 = 0 + for _, power := range allFpPower { + totalPower += power + } + + // no FP has voting power for the consumer chain + if totalPower == 0 { + return false, ErrNoFpHasVotingPower + } + + // get all FPs that voted this (L2 block height, L2 block hash) combination + votedFpPks, err := fg.cwClient.QueryListOfVotedFinalityProviders(block) + if err != nil { + return false, err + } + if votedFpPks == nil { + return false, nil + } + // calculate voted voting power + var votedPower uint64 = 0 + for _, key := range votedFpPks { + if power, exists := allFpPower[key]; exists { + votedPower += power + } + } + + // quorom < 2/3 + if votedPower*3 < totalPower*2 { + return false, nil + } + return true, nil +} + +/* QueryBlockRangeBabylonFinalized searches for a row of consecutive finalized blocks in the block range, and returns + * the last finalized block height + * + * Example: if give block range 1-10, and block 1-5 are finalized, and block 6-10 are not finalized, then return 5 + * + * - if no block in the range is finalized, return (nil, nil) + * - else, return the height of the last found consecutive finalized block, return error if any + * + * Example: if give block range 1-10, and block 1-5 are finalized, and when querying block 6 we meet an error, then + * return (5, error) + * + * Note: caller needs to make sure the given queryBlocks are consecutive (we don't check hashes inside this method) + * and start from low to high + */ +func (fg *FinalityGadget) QueryBlockRangeBabylonFinalized( + queryBlocks []*types.Block, +) (*uint64, error) { + if len(queryBlocks) == 0 { + return nil, fmt.Errorf("no blocks provided") + } + // check if the blocks are consecutive + for i := 1; i < len(queryBlocks); i++ { + if queryBlocks[i].BlockHeight != queryBlocks[i-1].BlockHeight+1 { + return nil, fmt.Errorf("blocks are not consecutive") + } + } + var finalizedBlockHeight *uint64 + for _, block := range queryBlocks { + isFinalized, err := fg.QueryIsBlockBabylonFinalized(block) + if err != nil { + return finalizedBlockHeight, err + } + if isFinalized { + finalizedBlockHeight = &block.BlockHeight + } else { + break + } + } + return finalizedBlockHeight, nil +} + +/* QueryBtcStakingActivatedTimestamp returns the timestamp when the BTC staking is activated + * + * - We will check for k deep and covenant quorum to mark a delegation as active + * - So technically, activated time needs to be max of the following + * - timestamp of Babylon block that BTC delegation receives covenant quorum + * - timestamp of BTC block that BTC delegation's staking tx becomes k-deep + * - But we don't have a Babylon API to find the earliest Babylon block where BTC delegation gets covenant quorum. + * and it's probably not a good idea to add this to Babylon, as this creates more coupling between Babylon and + * consumer. So waiting for covenant quorum can be implemented in a clean way only with Babylon side support. + * this will be considered as future work + * - For now, we will use the k-deep BTC block timestamp for the activation timestamp + * - The time diff issue is not burning. The time diff between pending and active only matters if FP equivocates + * during that time period + * + * returns math.MaxUint64, ErrBtcStakingNotActivated if the BTC staking is not activated + */ +func (fg *FinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { + allFpPks, err := fg.queryAllFpBtcPubKeys() + if err != nil { + return math.MaxUint64, err + } + + // check whether the btc staking is actived + earliestDelHeight, err := fg.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) + if err != nil { + return math.MaxUint64, err + } + + // not activated yet + if earliestDelHeight == math.MaxUint64 { + return math.MaxUint64, ErrBtcStakingNotActivated + } + + // get the timestamp of the BTC height + btcBlockTimestamp, err := fg.btcClient.GetBlockTimestampByHeight(earliestDelHeight) + if err != nil { + return math.MaxUint64, err + } + return btcBlockTimestamp, nil +} + +func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { + return fg.db.GetBlockStatusByHeight(height) +} + +func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { + return fg.db.GetBlockStatusByHash(normalizeBlockHash(hash)) +} + +func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { + return fg.db.GetLatestBlock() +} + // This function process blocks indefinitely, starting from the last finalized block. func (fg *FinalityGadget) ProcessBlocks(ctx context.Context) error { // Start service at last finalized block @@ -119,6 +318,71 @@ func (fg *FinalityGadget) ProcessBlocks(ctx context.Context) error { } } +func (fg *FinalityGadget) InsertBlock(block *types.Block) error { + // Lock mutex + fg.mutex.Lock() + // Store block in DB + err := fg.db.InsertBlock(&types.Block{ + BlockHeight: block.BlockHeight, + BlockHash: normalizeBlockHash(block.BlockHash), + BlockTimestamp: block.BlockTimestamp, + }) + if err != nil { + return err + } + // Set last finalized block in memory + fg.currHeight = block.BlockHeight + // Unlock mutex + fg.mutex.Unlock() + + return nil +} + +func (fg *FinalityGadget) DeleteDB() error { + return fg.db.DeleteDB() +} + +func (fg *FinalityGadget) Close() { + fg.l2Client.Close() +} + +////////////////////////////// +// INTERNAL +////////////////////////////// + +func (fg *FinalityGadget) queryAllFpBtcPubKeys() ([]string, error) { + // get the consumer chain id + consumerId, err := fg.cwClient.QueryConsumerId() + if err != nil { + return nil, err + } + + // get all the FPs pubkey for the consumer chain + allFpPks, err := fg.bbnClient.QueryAllFpBtcPubKeys(consumerId) + if err != nil { + return nil, err + } + return allFpPks, nil +} + +// Get last btc finalized block +func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { + return fg.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) +} + +// Get block by number +func (fg *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { + header, err := fg.l2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) + if err != nil { + return nil, err + } + return &types.Block{ + BlockHeight: header.Number.Uint64(), + BlockHash: hex.EncodeToString(header.Hash().Bytes()), + BlockTimestamp: header.Time, + }, nil +} + // Start service at last finalized block func (fg *FinalityGadget) startService() error { // Query L2 node for last finalized block @@ -165,8 +429,7 @@ func (fg *FinalityGadget) startService() error { // Start service at block height log.Printf("Starting finality gadget at block %d...\n", block.BlockHeight) - // Set the start block and curr finalized block in memory - fg.startHeight = block.BlockHeight + // Set the curr finalized block in memory fg.currHeight = block.BlockHeight return nil @@ -195,30 +458,6 @@ func (fg *FinalityGadget) handleBlock(block *types.Block) { } } -func (fg *FinalityGadget) InsertBlock(block *types.Block) error { - // Lock mutex - fg.mutex.Lock() - // Store block in DB - err := fg.db.InsertBlock(&types.Block{ - BlockHeight: block.BlockHeight, - BlockHash: normalizeBlockHash(block.BlockHash), - BlockTimestamp: block.BlockTimestamp, - }) - if err != nil { - return err - } - // Set last finalized block in memory - fg.currHeight = block.BlockHeight - // Unlock mutex - fg.mutex.Unlock() - - return nil -} - -func (fg *FinalityGadget) DeleteDB() error { - return fg.db.DeleteDB() -} - -func (fg *FinalityGadget) Close() { - fg.l2Client.Close() +func normalizeBlockHash(hash string) string { + return common.HexToHash(hash).Hex() } diff --git a/types/finalitygadget.go b/finalitygadget/interface.go similarity index 91% rename from types/finalitygadget.go rename to finalitygadget/interface.go index a7ecfc0..93ccaee 100644 --- a/types/finalitygadget.go +++ b/finalitygadget/interface.go @@ -1,4 +1,6 @@ -package types +package finalitygadget + +import "github.com/babylonlabs-io/finality-gadget/types" type IFinalityGadget interface { /* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget @@ -17,7 +19,7 @@ type IFinalityGadget interface { * - calculate voted voting power * - check if the voted voting power is more than 2/3 of the total voting power */ - QueryIsBlockBabylonFinalized(block *Block) (bool, error) + QueryIsBlockBabylonFinalized(block *types.Block) (bool, error) /* QueryBlockRangeBabylonFinalized searches for a row of consecutive finalized blocks in the block range, and returns * the last finalized block height @@ -33,7 +35,7 @@ type IFinalityGadget interface { * Note: caller needs to make sure the given queryBlocks are consecutive (we don't check hashes inside this method) * and start from low to high */ - QueryBlockRangeBabylonFinalized(queryBlocks []*Block) (*uint64, error) + QueryBlockRangeBabylonFinalized(queryBlocks []*types.Block) (*uint64, error) /* QueryBtcStakingActivatedTimestamp returns the timestamp when the BTC staking is activated * @@ -54,7 +56,7 @@ type IFinalityGadget interface { QueryBtcStakingActivatedTimestamp() (uint64, error) // InsertBlock inserts a btc finalized block into the local db - InsertBlock(block *Block) error + InsertBlock(block *types.Block) error // GetBlockStatusByHeight returns the btc finalization status of a block at given height by querying the local db GetBlockStatusByHeight(height uint64) (bool, error) @@ -63,5 +65,5 @@ type IFinalityGadget interface { GetBlockStatusByHash(hash string) (bool, error) // GetLatestBlock returns the latest finalized block by querying the local db - GetLatestBlock() (*Block, error) + GetLatestBlock() (*types.Block, error) } diff --git a/finalitygadget/query.go b/finalitygadget/query.go deleted file mode 100644 index ad0b6a6..0000000 --- a/finalitygadget/query.go +++ /dev/null @@ -1,231 +0,0 @@ -package finalitygadget - -import ( - "context" - "encoding/hex" - "fmt" - "math" - "math/big" - "strings" - - "github.com/babylonlabs-io/finality-gadget/types" - ethrpc "github.com/ethereum/go-ethereum/rpc" -) - -// Get last btc finalized block -func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - return fg.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) -} - -// Get block by number -func (fg *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { - header, err := fg.l2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) - if err != nil { - return nil, err - } - return &types.Block{ - BlockHeight: header.Number.Uint64(), - BlockHash: hex.EncodeToString(header.Hash().Bytes()), - BlockTimestamp: header.Time, - }, nil -} - -/* QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget - * - * - if the finality gadget is not enabled, always return true - * - else, check if the given L2 block is finalized - * - return true if finalized, false if not finalized, and error if any - * - * - to check if the block is finalized, we need to: - * - get the consumer chain id - * - get all the FPs pubkey for the consumer chain - * - convert the L2 block timestamp to BTC height - * - get all FPs voting power at this BTC height - * - calculate total voting power - * - get all FPs that voted this L2 block with the same height and hash - * - calculate voted voting power - * - check if the voted voting power is more than 2/3 of the total voting power - */ -func (fg *FinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - // check if the finality gadget is enabled - // if not, always return true to pass through op derivation pipeline - isEnabled, err := fg.cwClient.QueryIsEnabled() - if err != nil { - return false, err - } - if !isEnabled { - return true, nil - } - - // trim prefix 0x for the L2 block hash - block.BlockHash = strings.TrimPrefix(block.BlockHash, "0x") - - // get all FPs pubkey for the consumer chain - allFpPks, err := fg.queryAllFpBtcPubKeys() - if err != nil { - return false, err - } - - // convert the L2 timestamp to BTC height - btcblockHeight, err := fg.btcClient.GetBlockHeightByTimestamp(block.BlockTimestamp) - if err != nil { - return false, err - } - - // check whether the btc staking is actived - earliestDelHeight, err := fg.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) - if err != nil { - return false, err - } - if btcblockHeight < earliestDelHeight { - return false, ErrBtcStakingNotActivated - } - - // get all FPs voting power at this BTC height - allFpPower, err := fg.bbnClient.QueryMultiFpPower(allFpPks, btcblockHeight) - if err != nil { - return false, err - } - - // calculate total voting power - var totalPower uint64 = 0 - for _, power := range allFpPower { - totalPower += power - } - - // no FP has voting power for the consumer chain - if totalPower == 0 { - return false, ErrNoFpHasVotingPower - } - - // get all FPs that voted this (L2 block height, L2 block hash) combination - votedFpPks, err := fg.cwClient.QueryListOfVotedFinalityProviders(block) - if err != nil { - return false, err - } - if votedFpPks == nil { - return false, nil - } - // calculate voted voting power - var votedPower uint64 = 0 - for _, key := range votedFpPks { - if power, exists := allFpPower[key]; exists { - votedPower += power - } - } - - // quorom < 2/3 - if votedPower*3 < totalPower*2 { - return false, nil - } - return true, nil -} - -func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - return fg.db.GetBlockStatusByHeight(height) -} - -func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - return fg.db.GetBlockStatusByHash(normalizeBlockHash(hash)) -} - -func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { - return fg.db.GetLatestBlock() -} - -/* QueryBlockRangeBabylonFinalized searches for a row of consecutive finalized blocks in the block range, and returns - * the last finalized block height - * - * Example: if give block range 1-10, and block 1-5 are finalized, and block 6-10 are not finalized, then return 5 - * - * - if no block in the range is finalized, return (nil, nil) - * - else, return the height of the last found consecutive finalized block, return error if any - * - * Example: if give block range 1-10, and block 1-5 are finalized, and when querying block 6 we meet an error, then - * return (5, error) - * - * Note: caller needs to make sure the given queryBlocks are consecutive (we don't check hashes inside this method) - * and start from low to high - */ -func (fg *FinalityGadget) QueryBlockRangeBabylonFinalized( - queryBlocks []*types.Block, -) (*uint64, error) { - if len(queryBlocks) == 0 { - return nil, fmt.Errorf("no blocks provided") - } - // check if the blocks are consecutive - for i := 1; i < len(queryBlocks); i++ { - if queryBlocks[i].BlockHeight != queryBlocks[i-1].BlockHeight+1 { - return nil, fmt.Errorf("blocks are not consecutive") - } - } - var finalizedBlockHeight *uint64 - for _, block := range queryBlocks { - isFinalized, err := fg.QueryIsBlockBabylonFinalized(block) - if err != nil { - return finalizedBlockHeight, err - } - if isFinalized { - finalizedBlockHeight = &block.BlockHeight - } else { - break - } - } - return finalizedBlockHeight, nil -} - -/* QueryBtcStakingActivatedTimestamp returns the timestamp when the BTC staking is activated - * - * - We will check for k deep and covenant quorum to mark a delegation as active - * - So technically, activated time needs to be max of the following - * - timestamp of Babylon block that BTC delegation receives covenant quorum - * - timestamp of BTC block that BTC delegation's staking tx becomes k-deep - * - But we don't have a Babylon API to find the earliest Babylon block where BTC delegation gets covenant quorum. - * and it's probably not a good idea to add this to Babylon, as this creates more coupling between Babylon and - * consumer. So waiting for covenant quorum can be implemented in a clean way only with Babylon side support. - * this will be considered as future work - * - For now, we will use the k-deep BTC block timestamp for the activation timestamp - * - The time diff issue is not burning. The time diff between pending and active only matters if FP equivocates - * during that time period - * - * returns math.MaxUint64, ErrBtcStakingNotActivated if the BTC staking is not activated - */ -func (fg *FinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { - allFpPks, err := fg.queryAllFpBtcPubKeys() - if err != nil { - return math.MaxUint64, err - } - - // check whether the btc staking is actived - earliestDelHeight, err := fg.bbnClient.QueryEarliestActiveDelBtcHeight(allFpPks) - if err != nil { - return math.MaxUint64, err - } - - // not activated yet - if earliestDelHeight == math.MaxUint64 { - return math.MaxUint64, ErrBtcStakingNotActivated - } - - // get the timestamp of the BTC height - btcBlockTimestamp, err := fg.btcClient.GetBlockTimestampByHeight(earliestDelHeight) - if err != nil { - return math.MaxUint64, err - } - return btcBlockTimestamp, nil -} - -func (fg *FinalityGadget) queryAllFpBtcPubKeys() ([]string, error) { - // get the consumer chain id - consumerId, err := fg.cwClient.QueryConsumerId() - if err != nil { - return nil, err - } - - // get all the FPs pubkey for the consumer chain - allFpPks, err := fg.bbnClient.QueryAllFpBtcPubKeys(consumerId) - if err != nil { - return nil, err - } - return allFpPks, nil -} diff --git a/finalitygadget/utils.go b/finalitygadget/utils.go deleted file mode 100644 index 7fe4717..0000000 --- a/finalitygadget/utils.go +++ /dev/null @@ -1,7 +0,0 @@ -package finalitygadget - -import "github.com/ethereum/go-ethereum/common" - -func normalizeBlockHash(hash string) string { - return common.HexToHash(hash).Hex() -} diff --git a/server/rpcserver.go b/server/rpcserver.go index df1b374..543ee74 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -5,6 +5,7 @@ import ( "google.golang.org/grpc" + "github.com/babylonlabs-io/finality-gadget/finalitygadget" "github.com/babylonlabs-io/finality-gadget/proto" "github.com/babylonlabs-io/finality-gadget/types" ) @@ -14,12 +15,12 @@ import ( type rpcServer struct { proto.UnimplementedFinalityGadgetServer - fg types.IFinalityGadget + fg finalitygadget.IFinalityGadget } // newRPCServer creates a new RPC sever from the set of input dependencies. func newRPCServer( - fg types.IFinalityGadget, + fg finalitygadget.IFinalityGadget, ) *rpcServer { return &rpcServer{ fg: fg, diff --git a/server/server.go b/server/server.go index 9cd7564..c2a5009 100644 --- a/server/server.go +++ b/server/server.go @@ -9,7 +9,7 @@ import ( "github.com/babylonlabs-io/finality-gadget/config" "github.com/babylonlabs-io/finality-gadget/db" - "github.com/babylonlabs-io/finality-gadget/types" + "github.com/babylonlabs-io/finality-gadget/finalitygadget" "github.com/lightningnetwork/lnd/signal" "google.golang.org/grpc" @@ -21,7 +21,7 @@ import ( type Server struct { rpcServer *rpcServer cfg *config.Config - db *db.BBoltHandler + db db.IDatabaseHandler quit chan struct{} interceptor signal.Interceptor @@ -29,7 +29,7 @@ type Server struct { } // NewEOTSManagerServer creates a new server with the given config. -func NewFinalityGadgetServer(cfg *config.Config, db *db.BBoltHandler, fg types.IFinalityGadget, sig signal.Interceptor) *Server { +func NewFinalityGadgetServer(cfg *config.Config, db db.IDatabaseHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), diff --git a/types/external_clients.go b/types/external_clients.go deleted file mode 100644 index 68b8674..0000000 --- a/types/external_clients.go +++ /dev/null @@ -1,36 +0,0 @@ -package types - -import ( - "context" - "math/big" - - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" - eth "github.com/ethereum/go-ethereum/core/types" -) - -type IBabylonClient interface { - QueryAllFpBtcPubKeys(consumerId string) ([]string, error) - QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) - QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) - QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) -} - -type IBitcoinClient interface { - GetBlockCount() (uint64, error) - GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) - GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) - GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) - GetBlockTimestampByHeight(height uint64) (uint64, error) -} - -type ICosmWasmClient interface { - QueryListOfVotedFinalityProviders(queryParams *Block) ([]string, error) - QueryConsumerId() (string, error) - QueryIsEnabled() (bool, error) -} - -type IEthL2Client interface { - HeaderByNumber(ctx context.Context, number *big.Int) (*eth.Header, error) - Close() -} From 5b71fc70570fc5277a92e27034988c3f7907d41f Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 14:09:36 +0100 Subject: [PATCH 73/93] test: regenerate mocks --- finalitygadget/finalitygadget.go | 4 +- testutil/mocks/bbnclient_mock.go | 99 ++++++++ testutil/mocks/btcclient_mock.go | 116 +++++++++ testutil/mocks/cwclient_mock.go | 85 +++++++ testutil/mocks/external_clients_mock.go | 321 ------------------------ testutil/{ => mocks}/mock_btc_client.go | 2 +- 6 files changed, 303 insertions(+), 324 deletions(-) create mode 100644 testutil/mocks/bbnclient_mock.go create mode 100644 testutil/mocks/btcclient_mock.go create mode 100644 testutil/mocks/cwclient_mock.go delete mode 100644 testutil/mocks/external_clients_mock.go rename testutil/{ => mocks}/mock_btc_client.go (98%) diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 271fd68..6937337 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -19,7 +19,7 @@ import ( "github.com/babylonlabs-io/finality-gadget/cwclient" "github.com/babylonlabs-io/finality-gadget/db" "github.com/babylonlabs-io/finality-gadget/ethl2client" - "github.com/babylonlabs-io/finality-gadget/testutil" + "github.com/babylonlabs-io/finality-gadget/testutil/mocks" "github.com/babylonlabs-io/finality-gadget/types" "github.com/ethereum/go-ethereum/common" ethrpc "github.com/ethereum/go-ethereum/rpc" @@ -60,7 +60,7 @@ func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler) (*FinalityGad switch cfg.BBNChainID { // TODO: once we set up our own local BTC devnet, we don't need to use this mock BTC client case config.BabylonLocalnetChainID: - btcClient, err = testutil.NewMockBitcoinClient(btcConfig, logger) + btcClient, err = mocks.NewMockBitcoinClient(btcConfig, logger) default: btcClient, err = btcclient.NewBitcoinClient(btcConfig, logger) } diff --git a/testutil/mocks/bbnclient_mock.go b/testutil/mocks/bbnclient_mock.go new file mode 100644 index 0000000..f8abd33 --- /dev/null +++ b/testutil/mocks/bbnclient_mock.go @@ -0,0 +1,99 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: bbnclient/interface.go +// +// Generated by this command: +// +// mockgen -source=bbnclient/interface.go -package mocks -destination ./testutil/mocks/bbnclient_mock.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockIBabylonClient is a mock of IBabylonClient interface. +type MockIBabylonClient struct { + ctrl *gomock.Controller + recorder *MockIBabylonClientMockRecorder +} + +// MockIBabylonClientMockRecorder is the mock recorder for MockIBabylonClient. +type MockIBabylonClientMockRecorder struct { + mock *MockIBabylonClient +} + +// NewMockIBabylonClient creates a new mock instance. +func NewMockIBabylonClient(ctrl *gomock.Controller) *MockIBabylonClient { + mock := &MockIBabylonClient{ctrl: ctrl} + mock.recorder = &MockIBabylonClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIBabylonClient) EXPECT() *MockIBabylonClientMockRecorder { + return m.recorder +} + +// QueryAllFpBtcPubKeys mocks base method. +func (m *MockIBabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryAllFpBtcPubKeys", consumerId) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryAllFpBtcPubKeys indicates an expected call of QueryAllFpBtcPubKeys. +func (mr *MockIBabylonClientMockRecorder) QueryAllFpBtcPubKeys(consumerId any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryAllFpBtcPubKeys", reflect.TypeOf((*MockIBabylonClient)(nil).QueryAllFpBtcPubKeys), consumerId) +} + +// QueryEarliestActiveDelBtcHeight mocks base method. +func (m *MockIBabylonClient) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryEarliestActiveDelBtcHeight", fpPubkeyHexList) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryEarliestActiveDelBtcHeight indicates an expected call of QueryEarliestActiveDelBtcHeight. +func (mr *MockIBabylonClientMockRecorder) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryEarliestActiveDelBtcHeight", reflect.TypeOf((*MockIBabylonClient)(nil).QueryEarliestActiveDelBtcHeight), fpPubkeyHexList) +} + +// QueryFpPower mocks base method. +func (m *MockIBabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryFpPower", fpPubkeyHex, btcHeight) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryFpPower indicates an expected call of QueryFpPower. +func (mr *MockIBabylonClientMockRecorder) QueryFpPower(fpPubkeyHex, btcHeight any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryFpPower), fpPubkeyHex, btcHeight) +} + +// QueryMultiFpPower mocks base method. +func (m *MockIBabylonClient) QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryMultiFpPower", fpPubkeyHexList, btcHeight) + ret0, _ := ret[0].(map[string]uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryMultiFpPower indicates an expected call of QueryMultiFpPower. +func (mr *MockIBabylonClientMockRecorder) QueryMultiFpPower(fpPubkeyHexList, btcHeight any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryMultiFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryMultiFpPower), fpPubkeyHexList, btcHeight) +} diff --git a/testutil/mocks/btcclient_mock.go b/testutil/mocks/btcclient_mock.go new file mode 100644 index 0000000..ba3ccf5 --- /dev/null +++ b/testutil/mocks/btcclient_mock.go @@ -0,0 +1,116 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: btcclient/interface.go +// +// Generated by this command: +// +// mockgen -source=btcclient/interface.go -package mocks -destination ./testutil/mocks/btcclient_mock.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" + wire "github.com/btcsuite/btcd/wire" + gomock "go.uber.org/mock/gomock" +) + +// MockIBitcoinClient is a mock of IBitcoinClient interface. +type MockIBitcoinClient struct { + ctrl *gomock.Controller + recorder *MockIBitcoinClientMockRecorder +} + +// MockIBitcoinClientMockRecorder is the mock recorder for MockIBitcoinClient. +type MockIBitcoinClientMockRecorder struct { + mock *MockIBitcoinClient +} + +// NewMockIBitcoinClient creates a new mock instance. +func NewMockIBitcoinClient(ctrl *gomock.Controller) *MockIBitcoinClient { + mock := &MockIBitcoinClient{ctrl: ctrl} + mock.recorder = &MockIBitcoinClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIBitcoinClient) EXPECT() *MockIBitcoinClientMockRecorder { + return m.recorder +} + +// GetBlockCount mocks base method. +func (m *MockIBitcoinClient) GetBlockCount() (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockCount") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockCount indicates an expected call of GetBlockCount. +func (mr *MockIBitcoinClientMockRecorder) GetBlockCount() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockCount", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockCount)) +} + +// GetBlockHashByHeight mocks base method. +func (m *MockIBitcoinClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockHashByHeight", height) + ret0, _ := ret[0].(*chainhash.Hash) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockHashByHeight indicates an expected call of GetBlockHashByHeight. +func (mr *MockIBitcoinClientMockRecorder) GetBlockHashByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHashByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHashByHeight), height) +} + +// GetBlockHeaderByHash mocks base method. +func (m *MockIBitcoinClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockHeaderByHash", blockHash) + ret0, _ := ret[0].(*wire.BlockHeader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockHeaderByHash indicates an expected call of GetBlockHeaderByHash. +func (mr *MockIBitcoinClientMockRecorder) GetBlockHeaderByHash(blockHash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeaderByHash", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeaderByHash), blockHash) +} + +// GetBlockHeightByTimestamp mocks base method. +func (m *MockIBitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockHeightByTimestamp", targetTimestamp) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockHeightByTimestamp indicates an expected call of GetBlockHeightByTimestamp. +func (mr *MockIBitcoinClientMockRecorder) GetBlockHeightByTimestamp(targetTimestamp any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeightByTimestamp", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeightByTimestamp), targetTimestamp) +} + +// GetBlockTimestampByHeight mocks base method. +func (m *MockIBitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockTimestampByHeight", height) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockTimestampByHeight indicates an expected call of GetBlockTimestampByHeight. +func (mr *MockIBitcoinClientMockRecorder) GetBlockTimestampByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockTimestampByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockTimestampByHeight), height) +} diff --git a/testutil/mocks/cwclient_mock.go b/testutil/mocks/cwclient_mock.go new file mode 100644 index 0000000..f6430d2 --- /dev/null +++ b/testutil/mocks/cwclient_mock.go @@ -0,0 +1,85 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: cwclient/interface.go +// +// Generated by this command: +// +// mockgen -source=cwclient/interface.go -package mocks -destination ./testutil/mocks/cwclient_mock.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + types "github.com/babylonlabs-io/finality-gadget/types" + gomock "go.uber.org/mock/gomock" +) + +// MockICosmWasmClient is a mock of ICosmWasmClient interface. +type MockICosmWasmClient struct { + ctrl *gomock.Controller + recorder *MockICosmWasmClientMockRecorder +} + +// MockICosmWasmClientMockRecorder is the mock recorder for MockICosmWasmClient. +type MockICosmWasmClientMockRecorder struct { + mock *MockICosmWasmClient +} + +// NewMockICosmWasmClient creates a new mock instance. +func NewMockICosmWasmClient(ctrl *gomock.Controller) *MockICosmWasmClient { + mock := &MockICosmWasmClient{ctrl: ctrl} + mock.recorder = &MockICosmWasmClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockICosmWasmClient) EXPECT() *MockICosmWasmClientMockRecorder { + return m.recorder +} + +// QueryConsumerId mocks base method. +func (m *MockICosmWasmClient) QueryConsumerId() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryConsumerId") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryConsumerId indicates an expected call of QueryConsumerId. +func (mr *MockICosmWasmClientMockRecorder) QueryConsumerId() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryConsumerId", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryConsumerId)) +} + +// QueryIsEnabled mocks base method. +func (m *MockICosmWasmClient) QueryIsEnabled() (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryIsEnabled") + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryIsEnabled indicates an expected call of QueryIsEnabled. +func (mr *MockICosmWasmClientMockRecorder) QueryIsEnabled() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsEnabled", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryIsEnabled)) +} + +// QueryListOfVotedFinalityProviders mocks base method. +func (m *MockICosmWasmClient) QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryListOfVotedFinalityProviders", queryParams) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryListOfVotedFinalityProviders indicates an expected call of QueryListOfVotedFinalityProviders. +func (mr *MockICosmWasmClientMockRecorder) QueryListOfVotedFinalityProviders(queryParams any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryListOfVotedFinalityProviders", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryListOfVotedFinalityProviders), queryParams) +} diff --git a/testutil/mocks/external_clients_mock.go b/testutil/mocks/external_clients_mock.go deleted file mode 100644 index ffc5bd0..0000000 --- a/testutil/mocks/external_clients_mock.go +++ /dev/null @@ -1,321 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: types/external_clients.go -// -// Generated by this command: -// -// mockgen -source=types/external_clients.go -package mocks -destination ./testutil/mocks/external_clients_mock.go -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - big "math/big" - reflect "reflect" - - types "github.com/babylonlabs-io/finality-gadget/types" - chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" - wire "github.com/btcsuite/btcd/wire" - types0 "github.com/ethereum/go-ethereum/core/types" - gomock "go.uber.org/mock/gomock" -) - -// MockIBabylonClient is a mock of IBabylonClient interface. -type MockIBabylonClient struct { - ctrl *gomock.Controller - recorder *MockIBabylonClientMockRecorder -} - -// MockIBabylonClientMockRecorder is the mock recorder for MockIBabylonClient. -type MockIBabylonClientMockRecorder struct { - mock *MockIBabylonClient -} - -// NewMockIBabylonClient creates a new mock instance. -func NewMockIBabylonClient(ctrl *gomock.Controller) *MockIBabylonClient { - mock := &MockIBabylonClient{ctrl: ctrl} - mock.recorder = &MockIBabylonClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIBabylonClient) EXPECT() *MockIBabylonClientMockRecorder { - return m.recorder -} - -// QueryAllFpBtcPubKeys mocks base method. -func (m *MockIBabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryAllFpBtcPubKeys", consumerId) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryAllFpBtcPubKeys indicates an expected call of QueryAllFpBtcPubKeys. -func (mr *MockIBabylonClientMockRecorder) QueryAllFpBtcPubKeys(consumerId any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryAllFpBtcPubKeys", reflect.TypeOf((*MockIBabylonClient)(nil).QueryAllFpBtcPubKeys), consumerId) -} - -// QueryEarliestActiveDelBtcHeight mocks base method. -func (m *MockIBabylonClient) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryEarliestActiveDelBtcHeight", fpPubkeyHexList) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryEarliestActiveDelBtcHeight indicates an expected call of QueryEarliestActiveDelBtcHeight. -func (mr *MockIBabylonClientMockRecorder) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryEarliestActiveDelBtcHeight", reflect.TypeOf((*MockIBabylonClient)(nil).QueryEarliestActiveDelBtcHeight), fpPubkeyHexList) -} - -// QueryFpPower mocks base method. -func (m *MockIBabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryFpPower", fpPubkeyHex, btcHeight) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryFpPower indicates an expected call of QueryFpPower. -func (mr *MockIBabylonClientMockRecorder) QueryFpPower(fpPubkeyHex, btcHeight any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryFpPower), fpPubkeyHex, btcHeight) -} - -// QueryMultiFpPower mocks base method. -func (m *MockIBabylonClient) QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryMultiFpPower", fpPubkeyHexList, btcHeight) - ret0, _ := ret[0].(map[string]uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryMultiFpPower indicates an expected call of QueryMultiFpPower. -func (mr *MockIBabylonClientMockRecorder) QueryMultiFpPower(fpPubkeyHexList, btcHeight any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryMultiFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryMultiFpPower), fpPubkeyHexList, btcHeight) -} - -// MockIBitcoinClient is a mock of IBitcoinClient interface. -type MockIBitcoinClient struct { - ctrl *gomock.Controller - recorder *MockIBitcoinClientMockRecorder -} - -// MockIBitcoinClientMockRecorder is the mock recorder for MockIBitcoinClient. -type MockIBitcoinClientMockRecorder struct { - mock *MockIBitcoinClient -} - -// NewMockIBitcoinClient creates a new mock instance. -func NewMockIBitcoinClient(ctrl *gomock.Controller) *MockIBitcoinClient { - mock := &MockIBitcoinClient{ctrl: ctrl} - mock.recorder = &MockIBitcoinClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIBitcoinClient) EXPECT() *MockIBitcoinClientMockRecorder { - return m.recorder -} - -// GetBlockCount mocks base method. -func (m *MockIBitcoinClient) GetBlockCount() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockCount") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockCount indicates an expected call of GetBlockCount. -func (mr *MockIBitcoinClientMockRecorder) GetBlockCount() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockCount", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockCount)) -} - -// GetBlockHashByHeight mocks base method. -func (m *MockIBitcoinClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockHashByHeight", height) - ret0, _ := ret[0].(*chainhash.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockHashByHeight indicates an expected call of GetBlockHashByHeight. -func (mr *MockIBitcoinClientMockRecorder) GetBlockHashByHeight(height any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHashByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHashByHeight), height) -} - -// GetBlockHeaderByHash mocks base method. -func (m *MockIBitcoinClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockHeaderByHash", blockHash) - ret0, _ := ret[0].(*wire.BlockHeader) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockHeaderByHash indicates an expected call of GetBlockHeaderByHash. -func (mr *MockIBitcoinClientMockRecorder) GetBlockHeaderByHash(blockHash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeaderByHash", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeaderByHash), blockHash) -} - -// GetBlockHeightByTimestamp mocks base method. -func (m *MockIBitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockHeightByTimestamp", targetTimestamp) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockHeightByTimestamp indicates an expected call of GetBlockHeightByTimestamp. -func (mr *MockIBitcoinClientMockRecorder) GetBlockHeightByTimestamp(targetTimestamp any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeightByTimestamp", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeightByTimestamp), targetTimestamp) -} - -// GetBlockTimestampByHeight mocks base method. -func (m *MockIBitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockTimestampByHeight", height) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockTimestampByHeight indicates an expected call of GetBlockTimestampByHeight. -func (mr *MockIBitcoinClientMockRecorder) GetBlockTimestampByHeight(height any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockTimestampByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockTimestampByHeight), height) -} - -// MockICosmWasmClient is a mock of ICosmWasmClient interface. -type MockICosmWasmClient struct { - ctrl *gomock.Controller - recorder *MockICosmWasmClientMockRecorder -} - -// MockICosmWasmClientMockRecorder is the mock recorder for MockICosmWasmClient. -type MockICosmWasmClientMockRecorder struct { - mock *MockICosmWasmClient -} - -// NewMockICosmWasmClient creates a new mock instance. -func NewMockICosmWasmClient(ctrl *gomock.Controller) *MockICosmWasmClient { - mock := &MockICosmWasmClient{ctrl: ctrl} - mock.recorder = &MockICosmWasmClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockICosmWasmClient) EXPECT() *MockICosmWasmClientMockRecorder { - return m.recorder -} - -// QueryConsumerId mocks base method. -func (m *MockICosmWasmClient) QueryConsumerId() (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryConsumerId") - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryConsumerId indicates an expected call of QueryConsumerId. -func (mr *MockICosmWasmClientMockRecorder) QueryConsumerId() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryConsumerId", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryConsumerId)) -} - -// QueryIsEnabled mocks base method. -func (m *MockICosmWasmClient) QueryIsEnabled() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryIsEnabled") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryIsEnabled indicates an expected call of QueryIsEnabled. -func (mr *MockICosmWasmClientMockRecorder) QueryIsEnabled() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsEnabled", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryIsEnabled)) -} - -// QueryListOfVotedFinalityProviders mocks base method. -func (m *MockICosmWasmClient) QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryListOfVotedFinalityProviders", queryParams) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryListOfVotedFinalityProviders indicates an expected call of QueryListOfVotedFinalityProviders. -func (mr *MockICosmWasmClientMockRecorder) QueryListOfVotedFinalityProviders(queryParams any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryListOfVotedFinalityProviders", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryListOfVotedFinalityProviders), queryParams) -} - -// MockIEthL2Client is a mock of IEthL2Client interface. -type MockIEthL2Client struct { - ctrl *gomock.Controller - recorder *MockIEthL2ClientMockRecorder -} - -// MockIEthL2ClientMockRecorder is the mock recorder for MockIEthL2Client. -type MockIEthL2ClientMockRecorder struct { - mock *MockIEthL2Client -} - -// NewMockIEthL2Client creates a new mock instance. -func NewMockIEthL2Client(ctrl *gomock.Controller) *MockIEthL2Client { - mock := &MockIEthL2Client{ctrl: ctrl} - mock.recorder = &MockIEthL2ClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIEthL2Client) EXPECT() *MockIEthL2ClientMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockIEthL2Client) Close() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Close") -} - -// Close indicates an expected call of Close. -func (mr *MockIEthL2ClientMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIEthL2Client)(nil).Close)) -} - -// HeaderByNumber mocks base method. -func (m *MockIEthL2Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types0.Header, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HeaderByNumber", ctx, number) - ret0, _ := ret[0].(*types0.Header) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// HeaderByNumber indicates an expected call of HeaderByNumber. -func (mr *MockIEthL2ClientMockRecorder) HeaderByNumber(ctx, number any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByNumber", reflect.TypeOf((*MockIEthL2Client)(nil).HeaderByNumber), ctx, number) -} diff --git a/testutil/mock_btc_client.go b/testutil/mocks/mock_btc_client.go similarity index 98% rename from testutil/mock_btc_client.go rename to testutil/mocks/mock_btc_client.go index a457f13..c9267de 100644 --- a/testutil/mock_btc_client.go +++ b/testutil/mocks/mock_btc_client.go @@ -1,4 +1,4 @@ -package testutil +package mocks import ( "github.com/babylonlabs-io/finality-gadget/btcclient" From b288c42b2900d2382ea2fe596bbfd56c4712bf86 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 14:24:31 +0100 Subject: [PATCH 74/93] feat: use zap logger --- cmd/opfgd/start.go | 13 ++++++-- db/bbolt.go | 56 +++++++++++++++++--------------- db/bbolt_test.go | 9 ++++- finalitygadget/finalitygadget.go | 41 ++++++++++------------- server/server.go | 15 +++++---- 5 files changed, 74 insertions(+), 60 deletions(-) diff --git a/cmd/opfgd/start.go b/cmd/opfgd/start.go index 35c4b76..87757ea 100644 --- a/cmd/opfgd/start.go +++ b/cmd/opfgd/start.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" + "go.uber.org/zap" rpcclient "github.com/babylonlabs-io/finality-gadget/client" "github.com/babylonlabs-io/finality-gadget/config" @@ -47,8 +48,14 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to load configuration: %w", err) } + // Create logger + logger, err := zap.NewProduction() + if err != nil { + return fmt.Errorf("failed to create logger: %w", err) + } + // Init local DB for storing and querying blocks - db, err := db.NewBBoltHandler(cfg.DBFilePath) + db, err := db.NewBBoltHandler(cfg.DBFilePath, logger) if err != nil { return fmt.Errorf("failed to create DB handler: %w", err) } @@ -59,7 +66,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { } // Create finality gadget - fg, err := finalitygadget.NewFinalityGadget(cfg, db) + fg, err := finalitygadget.NewFinalityGadget(cfg, db, logger) if err != nil { log.Fatalf("Error creating finality gadget: %v\n", err) return fmt.Errorf("error creating finality gadget: %v", err) @@ -71,7 +78,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { if err != nil { return err } - srv := server.NewFinalityGadgetServer(cfg, db, fg, shutdownInterceptor) + srv := server.NewFinalityGadgetServer(cfg, db, fg, shutdownInterceptor, logger) go func() { err = srv.RunUntilShutdown() if err != nil { diff --git a/db/bbolt.go b/db/bbolt.go index 6104ddd..82063e3 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -6,17 +6,18 @@ import ( "encoding/json" "errors" "fmt" - "log" "os" "path/filepath" "time" "github.com/babylonlabs-io/finality-gadget/types" bolt "go.etcd.io/bbolt" + "go.uber.org/zap" ) type BBoltHandler struct { - db *bolt.DB + db *bolt.DB + logger *zap.Logger } var _ IDatabaseHandler = &BBoltHandler{} @@ -36,16 +37,17 @@ var ( // CONSTRUCTOR ////////////////////////////// -func NewBBoltHandler(path string) (*BBoltHandler, error) { +func NewBBoltHandler(path string, logger *zap.Logger) (*BBoltHandler, error) { // 0600 = read/write permission for owner only db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 1 * time.Second}) if err != nil { - log.Fatalf("Error opening DB: %v\n", err) + logger.Error("Error opening DB", zap.Error(err)) return nil, err } return &BBoltHandler{ - db: db, + db: db, + logger: logger, }, nil } @@ -54,11 +56,11 @@ func NewBBoltHandler(path string) (*BBoltHandler, error) { ////////////////////////////// func (bb *BBoltHandler) CreateInitialSchema() error { - log.Printf("Initialising DB...") + bb.logger.Info("Initialising DB...") return bb.db.Update(func(tx *bolt.Tx) error { buckets := []string{blocksBucket, blockHeightsBucket, latestBlockBucket} for _, bucket := range buckets { - if err := tryCreateBucket(tx, bucket); err != nil { + if err := bb.tryCreateBucket(tx, bucket); err != nil { return err } } @@ -67,12 +69,12 @@ func (bb *BBoltHandler) CreateInitialSchema() error { } func (bb *BBoltHandler) InsertBlock(block *types.Block) error { - log.Printf("Inserting block %d to DB...\n", block.BlockHeight) + bb.logger.Info("Inserting block to DB", zap.Uint64("block_height", block.BlockHeight)) // Store mapping number -> block err := bb.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blocksBucket)) - key := itob(block.BlockHeight) + key := bb.itob(block.BlockHeight) blockBytes, err := json.Marshal(block) if err != nil { return err @@ -80,24 +82,24 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { return b.Put(key, blockBytes) }) if err != nil { - log.Fatalf("Error inserting block: %v\n", err) + bb.logger.Error("Error inserting block", zap.Error(err)) return err } // Store mapping hash -> number err = bb.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blockHeightsBucket)) - return b.Put([]byte(block.BlockHash), itob(block.BlockHeight)) + return b.Put([]byte(block.BlockHash), bb.itob(block.BlockHeight)) }) if err != nil { - log.Fatalf("Error inserting block: %v\n", err) + bb.logger.Error("Error inserting block", zap.Error(err)) return err } // Get current latest block latestBlock, err := bb.GetLatestBlock() if err != nil { - log.Fatalf("Error getting latest block: %v\n", err) + bb.logger.Error("Error getting latest block", zap.Error(err)) return err } @@ -105,16 +107,16 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { err = bb.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(latestBlockBucket)) if err != nil { - log.Fatalf("Error getting latest block: %v\n", err) + bb.logger.Error("Error getting latest block", zap.Error(err)) return err } if latestBlock.BlockHeight < block.BlockHeight { - return b.Put([]byte(latestBlockKey), itob(block.BlockHeight)) + return b.Put([]byte(latestBlockKey), bb.itob(block.BlockHeight)) } return nil }) if err != nil { - log.Fatalf("Error updating latest block: %v\n", err) + bb.logger.Error("Error updating latest block", zap.Error(err)) return err } @@ -125,7 +127,7 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { var block types.Block err := bb.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(blocksBucket)) - v := b.Get(itob(height)) + v := b.Get(bb.itob(height)) if v == nil { return ErrBlockNotFound } @@ -157,7 +159,7 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { if len(res) == 0 { return ErrBlockNotFound } - blockHeight = btoi(res) + blockHeight = bb.btoi(res) return nil }) if err != nil { @@ -180,7 +182,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { if v == nil { return ErrBlockNotFound } - latestBlockHeight = btoi(v) + latestBlockHeight = bb.btoi(v) return nil }) if err != nil { @@ -192,7 +194,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { BlockTimestamp: 0, }, nil } - log.Fatalf("Error getting latest block: %v\n", err) + bb.logger.Error("Error getting latest block", zap.Error(err)) return nil, err } @@ -203,7 +205,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { func (bb *BBoltHandler) DeleteDB() error { absPath, err := filepath.Abs(bb.db.Path()) if err != nil { - log.Fatalf("failed to get db absolute path: %v\n", err) + bb.logger.Error("Error getting db absolute path", zap.Error(err)) return fmt.Errorf("failed to get db absolute path: %w", err) } @@ -218,29 +220,29 @@ func (bb *BBoltHandler) Close() error { // INTERNAL ////////////////////////////// -func tryCreateBucket(tx *bolt.Tx, bucketName string) error { +func (bb *BBoltHandler) tryCreateBucket(tx *bolt.Tx, bucketName string) error { _, err := tx.CreateBucketIfNotExists([]byte(bucketName)) if err != nil { - log.Fatalf("Error creating bucket: %v\n", err) + bb.logger.Error("Error creating bucket", zap.Error(err)) } return err } -func itob(v uint64) []byte { +func (bb *BBoltHandler) itob(v uint64) []byte { buf := new(bytes.Buffer) err := binary.Write(buf, binary.BigEndian, v) if err != nil { - log.Fatalf("Error writing to buffer: %v\n", err) + bb.logger.Fatal("Error writing to buffer", zap.Error(err)) } return buf.Bytes() } -func btoi(b []byte) uint64 { +func (bb *BBoltHandler) btoi(b []byte) uint64 { var v uint64 buf := bytes.NewReader(b) err := binary.Read(buf, binary.BigEndian, &v) if err != nil { - log.Fatalf("Error reading from buffer: %v\n", err) + bb.logger.Fatal("Error reading from buffer", zap.Error(err)) } return v } diff --git a/db/bbolt_test.go b/db/bbolt_test.go index ab8d4f7..7132554 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -6,6 +6,7 @@ import ( "github.com/babylonlabs-io/finality-gadget/types" "github.com/stretchr/testify/assert" + "go.uber.org/zap" ) func setupDB(t *testing.T) (*BBoltHandler, func()) { @@ -16,8 +17,14 @@ func setupDB(t *testing.T) (*BBoltHandler, func()) { } tempFile.Close() + // Create logger. + logger, err := zap.NewProduction() + if err != nil { + t.Fatalf("Failed to create logger: %v", err) + } + // Create a new BBoltHandler - db, err := NewBBoltHandler(tempFile.Name()) + db, err := NewBBoltHandler(tempFile.Name(), logger) if err != nil { t.Fatalf("Failed to create BBoltHandler: %v", err) } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 6937337..1ba88eb 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -4,7 +4,6 @@ import ( "context" "encoding/hex" "fmt" - "log" "math" "math/big" "strings" @@ -39,24 +38,32 @@ type FinalityGadget struct { pollInterval time.Duration currHeight uint64 + + logger *zap.Logger } ////////////////////////////// // CONSTRUCTOR ////////////////////////////// -func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler) (*FinalityGadget, error) { - // Create logger - logger, err := zap.NewProduction() +func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler, logger *zap.Logger) (*FinalityGadget, error) { + // Create babylon client + bbnConfig := bbncfg.DefaultBabylonConfig() + bbnConfig.RPCAddr = cfg.BBNRPCAddress + bbnConfig.ChainID = cfg.BBNChainID + babylonClient, err := bbnClient.New( + &bbnConfig, + logger, + ) + bbnClient := bbnclient.NewBabylonClient(babylonClient.QueryClient) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create Babylon client: %w", err) } // Create bitcoin client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost var btcClient btcclient.IBitcoinClient - // Create BTC client switch cfg.BBNChainID { // TODO: once we set up our own local BTC devnet, we don't need to use this mock BTC client case config.BabylonLocalnetChainID: @@ -68,19 +75,6 @@ func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler) (*FinalityGad return nil, err } - // Create babylon client - bbnConfig := bbncfg.DefaultBabylonConfig() - bbnConfig.RPCAddr = cfg.BBNRPCAddress - bbnConfig.ChainID = cfg.BBNChainID - babylonClient, err := bbnClient.New( - &bbnConfig, - logger, - ) - bbnClient := bbnclient.NewBabylonClient(babylonClient.QueryClient) - if err != nil { - return nil, fmt.Errorf("failed to create Babylon client: %w", err) - } - // Create cosmwasm client cwClient := cwclient.NewCosmWasmClient(babylonClient.QueryClient.RPCClient, cfg.FGContractAddress) @@ -98,6 +92,7 @@ func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler) (*FinalityGad l2Client: l2Client, db: db, pollInterval: cfg.PollInterval, + logger: logger, }, nil } @@ -308,7 +303,7 @@ func (fg *FinalityGadget) ProcessBlocks(ctx context.Context) error { case <-ticker.C: block, err := fg.getBlockByNumber(int64(fg.currHeight + 1)) if err != nil { - log.Fatalf("error getting new block: %v\n", err) + fg.logger.Fatal("error getting new block", zap.Error(err)) continue } go func() { @@ -427,7 +422,7 @@ func (fg *FinalityGadget) startService() error { } // Start service at block height - log.Printf("Starting finality gadget at block %d...\n", block.BlockHeight) + fg.logger.Info("Starting finality gadget at block", zap.Uint64("block_height", block.BlockHeight)) // Set the curr finalized block in memory fg.currHeight = block.BlockHeight @@ -442,13 +437,13 @@ func (fg *FinalityGadget) handleBlock(block *types.Block) { // Check if block is finalized isFinal, err := fg.QueryIsBlockBabylonFinalized(block) if err != nil { - log.Fatalf("Error checking block %d: %v\n", block.BlockHeight, err) + fg.logger.Fatal("Error checking block", zap.Uint64("block_height", block.BlockHeight), zap.Error(err)) return } if isFinal { err = fg.InsertBlock(block) if err != nil { - log.Fatalf("Error storing block %d: %v\n", block.BlockHeight, err) + fg.logger.Fatal("Error storing block", zap.Uint64("block_height", block.BlockHeight), zap.Error(err)) } return } diff --git a/server/server.go b/server/server.go index c2a5009..1d194fe 100644 --- a/server/server.go +++ b/server/server.go @@ -2,7 +2,6 @@ package server import ( "fmt" - "log" "net" "sync" "sync/atomic" @@ -11,6 +10,7 @@ import ( "github.com/babylonlabs-io/finality-gadget/db" "github.com/babylonlabs-io/finality-gadget/finalitygadget" "github.com/lightningnetwork/lnd/signal" + "go.uber.org/zap" "google.golang.org/grpc" ) @@ -23,17 +23,20 @@ type Server struct { cfg *config.Config db db.IDatabaseHandler + logger *zap.Logger + quit chan struct{} interceptor signal.Interceptor started int32 } // NewEOTSManagerServer creates a new server with the given config. -func NewFinalityGadgetServer(cfg *config.Config, db db.IDatabaseHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor) *Server { +func NewFinalityGadgetServer(cfg *config.Config, db db.IDatabaseHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor, logger *zap.Logger) *Server { return &Server{ cfg: cfg, rpcServer: newRPCServer(fg), db: db, + logger: logger, interceptor: sig, quit: make(chan struct{}, 1), } @@ -47,9 +50,9 @@ func (s *Server) RunUntilShutdown() error { } defer func() { - log.Printf("Closing database...") + s.logger.Info("Closing database...") s.db.Close() - log.Printf("Database closed") + s.logger.Info("Database closed") }() listenAddr := "localhost:" + s.cfg.GRPCServerPort @@ -74,7 +77,7 @@ func (s *Server) RunUntilShutdown() error { return fmt.Errorf("failed to start gRPC listener: %v", err) } - log.Printf("Finality gadget is active") + s.logger.Info("Finality gadget is active") // Wait for shutdown signal from either a graceful server stop or from // the interrupt handler. @@ -93,7 +96,7 @@ func (s *Server) startGrpcListen(grpcServer *grpc.Server, listeners []net.Listen for _, lis := range listeners { wg.Add(1) go func(lis net.Listener) { - log.Printf("RPC server listening: %s", lis.Addr().String()) + s.logger.Info("RPC server listening", zap.String("address", lis.Addr().String())) // Close the ready chan to indicate we are listening. defer lis.Close() From 0f98df16698419cd28d2703c5dff6fec8502ccf8 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 14:26:21 +0100 Subject: [PATCH 75/93] docs: update readme --- README.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bab7282..2ed4670 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,25 @@ The Babylon Finality Gadget is a program that can be run by users of OP stack L2 See our [proposal](https://github.com/ethereum-optimism/specs/discussions/218) on Optimism for more details. -## Downloading and configuring the daemon +## Modules + +- `cmd` : entry point for `opfgd` finality gadget daemon +- `finalitygadget` : top-level umbrella module that exposes query methods and coordinates calls to other clients +- `client` : grpc client to query the finality gadget +- `server` : grpc server for the finality gadget +- `proto` : protobuf definitions for the grpc server +- `config` : configs for the finality gadget +- `btcclient` : wrapper around Bitcoin RPC client +- `bbnclient` : wrapper around Babylon RPC client +- `ethl2client` : wrapper around OP stack L2 ETH RPC client +- `cwclient` : client to query CosmWasm smart contract deployed on BabylonChain +- `db` : handler for local database to store finalized block state +- `types` : common types +- `testutil` : test utilities and helpers + +## Instructions + +### Download and configuration To get started, clone the repository. @@ -12,7 +30,7 @@ To get started, clone the repository. git clone https://github.com/babylonlabs-io/finality-gadget.git ``` -Configure the `config.toml` file with the following content: +Configure the `config.toml` file: ```toml L2RPCHost = # RPC URL of OP stack L2 chain @@ -34,10 +52,7 @@ make install ``` The above command will build and install the `opfgd` binary to -`$GOPATH/bin`: - -- `eotsd`: The daemon program for the EOTS manager. -- `fpd`: The daemon program for the finality-provider with overall commands. +`$GOPATH/bin`. If your shell cannot find the installed binaries, make sure `$GOPATH/bin` is in the `$PATH` of your shell. Usually these commands will do the job From 556b15bd1cb59f353159a6853e93138136fa3658 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 15:00:19 +0100 Subject: [PATCH 76/93] feat: add getBlockByHash route to db --- db/bbolt.go | 18 ++++ db/bbolt_test.go | 30 +++++++ db/interface.go | 1 + testutil/mocks/db_mock.go | 171 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 testutil/mocks/db_mock.go diff --git a/db/bbolt.go b/db/bbolt.go index 82063e3..c2b1cc1 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -139,6 +139,24 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { return &block, nil } +func (bb *BBoltHandler) GetBlockByHash(hash string) (*types.Block, error) { + // Fetch block number corresponding to hash + var blockHeight uint64 + err := bb.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(blockHeightsBucket)) + v := b.Get([]byte(hash)) + if v == nil { + return ErrBlockNotFound + } + blockHeight = bb.btoi(v) + return nil + }) + if err != nil { + return nil, err + } + return bb.GetBlockByHeight(blockHeight) +} + func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { _, err := bb.GetBlockByHeight(height) if err != nil { diff --git a/db/bbolt_test.go b/db/bbolt_test.go index 7132554..38e5da5 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -95,6 +95,36 @@ func TestGetBlockByHeightForNonExistentBlock(t *testing.T) { assert.Equal(t, ErrBlockNotFound, err) } +func TestGetBlockByHash(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + // Insert a block + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + err := handler.InsertBlock(block) + assert.NoError(t, err) + + // Retrieve block by hash + retrievedBlock, err := handler.GetBlockByHash(block.BlockHash) + assert.NoError(t, err) + assert.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + assert.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + assert.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHashForNonExistentBlock(t *testing.T) { + handler, cleanup := setupDB(t) + defer cleanup() + + block, err := handler.GetBlockByHash("0x123") + assert.Nil(t, block) + assert.Equal(t, ErrBlockNotFound, err) +} + func TestGetBlockStatusByHeight(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() diff --git a/db/interface.go b/db/interface.go index 0314809..2d410ef 100644 --- a/db/interface.go +++ b/db/interface.go @@ -6,6 +6,7 @@ type IDatabaseHandler interface { CreateInitialSchema() error InsertBlock(block *types.Block) error GetBlockByHeight(height uint64) (*types.Block, error) + GetBlockByHash(hash string) (*types.Block, error) GetBlockStatusByHeight(height uint64) (bool, error) GetBlockStatusByHash(hash string) (bool, error) GetLatestBlock() (*types.Block, error) diff --git a/testutil/mocks/db_mock.go b/testutil/mocks/db_mock.go new file mode 100644 index 0000000..f2b4d5e --- /dev/null +++ b/testutil/mocks/db_mock.go @@ -0,0 +1,171 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: db/interface.go +// +// Generated by this command: +// +// mockgen -source=db/interface.go -package mocks -destination ./testutil/mocks/db_mock.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + types "github.com/babylonlabs-io/finality-gadget/types" + gomock "go.uber.org/mock/gomock" +) + +// MockIDatabaseHandler is a mock of IDatabaseHandler interface. +type MockIDatabaseHandler struct { + ctrl *gomock.Controller + recorder *MockIDatabaseHandlerMockRecorder +} + +// MockIDatabaseHandlerMockRecorder is the mock recorder for MockIDatabaseHandler. +type MockIDatabaseHandlerMockRecorder struct { + mock *MockIDatabaseHandler +} + +// NewMockIDatabaseHandler creates a new mock instance. +func NewMockIDatabaseHandler(ctrl *gomock.Controller) *MockIDatabaseHandler { + mock := &MockIDatabaseHandler{ctrl: ctrl} + mock.recorder = &MockIDatabaseHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIDatabaseHandler) EXPECT() *MockIDatabaseHandlerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockIDatabaseHandler) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockIDatabaseHandlerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIDatabaseHandler)(nil).Close)) +} + +// CreateInitialSchema mocks base method. +func (m *MockIDatabaseHandler) CreateInitialSchema() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateInitialSchema") + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateInitialSchema indicates an expected call of CreateInitialSchema. +func (mr *MockIDatabaseHandlerMockRecorder) CreateInitialSchema() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInitialSchema", reflect.TypeOf((*MockIDatabaseHandler)(nil).CreateInitialSchema)) +} + +// DeleteDB mocks base method. +func (m *MockIDatabaseHandler) DeleteDB() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDB") + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDB indicates an expected call of DeleteDB. +func (mr *MockIDatabaseHandlerMockRecorder) DeleteDB() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDB", reflect.TypeOf((*MockIDatabaseHandler)(nil).DeleteDB)) +} + +// GetBlockByHash mocks base method. +func (m *MockIDatabaseHandler) GetBlockByHash(hash string) (*types.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockByHash", hash) + ret0, _ := ret[0].(*types.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockByHash indicates an expected call of GetBlockByHash. +func (mr *MockIDatabaseHandlerMockRecorder) GetBlockByHash(hash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHash", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockByHash), hash) +} + +// GetBlockByHeight mocks base method. +func (m *MockIDatabaseHandler) GetBlockByHeight(height uint64) (*types.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockByHeight", height) + ret0, _ := ret[0].(*types.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockByHeight indicates an expected call of GetBlockByHeight. +func (mr *MockIDatabaseHandlerMockRecorder) GetBlockByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockByHeight), height) +} + +// GetBlockStatusByHash mocks base method. +func (m *MockIDatabaseHandler) GetBlockStatusByHash(hash string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockStatusByHash", hash) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockStatusByHash indicates an expected call of GetBlockStatusByHash. +func (mr *MockIDatabaseHandlerMockRecorder) GetBlockStatusByHash(hash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHash", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockStatusByHash), hash) +} + +// GetBlockStatusByHeight mocks base method. +func (m *MockIDatabaseHandler) GetBlockStatusByHeight(height uint64) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockStatusByHeight", height) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockStatusByHeight indicates an expected call of GetBlockStatusByHeight. +func (mr *MockIDatabaseHandlerMockRecorder) GetBlockStatusByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockStatusByHeight), height) +} + +// GetLatestBlock mocks base method. +func (m *MockIDatabaseHandler) GetLatestBlock() (*types.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLatestBlock") + ret0, _ := ret[0].(*types.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLatestBlock indicates an expected call of GetLatestBlock. +func (mr *MockIDatabaseHandlerMockRecorder) GetLatestBlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestBlock", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetLatestBlock)) +} + +// InsertBlock mocks base method. +func (m *MockIDatabaseHandler) InsertBlock(block *types.Block) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InsertBlock", block) + ret0, _ := ret[0].(error) + return ret0 +} + +// InsertBlock indicates an expected call of InsertBlock. +func (mr *MockIDatabaseHandlerMockRecorder) InsertBlock(block any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockIDatabaseHandler)(nil).InsertBlock), block) +} From 4d7124e873a4173d36ad65137ee6abb135090bb7 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 15:00:42 +0100 Subject: [PATCH 77/93] feat: add get block routes to finalitygadget --- finalitygadget/finalitygadget.go | 8 +++++++ finalitygadget/interface.go | 6 +++++ testutil/mocks/finalitygadget_mock.go | 34 +++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 1ba88eb..cc848b3 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -273,6 +273,14 @@ func (fg *FinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { return btcBlockTimestamp, nil } +func (fg *FinalityGadget) GetBlockByHeight(height uint64) (*types.Block, error) { + return fg.db.GetBlockByHeight(height) +} + +func (fg *FinalityGadget) GetBlockByHash(hash string) (*types.Block, error) { + return fg.db.GetBlockByHash(normalizeBlockHash(hash)) +} + func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { return fg.db.GetBlockStatusByHeight(height) } diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go index 93ccaee..4212d6a 100644 --- a/finalitygadget/interface.go +++ b/finalitygadget/interface.go @@ -58,6 +58,12 @@ type IFinalityGadget interface { // InsertBlock inserts a btc finalized block into the local db InsertBlock(block *types.Block) error + // GetBlockByHeight returns the btc finalized block at given height by querying the local db + GetBlockByHeight(height uint64) (*types.Block, error) + + // GetBlockByHash returns the btc finalized block at given hash by querying the local db + GetBlockByHash(hash string) (*types.Block, error) + // GetBlockStatusByHeight returns the btc finalization status of a block at given height by querying the local db GetBlockStatusByHeight(height uint64) (bool, error) diff --git a/testutil/mocks/finalitygadget_mock.go b/testutil/mocks/finalitygadget_mock.go index 7defdd9..beb798a 100644 --- a/testutil/mocks/finalitygadget_mock.go +++ b/testutil/mocks/finalitygadget_mock.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: types/finalitygadget.go +// Source: finalitygadget/interface.go // // Generated by this command: // -// mockgen -source=types/finalitygadget.go -package mocks -destination ./testutil/mocks/finalitygadget_mock.go +// mockgen -source=finalitygadget/interface.go -package mocks -destination ./testutil/mocks/finalitygadget_mock.go // // Package mocks is a generated GoMock package. @@ -39,6 +39,36 @@ func (m *MockIFinalityGadget) EXPECT() *MockIFinalityGadgetMockRecorder { return m.recorder } +// GetBlockByHash mocks base method. +func (m *MockIFinalityGadget) GetBlockByHash(hash string) (*types.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockByHash", hash) + ret0, _ := ret[0].(*types.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockByHash indicates an expected call of GetBlockByHash. +func (mr *MockIFinalityGadgetMockRecorder) GetBlockByHash(hash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHash", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockByHash), hash) +} + +// GetBlockByHeight mocks base method. +func (m *MockIFinalityGadget) GetBlockByHeight(height uint64) (*types.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockByHeight", height) + ret0, _ := ret[0].(*types.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockByHeight indicates an expected call of GetBlockByHeight. +func (mr *MockIFinalityGadgetMockRecorder) GetBlockByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHeight", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockByHeight), height) +} + // GetBlockStatusByHash mocks base method. func (m *MockIFinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { m.ctrl.T.Helper() From 7328f3c5e6ea132b6ae745a65c1ef30ea5cb195d Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 15:09:49 +0100 Subject: [PATCH 78/93] chore: consolidate errors --- db/bbolt.go | 18 +++++++----------- db/bbolt_test.go | 4 ++-- finalitygadget/errors.go | 8 -------- finalitygadget/finalitygadget.go | 6 +++--- finalitygadget/finalitygadget_test.go | 9 +++++---- types/errors.go | 9 +++++++++ 6 files changed, 26 insertions(+), 28 deletions(-) delete mode 100644 finalitygadget/errors.go create mode 100644 types/errors.go diff --git a/db/bbolt.go b/db/bbolt.go index c2b1cc1..cc88822 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -29,10 +29,6 @@ const ( latestBlockKey = "latest" ) -var ( - ErrBlockNotFound = errors.New("block not found") -) - ////////////////////////////// // CONSTRUCTOR ////////////////////////////// @@ -129,7 +125,7 @@ func (bb *BBoltHandler) GetBlockByHeight(height uint64) (*types.Block, error) { b := tx.Bucket([]byte(blocksBucket)) v := b.Get(bb.itob(height)) if v == nil { - return ErrBlockNotFound + return types.ErrBlockNotFound } return json.Unmarshal(v, &block) }) @@ -146,7 +142,7 @@ func (bb *BBoltHandler) GetBlockByHash(hash string) (*types.Block, error) { b := tx.Bucket([]byte(blockHeightsBucket)) v := b.Get([]byte(hash)) if v == nil { - return ErrBlockNotFound + return types.ErrBlockNotFound } blockHeight = bb.btoi(v) return nil @@ -160,7 +156,7 @@ func (bb *BBoltHandler) GetBlockByHash(hash string) (*types.Block, error) { func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { _, err := bb.GetBlockByHeight(height) if err != nil { - if errors.Is(err, ErrBlockNotFound) { + if errors.Is(err, types.ErrBlockNotFound) { return false, nil } return false, err @@ -175,13 +171,13 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { b := tx.Bucket([]byte(blockHeightsBucket)) res := b.Get([]byte(hash)) if len(res) == 0 { - return ErrBlockNotFound + return types.ErrBlockNotFound } blockHeight = bb.btoi(res) return nil }) if err != nil { - if errors.Is(err, ErrBlockNotFound) { + if errors.Is(err, types.ErrBlockNotFound) { return false, nil } return false, err @@ -198,14 +194,14 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { b := tx.Bucket([]byte(latestBlockBucket)) v := b.Get([]byte(latestBlockKey)) if v == nil { - return ErrBlockNotFound + return types.ErrBlockNotFound } latestBlockHeight = bb.btoi(v) return nil }) if err != nil { // If no latest block has been stored yet, return empty block (block 0) - if errors.Is(err, ErrBlockNotFound) { + if errors.Is(err, types.ErrBlockNotFound) { return &types.Block{ BlockHeight: 0, BlockHash: "", diff --git a/db/bbolt_test.go b/db/bbolt_test.go index 38e5da5..c98cf00 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -92,7 +92,7 @@ func TestGetBlockByHeightForNonExistentBlock(t *testing.T) { block, err := handler.GetBlockByHeight(1) assert.Nil(t, block) - assert.Equal(t, ErrBlockNotFound, err) + assert.Equal(t, types.ErrBlockNotFound, err) } func TestGetBlockByHash(t *testing.T) { @@ -122,7 +122,7 @@ func TestGetBlockByHashForNonExistentBlock(t *testing.T) { block, err := handler.GetBlockByHash("0x123") assert.Nil(t, block) - assert.Equal(t, ErrBlockNotFound, err) + assert.Equal(t, types.ErrBlockNotFound, err) } func TestGetBlockStatusByHeight(t *testing.T) { diff --git a/finalitygadget/errors.go b/finalitygadget/errors.go deleted file mode 100644 index 6cf7d40..0000000 --- a/finalitygadget/errors.go +++ /dev/null @@ -1,8 +0,0 @@ -package finalitygadget - -import "fmt" - -var ( - ErrNoFpHasVotingPower = fmt.Errorf("no FP has voting power for the consumer chain") - ErrBtcStakingNotActivated = fmt.Errorf("BTC staking is not activated for the consumer chain") -) diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index cc848b3..8c60bb6 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -148,7 +148,7 @@ func (fg *FinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool return false, err } if btcblockHeight < earliestDelHeight { - return false, ErrBtcStakingNotActivated + return false, types.ErrBtcStakingNotActivated } // get all FPs voting power at this BTC height @@ -165,7 +165,7 @@ func (fg *FinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool // no FP has voting power for the consumer chain if totalPower == 0 { - return false, ErrNoFpHasVotingPower + return false, types.ErrNoFpHasVotingPower } // get all FPs that voted this (L2 block height, L2 block hash) combination @@ -262,7 +262,7 @@ func (fg *FinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { // not activated yet if earliestDelHeight == math.MaxUint64 { - return math.MaxUint64, ErrBtcStakingNotActivated + return math.MaxUint64, types.ErrBtcStakingNotActivated } // get the timestamp of the BTC height diff --git a/finalitygadget/finalitygadget_test.go b/finalitygadget/finalitygadget_test.go index 5a90b16..0521ef3 100644 --- a/finalitygadget/finalitygadget_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -1,6 +1,7 @@ package finalitygadget import ( + "errors" "fmt" "math/rand" "strings" @@ -124,7 +125,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { votedProviders: []string{"pk1", "pk2", "pk3"}, stakingActivationHeight: BTCHeight - 1, expectResult: false, - expectedErr: ErrNoFpHasVotingPower, + expectedErr: types.ErrNoFpHasVotingPower, }, { name: "Btc staking not activated, 100% votes, expects false", @@ -134,7 +135,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { votedProviders: []string{"pk1", "pk2", "pk3"}, stakingActivationHeight: BTCHeight + 1, expectResult: false, - expectedErr: ErrBtcStakingNotActivated, + expectedErr: types.ErrBtcStakingNotActivated, }, } @@ -162,13 +163,13 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) { Return(tc.stakingActivationHeight, nil). Times(1) - if tc.expectedErr != ErrBtcStakingNotActivated { + if !errors.Is(tc.expectedErr, types.ErrBtcStakingNotActivated) { mockBBNClient.EXPECT(). QueryMultiFpPower(tc.allFpPks, BTCHeight). Return(tc.fpPowers, nil). Times(1) - if tc.expectedErr != ErrNoFpHasVotingPower { + if !errors.Is(tc.expectedErr, types.ErrNoFpHasVotingPower) { mockCwClient.EXPECT(). QueryListOfVotedFinalityProviders(&blockWithHashTrimmed). Return(tc.votedProviders, tc.expectedErr). diff --git a/types/errors.go b/types/errors.go new file mode 100644 index 0000000..fe93f70 --- /dev/null +++ b/types/errors.go @@ -0,0 +1,9 @@ +package types + +import "errors" + +var ( + ErrBlockNotFound = errors.New("block not found") + ErrNoFpHasVotingPower = errors.New("no FP has voting power for the consumer chain") + ErrBtcStakingNotActivated = errors.New("BTC staking is not activated for the consumer chain") +) From 8d37a70da52427f6c9acc485cf9ea0ea421ab382 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 15:55:20 +0100 Subject: [PATCH 79/93] test: add fg unit tests --- db/bbolt.go | 9 +- db/bbolt_test.go | 6 +- finalitygadget/finalitygadget.go | 2 +- finalitygadget/finalitygadget_test.go | 326 ++++++++++++++++++++++++++ 4 files changed, 332 insertions(+), 11 deletions(-) diff --git a/db/bbolt.go b/db/bbolt.go index cc88822..9fd7555 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -94,6 +94,9 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { // Get current latest block latestBlock, err := bb.GetLatestBlock() + if latestBlock == nil { + latestBlock = &types.Block{BlockHeight: 0} + } if err != nil { bb.logger.Error("Error getting latest block", zap.Error(err)) return err @@ -202,11 +205,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { if err != nil { // If no latest block has been stored yet, return empty block (block 0) if errors.Is(err, types.ErrBlockNotFound) { - return &types.Block{ - BlockHeight: 0, - BlockHash: "", - BlockTimestamp: 0, - }, nil + return nil, nil } bb.logger.Error("Error getting latest block", zap.Error(err)) return nil, err diff --git a/db/bbolt_test.go b/db/bbolt_test.go index c98cf00..f631eb1 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -214,10 +214,6 @@ func TestGetLatestBlockNonExistent(t *testing.T) { defer cleanup() latestBlock, err := handler.GetLatestBlock() - assert.Equal(t, latestBlock, &types.Block{ - BlockHeight: 0, - BlockHash: "", - BlockTimestamp: 0, - }) + assert.Nil(t, latestBlock) assert.NoError(t, err) } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 8c60bb6..f885d53 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -401,7 +401,7 @@ func (fg *FinalityGadget) startService() error { } // if local chain tip is ahead of node, start service at latest block - if localBlock.BlockHeight != 0 && localBlock.BlockHeight >= block.BlockHeight { + if localBlock != nil && localBlock.BlockHeight >= block.BlockHeight { block = &types.Block{ BlockHeight: localBlock.BlockHeight, BlockHash: localBlock.BlockHash, diff --git a/finalitygadget/finalitygadget_test.go b/finalitygadget/finalitygadget_test.go index 0521ef3..cede930 100644 --- a/finalitygadget/finalitygadget_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -260,3 +260,329 @@ func TestQueryBlockRangeBabylonFinalized(t *testing.T) { }) } } + +func TestInsertBlock(t *testing.T) { + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + // note: the block hash is normalized before passing to the db handler + mockDbHandler.EXPECT().InsertBlock(normalizedBlock(block)).Return(nil).Times(1) + mockDbHandler.EXPECT().GetBlockByHeight(block.BlockHeight).Return(block, nil).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // insert block + err := mockFinalityGadget.InsertBlock(block) + require.NoError(t, err) + + // verify block was inserted + retrievedBlock, err := mockFinalityGadget.GetBlockByHeight(1) + require.NoError(t, err) + require.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + require.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + require.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHeight(t *testing.T) { + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + // note: the block hash is normalized before passing to the db handler + mockDbHandler.EXPECT().InsertBlock(normalizedBlock(block)).Return(nil).Times(1) + mockDbHandler.EXPECT().GetBlockByHeight(block.BlockHeight).Return(block, nil).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // insert block + err := mockFinalityGadget.InsertBlock(block) + require.NoError(t, err) + + // fetch block by height + retrievedBlock, err := mockFinalityGadget.GetBlockByHeight(1) + require.NoError(t, err) + require.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + require.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + require.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHeightForNonExistentBlock(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockByHeight(uint64(1)).Return(nil, types.ErrBlockNotFound).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block by height + retrievedBlock, err := mockFinalityGadget.GetBlockByHeight(1) + require.Nil(t, retrievedBlock) + require.Equal(t, err, types.ErrBlockNotFound) +} + +func TestGetBlockByHashWith0xPrefix(t *testing.T) { + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + // note: the block hash is normalized before passing to the db handler + mockDbHandler.EXPECT().InsertBlock(normalizedBlock(block)).Return(nil).Times(1) + mockDbHandler.EXPECT().GetBlockByHash(normalizeBlockHash(block.BlockHash)).Return(block, nil).Times(2) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // insert block + err := mockFinalityGadget.InsertBlock(block) + require.NoError(t, err) + + // fetch block by hash including 0x prefix + retrievedBlock, err := mockFinalityGadget.GetBlockByHash(block.BlockHash) + require.NoError(t, err) + require.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + require.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + require.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) + + // fetch block by hash excluding 0x prefix + retrievedBlock, err = mockFinalityGadget.GetBlockByHash(strings.TrimPrefix(block.BlockHash, "0x")) + require.NoError(t, err) + require.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + require.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + require.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHashWithout0xPrefix(t *testing.T) { + block := &types.Block{ + BlockHeight: 1, + BlockHash: "123", + BlockTimestamp: 1000, + } + + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + // note: the block hash is normalized before passing to the db handler + mockDbHandler.EXPECT().InsertBlock(normalizedBlock(block)).Return(nil).Times(1) + mockDbHandler.EXPECT().GetBlockByHash(normalizeBlockHash(block.BlockHash)).Return(block, nil).Times(2) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // insert block + err := mockFinalityGadget.InsertBlock(block) + require.NoError(t, err) + + // fetch block by hash including 0x prefix + retrievedBlock, err := mockFinalityGadget.GetBlockByHash("0x" + block.BlockHash) + require.NoError(t, err) + require.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + require.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + require.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) + + // fetch block by hash excluding 0x prefix + retrievedBlock, err = mockFinalityGadget.GetBlockByHash(block.BlockHash) + require.NoError(t, err) + require.Equal(t, block.BlockHeight, retrievedBlock.BlockHeight) + require.Equal(t, block.BlockHash, retrievedBlock.BlockHash) + require.Equal(t, block.BlockTimestamp, retrievedBlock.BlockTimestamp) +} + +func TestGetBlockByHashForNonExistentBlock(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockByHash(normalizeBlockHash("123")).Return(nil, types.ErrBlockNotFound).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block by hash + retrievedBlock, err := mockFinalityGadget.GetBlockByHash("123") + require.Nil(t, retrievedBlock) + require.Equal(t, err, types.ErrBlockNotFound) +} + +func TestGetBlockStatusByHeight(t *testing.T) { + block := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockStatusByHeight(block.BlockHeight).Return(true, nil).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block status by height + isFinalized, err := mockFinalityGadget.GetBlockStatusByHeight(1) + require.NoError(t, err) + require.True(t, isFinalized) +} + +func TestGetBlockStatusByHeightForNonExistentBlock(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockStatusByHeight(uint64(1)).Return(false, types.ErrBlockNotFound).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block status by height + isFinalized, err := mockFinalityGadget.GetBlockStatusByHeight(1) + require.False(t, isFinalized) + require.Equal(t, err, types.ErrBlockNotFound) +} + +func TestGetBlockStatusByHashWith0xPrefix(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockStatusByHash(normalizeBlockHash("0x123")).Return(true, nil).Times(2) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block status by hash including 0x prefix + isFinalized, err := mockFinalityGadget.GetBlockStatusByHash("0x123") + require.NoError(t, err) + require.True(t, isFinalized) + + // fetch block status by hash excluding 0x prefix + isFinalized, err = mockFinalityGadget.GetBlockStatusByHash("123") + require.NoError(t, err) + require.True(t, isFinalized) +} + +func TestGetBlockStatusByHashWithout0xPrefix(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockStatusByHash(normalizeBlockHash("123")).Return(true, nil).Times(2) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block status by hash including 0x prefix + isFinalized, err := mockFinalityGadget.GetBlockStatusByHash("0x123") + require.NoError(t, err) + require.True(t, isFinalized) + + // fetch block status by hash excluding 0x prefix + isFinalized, err = mockFinalityGadget.GetBlockStatusByHash("123") + require.NoError(t, err) + require.True(t, isFinalized) +} + +func TestGetBlockStatusByHashForNonExistentBlock(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetBlockStatusByHash(normalizeBlockHash("123")).Return(false, types.ErrBlockNotFound).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch block status by hash + isFinalized, err := mockFinalityGadget.GetBlockStatusByHash("123") + require.False(t, isFinalized) + require.Equal(t, err, types.ErrBlockNotFound) +} + +func TestGetLatestBlock(t *testing.T) { + // define blocks + first := &types.Block{ + BlockHeight: 1, + BlockHash: "0x123", + BlockTimestamp: 1000, + } + second := &types.Block{ + BlockHeight: 2, + BlockHash: "0x456", + BlockTimestamp: 2000, + } + normalizedFirst := normalizedBlock(first) + normalizedSecond := normalizedBlock(second) + + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().InsertBlock(normalizedFirst).Return(nil).Times(1) + mockDbHandler.EXPECT().InsertBlock(normalizedSecond).Return(nil).Times(1) + mockDbHandler.EXPECT().GetLatestBlock().Return(normalizedSecond, nil).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // insert two blocks + err := mockFinalityGadget.InsertBlock(first) + require.NoError(t, err) + err = mockFinalityGadget.InsertBlock(second) + require.NoError(t, err) + + // fetch latest block + latestBlock, err := mockFinalityGadget.GetLatestBlock() + require.NoError(t, err) + require.Equal(t, normalizedSecond.BlockHeight, latestBlock.BlockHeight) + require.Equal(t, normalizedSecond.BlockHash, latestBlock.BlockHash) + require.Equal(t, normalizedSecond.BlockTimestamp, latestBlock.BlockTimestamp) +} + +func TestGetLatestBlockForNonExistentBlock(t *testing.T) { + // mock db and finality gadget + ctl := gomock.NewController(t) + mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) + mockDbHandler.EXPECT().GetLatestBlock().Return(nil, types.ErrBlockNotFound).Times(1) + + mockFinalityGadget := &FinalityGadget{ + db: mockDbHandler, + } + + // fetch latest block + latestBlock, err := mockFinalityGadget.GetLatestBlock() + require.Nil(t, latestBlock) + require.Equal(t, err, types.ErrBlockNotFound) +} + +func normalizedBlock(block *types.Block) *types.Block { + return &types.Block{ + BlockHeight: block.BlockHeight, + BlockHash: normalizeBlockHash(block.BlockHash), + BlockTimestamp: block.BlockTimestamp, + } +} From 04a6c73bd02700ea62dadbe8889279b0a4702267 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 16:02:58 +0100 Subject: [PATCH 80/93] feat: add logger --- btcclient/btcclient_test.go | 4 ++-- cmd/opfgd/start.go | 16 +++++++-------- db/bbolt_test.go | 4 ++-- log/log.go | 41 +++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 log/log.go diff --git a/btcclient/btcclient_test.go b/btcclient/btcclient_test.go index ccab76e..369814a 100644 --- a/btcclient/btcclient_test.go +++ b/btcclient/btcclient_test.go @@ -3,8 +3,8 @@ package btcclient import ( "testing" + "github.com/babylonlabs-io/finality-gadget/log" "github.com/stretchr/testify/require" - "go.uber.org/zap" ) // TODO: 1) not rely on mainnet RPC; 2) add more tests for some other edge cases @@ -13,7 +13,7 @@ func TestBtcClient(t *testing.T) { var err error // Create logger. - logger, err := zap.NewDevelopment() + logger, err := log.NewRootLogger("console", true) require.Nil(t, err) // Create BTC client diff --git a/cmd/opfgd/start.go b/cmd/opfgd/start.go index 87757ea..f0b161b 100644 --- a/cmd/opfgd/start.go +++ b/cmd/opfgd/start.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "log" "os" "os/signal" "syscall" @@ -16,6 +15,7 @@ import ( "github.com/babylonlabs-io/finality-gadget/config" "github.com/babylonlabs-io/finality-gadget/db" "github.com/babylonlabs-io/finality-gadget/finalitygadget" + "github.com/babylonlabs-io/finality-gadget/log" "github.com/babylonlabs-io/finality-gadget/server" sig "github.com/lightningnetwork/lnd/signal" ) @@ -49,7 +49,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { } // Create logger - logger, err := zap.NewProduction() + logger, err := log.NewRootLogger("console", true) if err != nil { return fmt.Errorf("failed to create logger: %w", err) } @@ -68,7 +68,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { // Create finality gadget fg, err := finalitygadget.NewFinalityGadget(cfg, db, logger) if err != nil { - log.Fatalf("Error creating finality gadget: %v\n", err) + logger.Fatal("Error creating finality gadget", zap.Error(err)) return fmt.Errorf("error creating finality gadget: %v", err) } @@ -82,7 +82,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { go func() { err = srv.RunUntilShutdown() if err != nil { - log.Fatalf("Finality gadget server error: %v\n", err) + logger.Fatal("Finality gadget server error", zap.Error(err)) } }() @@ -90,7 +90,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { hostAddr := "localhost:" + cfg.GRPCServerPort client, err := rpcclient.NewFinalityGadgetGrpcClient(db, hostAddr) if err != nil { - log.Fatalf("Error creating grpc client: %v\n", err) + logger.Fatal("Error creating grpc client", zap.Error(err)) return fmt.Errorf("error creating grpc client: %v", err) } @@ -101,7 +101,7 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { // Run finality gadget in a separate goroutine go func() { if err := fg.ProcessBlocks(context.Background()); err != nil { - log.Fatalf("Error processing blocks: %v\n", err) + logger.Fatal("Error processing blocks", zap.Error(err)) } }() @@ -112,9 +112,9 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { } // Call Close method when interrupt signal is received - log.Printf("Closing finality gadget server...") + logger.Info("Closing finality gadget server...") if err := client.Close(); err != nil { - log.Fatalf("Error stopping grpc client: %v\n", err) + logger.Fatal("Error closing grpc client", zap.Error(err)) return err } fg.Close() diff --git a/db/bbolt_test.go b/db/bbolt_test.go index f631eb1..6587116 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -4,9 +4,9 @@ import ( "os" "testing" + "github.com/babylonlabs-io/finality-gadget/log" "github.com/babylonlabs-io/finality-gadget/types" "github.com/stretchr/testify/assert" - "go.uber.org/zap" ) func setupDB(t *testing.T) (*BBoltHandler, func()) { @@ -18,7 +18,7 @@ func setupDB(t *testing.T) (*BBoltHandler, func()) { tempFile.Close() // Create logger. - logger, err := zap.NewProduction() + logger, err := log.NewRootLogger("console", true) if err != nil { t.Fatalf("Failed to create logger: %v", err) } diff --git a/log/log.go b/log/log.go new file mode 100644 index 0000000..992f9c6 --- /dev/null +++ b/log/log.go @@ -0,0 +1,41 @@ +package log + +import ( + "fmt" + "os" + "time" + + zaplogfmt "github.com/jsternberg/zap-logfmt" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func NewRootLogger(format string, debug bool) (*zap.Logger, error) { + cfg := zap.NewProductionEncoderConfig() + cfg.EncodeTime = func(ts time.Time, encoder zapcore.PrimitiveArrayEncoder) { + encoder.AppendString(ts.UTC().Format("2006-01-02T15:04:05.000000Z07:00")) + } + cfg.LevelKey = "lvl" + + var enc zapcore.Encoder + switch format { + case "json": + enc = zapcore.NewJSONEncoder(cfg) + case "auto", "console": + enc = zapcore.NewConsoleEncoder(cfg) + case "logfmt": + enc = zaplogfmt.NewEncoder(cfg) + default: + return nil, fmt.Errorf("unrecognized log format %q", format) + } + + level := zap.InfoLevel + if debug { + level = zap.DebugLevel + } + return zap.New(zapcore.NewCore( + enc, + os.Stderr, + level, + )), nil +} From cfad1d39a1586570100456332833425ac40bd441 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 16:07:43 +0100 Subject: [PATCH 81/93] fix: lint errors --- db/bbolt.go | 1 + db/bbolt_test.go | 5 ++++- finalitygadget/finalitygadget.go | 7 +++---- finalitygadget/finalitygadget_test.go | 8 ++------ 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/db/bbolt.go b/db/bbolt.go index 9fd7555..36ebd42 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -217,6 +217,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { func (bb *BBoltHandler) DeleteDB() error { absPath, err := filepath.Abs(bb.db.Path()) + bb.logger.Info("Deleting DB", zap.String("path", absPath)) if err != nil { bb.logger.Error("Error getting db absolute path", zap.Error(err)) return fmt.Errorf("failed to get db absolute path: %w", err) diff --git a/db/bbolt_test.go b/db/bbolt_test.go index 6587116..3bfadb7 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -37,8 +37,11 @@ func setupDB(t *testing.T) (*BBoltHandler, func()) { // Cleanup function to close DB and remove temp file cleanup := func() { + err := db.DeleteDB() + if err != nil { + t.Fatalf("Failed to delete DB: %v", err) + } db.Close() - db.DeleteDB() } return db, cleanup diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index f885d53..b191509 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -33,13 +33,12 @@ type FinalityGadget struct { cwClient cwclient.ICosmWasmClient l2Client ethl2client.IEthL2Client - db db.IDatabaseHandler - mutex sync.Mutex + db db.IDatabaseHandler + logger *zap.Logger + mutex sync.Mutex pollInterval time.Duration currHeight uint64 - - logger *zap.Logger } ////////////////////////////// diff --git a/finalitygadget/finalitygadget_test.go b/finalitygadget/finalitygadget_test.go index cede930..40b1c49 100644 --- a/finalitygadget/finalitygadget_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -428,16 +428,12 @@ func TestGetBlockByHashForNonExistentBlock(t *testing.T) { } func TestGetBlockStatusByHeight(t *testing.T) { - block := &types.Block{ - BlockHeight: 1, - BlockHash: "0x123", - BlockTimestamp: 1000, - } + blockHeight := uint64(1) // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetBlockStatusByHeight(block.BlockHeight).Return(true, nil).Times(1) + mockDbHandler.EXPECT().GetBlockStatusByHeight(blockHeight).Return(true, nil).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, From 28dc39fd01948e8e89ecf681dd44c1c6894f89e0 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 16:12:39 +0100 Subject: [PATCH 82/93] docs: add logger to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2ed4670..2e5339f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ See our [proposal](https://github.com/ethereum-optimism/specs/discussions/218) o - `cwclient` : client to query CosmWasm smart contract deployed on BabylonChain - `db` : handler for local database to store finalized block state - `types` : common types +- `log` : custom logger - `testutil` : test utilities and helpers ## Instructions From c288422f4d20280d5eb6eed0440c4d3fef10ec34 Mon Sep 17 00:00:00 2001 From: parketh Date: Tue, 6 Aug 2024 21:27:22 +0100 Subject: [PATCH 83/93] restore expected_clients --- bbnclient/bbnclient.go | 2 - bbnclient/interface.go | 8 - btcclient/btcclient.go | 2 - btcclient/interface.go | 14 -- cwclient/cwclient.go | 2 - cwclient/interface.go | 9 - ethl2client/ethl2client.go | 2 - ethl2client/interface.go | 13 - finalitygadget/expected_clients.go | 37 +++ finalitygadget/finalitygadget.go | 10 +- testutil/mocks/bbnclient_mock.go | 99 -------- testutil/mocks/btcclient_mock.go | 116 --------- testutil/mocks/cwclient_mock.go | 85 ------- testutil/mocks/expected_clients_mock.go | 321 ++++++++++++++++++++++++ testutil/mocks/finalitygadget_mock.go | 174 ------------- 15 files changed, 363 insertions(+), 531 deletions(-) delete mode 100644 bbnclient/interface.go delete mode 100644 btcclient/interface.go delete mode 100644 cwclient/interface.go delete mode 100644 ethl2client/interface.go create mode 100644 finalitygadget/expected_clients.go delete mode 100644 testutil/mocks/bbnclient_mock.go delete mode 100644 testutil/mocks/btcclient_mock.go delete mode 100644 testutil/mocks/cwclient_mock.go create mode 100644 testutil/mocks/expected_clients_mock.go delete mode 100644 testutil/mocks/finalitygadget_mock.go diff --git a/bbnclient/bbnclient.go b/bbnclient/bbnclient.go index 64b41f2..fde8f85 100644 --- a/bbnclient/bbnclient.go +++ b/bbnclient/bbnclient.go @@ -12,8 +12,6 @@ type BabylonClient struct { *query.QueryClient } -var _ IBabylonClient = &BabylonClient{} - ////////////////////////////// // CONSTRUCTOR ////////////////////////////// diff --git a/bbnclient/interface.go b/bbnclient/interface.go deleted file mode 100644 index f22b492..0000000 --- a/bbnclient/interface.go +++ /dev/null @@ -1,8 +0,0 @@ -package bbnclient - -type IBabylonClient interface { - QueryAllFpBtcPubKeys(consumerId string) ([]string, error) - QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) - QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) - QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) -} diff --git a/btcclient/btcclient.go b/btcclient/btcclient.go index 1021d64..eb88d09 100644 --- a/btcclient/btcclient.go +++ b/btcclient/btcclient.go @@ -16,8 +16,6 @@ type BitcoinClient struct { cfg *BTCConfig } -var _ IBitcoinClient = &BitcoinClient{} - ////////////////////////////// // CONSTRUCTOR ////////////////////////////// diff --git a/btcclient/interface.go b/btcclient/interface.go deleted file mode 100644 index 4d2ad7b..0000000 --- a/btcclient/interface.go +++ /dev/null @@ -1,14 +0,0 @@ -package btcclient - -import ( - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/wire" -) - -type IBitcoinClient interface { - GetBlockCount() (uint64, error) - GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) - GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) - GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) - GetBlockTimestampByHeight(height uint64) (uint64, error) -} diff --git a/cwclient/cwclient.go b/cwclient/cwclient.go index a4646a8..04dc8bc 100644 --- a/cwclient/cwclient.go +++ b/cwclient/cwclient.go @@ -16,8 +16,6 @@ type CosmWasmClient struct { contractAddr string } -var _ ICosmWasmClient = &CosmWasmClient{} - const ( // hardcode the timeout to 20 seconds. We can expose it to the params once needed DefaultTimeout = 20 * time.Second diff --git a/cwclient/interface.go b/cwclient/interface.go deleted file mode 100644 index 841a146..0000000 --- a/cwclient/interface.go +++ /dev/null @@ -1,9 +0,0 @@ -package cwclient - -import "github.com/babylonlabs-io/finality-gadget/types" - -type ICosmWasmClient interface { - QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) - QueryConsumerId() (string, error) - QueryIsEnabled() (bool, error) -} diff --git a/ethl2client/ethl2client.go b/ethl2client/ethl2client.go index c9e7936..56e969b 100644 --- a/ethl2client/ethl2client.go +++ b/ethl2client/ethl2client.go @@ -9,8 +9,6 @@ import ( "github.com/ethereum/go-ethereum/ethclient" ) -var _ IEthL2Client = &EthL2Client{} - type EthL2Client struct { client *ethclient.Client } diff --git a/ethl2client/interface.go b/ethl2client/interface.go deleted file mode 100644 index e5e8126..0000000 --- a/ethl2client/interface.go +++ /dev/null @@ -1,13 +0,0 @@ -package ethl2client - -import ( - "context" - "math/big" - - eth "github.com/ethereum/go-ethereum/core/types" -) - -type IEthL2Client interface { - HeaderByNumber(ctx context.Context, number *big.Int) (*eth.Header, error) - Close() -} diff --git a/finalitygadget/expected_clients.go b/finalitygadget/expected_clients.go new file mode 100644 index 0000000..047bffa --- /dev/null +++ b/finalitygadget/expected_clients.go @@ -0,0 +1,37 @@ +package finalitygadget + +import ( + "context" + "math/big" + + "github.com/babylonlabs-io/finality-gadget/types" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + eth "github.com/ethereum/go-ethereum/core/types" +) + +type IBitcoinClient interface { + GetBlockCount() (uint64, error) + GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) + GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) + GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) + GetBlockTimestampByHeight(height uint64) (uint64, error) +} + +type IBabylonClient interface { + QueryAllFpBtcPubKeys(consumerId string) ([]string, error) + QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) + QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) + QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) +} + +type ICosmWasmClient interface { + QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) + QueryConsumerId() (string, error) + QueryIsEnabled() (bool, error) +} + +type IEthL2Client interface { + HeaderByNumber(ctx context.Context, number *big.Int) (*eth.Header, error) + Close() +} diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index b191509..3e33c6f 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -28,10 +28,10 @@ import ( var _ IFinalityGadget = &FinalityGadget{} type FinalityGadget struct { - btcClient btcclient.IBitcoinClient - bbnClient bbnclient.IBabylonClient - cwClient cwclient.ICosmWasmClient - l2Client ethl2client.IEthL2Client + btcClient IBitcoinClient + bbnClient IBabylonClient + cwClient ICosmWasmClient + l2Client IEthL2Client db db.IDatabaseHandler logger *zap.Logger @@ -62,7 +62,7 @@ func NewFinalityGadget(cfg *config.Config, db db.IDatabaseHandler, logger *zap.L // Create bitcoin client btcConfig := btcclient.DefaultBTCConfig() btcConfig.RPCHost = cfg.BitcoinRPCHost - var btcClient btcclient.IBitcoinClient + var btcClient IBitcoinClient switch cfg.BBNChainID { // TODO: once we set up our own local BTC devnet, we don't need to use this mock BTC client case config.BabylonLocalnetChainID: diff --git a/testutil/mocks/bbnclient_mock.go b/testutil/mocks/bbnclient_mock.go deleted file mode 100644 index f8abd33..0000000 --- a/testutil/mocks/bbnclient_mock.go +++ /dev/null @@ -1,99 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: bbnclient/interface.go -// -// Generated by this command: -// -// mockgen -source=bbnclient/interface.go -package mocks -destination ./testutil/mocks/bbnclient_mock.go -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockIBabylonClient is a mock of IBabylonClient interface. -type MockIBabylonClient struct { - ctrl *gomock.Controller - recorder *MockIBabylonClientMockRecorder -} - -// MockIBabylonClientMockRecorder is the mock recorder for MockIBabylonClient. -type MockIBabylonClientMockRecorder struct { - mock *MockIBabylonClient -} - -// NewMockIBabylonClient creates a new mock instance. -func NewMockIBabylonClient(ctrl *gomock.Controller) *MockIBabylonClient { - mock := &MockIBabylonClient{ctrl: ctrl} - mock.recorder = &MockIBabylonClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIBabylonClient) EXPECT() *MockIBabylonClientMockRecorder { - return m.recorder -} - -// QueryAllFpBtcPubKeys mocks base method. -func (m *MockIBabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryAllFpBtcPubKeys", consumerId) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryAllFpBtcPubKeys indicates an expected call of QueryAllFpBtcPubKeys. -func (mr *MockIBabylonClientMockRecorder) QueryAllFpBtcPubKeys(consumerId any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryAllFpBtcPubKeys", reflect.TypeOf((*MockIBabylonClient)(nil).QueryAllFpBtcPubKeys), consumerId) -} - -// QueryEarliestActiveDelBtcHeight mocks base method. -func (m *MockIBabylonClient) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryEarliestActiveDelBtcHeight", fpPubkeyHexList) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryEarliestActiveDelBtcHeight indicates an expected call of QueryEarliestActiveDelBtcHeight. -func (mr *MockIBabylonClientMockRecorder) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryEarliestActiveDelBtcHeight", reflect.TypeOf((*MockIBabylonClient)(nil).QueryEarliestActiveDelBtcHeight), fpPubkeyHexList) -} - -// QueryFpPower mocks base method. -func (m *MockIBabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryFpPower", fpPubkeyHex, btcHeight) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryFpPower indicates an expected call of QueryFpPower. -func (mr *MockIBabylonClientMockRecorder) QueryFpPower(fpPubkeyHex, btcHeight any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryFpPower), fpPubkeyHex, btcHeight) -} - -// QueryMultiFpPower mocks base method. -func (m *MockIBabylonClient) QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryMultiFpPower", fpPubkeyHexList, btcHeight) - ret0, _ := ret[0].(map[string]uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryMultiFpPower indicates an expected call of QueryMultiFpPower. -func (mr *MockIBabylonClientMockRecorder) QueryMultiFpPower(fpPubkeyHexList, btcHeight any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryMultiFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryMultiFpPower), fpPubkeyHexList, btcHeight) -} diff --git a/testutil/mocks/btcclient_mock.go b/testutil/mocks/btcclient_mock.go deleted file mode 100644 index ba3ccf5..0000000 --- a/testutil/mocks/btcclient_mock.go +++ /dev/null @@ -1,116 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: btcclient/interface.go -// -// Generated by this command: -// -// mockgen -source=btcclient/interface.go -package mocks -destination ./testutil/mocks/btcclient_mock.go -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - reflect "reflect" - - chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" - wire "github.com/btcsuite/btcd/wire" - gomock "go.uber.org/mock/gomock" -) - -// MockIBitcoinClient is a mock of IBitcoinClient interface. -type MockIBitcoinClient struct { - ctrl *gomock.Controller - recorder *MockIBitcoinClientMockRecorder -} - -// MockIBitcoinClientMockRecorder is the mock recorder for MockIBitcoinClient. -type MockIBitcoinClientMockRecorder struct { - mock *MockIBitcoinClient -} - -// NewMockIBitcoinClient creates a new mock instance. -func NewMockIBitcoinClient(ctrl *gomock.Controller) *MockIBitcoinClient { - mock := &MockIBitcoinClient{ctrl: ctrl} - mock.recorder = &MockIBitcoinClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIBitcoinClient) EXPECT() *MockIBitcoinClientMockRecorder { - return m.recorder -} - -// GetBlockCount mocks base method. -func (m *MockIBitcoinClient) GetBlockCount() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockCount") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockCount indicates an expected call of GetBlockCount. -func (mr *MockIBitcoinClientMockRecorder) GetBlockCount() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockCount", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockCount)) -} - -// GetBlockHashByHeight mocks base method. -func (m *MockIBitcoinClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockHashByHeight", height) - ret0, _ := ret[0].(*chainhash.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockHashByHeight indicates an expected call of GetBlockHashByHeight. -func (mr *MockIBitcoinClientMockRecorder) GetBlockHashByHeight(height any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHashByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHashByHeight), height) -} - -// GetBlockHeaderByHash mocks base method. -func (m *MockIBitcoinClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockHeaderByHash", blockHash) - ret0, _ := ret[0].(*wire.BlockHeader) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockHeaderByHash indicates an expected call of GetBlockHeaderByHash. -func (mr *MockIBitcoinClientMockRecorder) GetBlockHeaderByHash(blockHash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeaderByHash", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeaderByHash), blockHash) -} - -// GetBlockHeightByTimestamp mocks base method. -func (m *MockIBitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockHeightByTimestamp", targetTimestamp) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockHeightByTimestamp indicates an expected call of GetBlockHeightByTimestamp. -func (mr *MockIBitcoinClientMockRecorder) GetBlockHeightByTimestamp(targetTimestamp any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeightByTimestamp", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeightByTimestamp), targetTimestamp) -} - -// GetBlockTimestampByHeight mocks base method. -func (m *MockIBitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockTimestampByHeight", height) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockTimestampByHeight indicates an expected call of GetBlockTimestampByHeight. -func (mr *MockIBitcoinClientMockRecorder) GetBlockTimestampByHeight(height any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockTimestampByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockTimestampByHeight), height) -} diff --git a/testutil/mocks/cwclient_mock.go b/testutil/mocks/cwclient_mock.go deleted file mode 100644 index f6430d2..0000000 --- a/testutil/mocks/cwclient_mock.go +++ /dev/null @@ -1,85 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: cwclient/interface.go -// -// Generated by this command: -// -// mockgen -source=cwclient/interface.go -package mocks -destination ./testutil/mocks/cwclient_mock.go -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - reflect "reflect" - - types "github.com/babylonlabs-io/finality-gadget/types" - gomock "go.uber.org/mock/gomock" -) - -// MockICosmWasmClient is a mock of ICosmWasmClient interface. -type MockICosmWasmClient struct { - ctrl *gomock.Controller - recorder *MockICosmWasmClientMockRecorder -} - -// MockICosmWasmClientMockRecorder is the mock recorder for MockICosmWasmClient. -type MockICosmWasmClientMockRecorder struct { - mock *MockICosmWasmClient -} - -// NewMockICosmWasmClient creates a new mock instance. -func NewMockICosmWasmClient(ctrl *gomock.Controller) *MockICosmWasmClient { - mock := &MockICosmWasmClient{ctrl: ctrl} - mock.recorder = &MockICosmWasmClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockICosmWasmClient) EXPECT() *MockICosmWasmClientMockRecorder { - return m.recorder -} - -// QueryConsumerId mocks base method. -func (m *MockICosmWasmClient) QueryConsumerId() (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryConsumerId") - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryConsumerId indicates an expected call of QueryConsumerId. -func (mr *MockICosmWasmClientMockRecorder) QueryConsumerId() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryConsumerId", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryConsumerId)) -} - -// QueryIsEnabled mocks base method. -func (m *MockICosmWasmClient) QueryIsEnabled() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryIsEnabled") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryIsEnabled indicates an expected call of QueryIsEnabled. -func (mr *MockICosmWasmClientMockRecorder) QueryIsEnabled() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsEnabled", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryIsEnabled)) -} - -// QueryListOfVotedFinalityProviders mocks base method. -func (m *MockICosmWasmClient) QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryListOfVotedFinalityProviders", queryParams) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryListOfVotedFinalityProviders indicates an expected call of QueryListOfVotedFinalityProviders. -func (mr *MockICosmWasmClientMockRecorder) QueryListOfVotedFinalityProviders(queryParams any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryListOfVotedFinalityProviders", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryListOfVotedFinalityProviders), queryParams) -} diff --git a/testutil/mocks/expected_clients_mock.go b/testutil/mocks/expected_clients_mock.go new file mode 100644 index 0000000..6ad6642 --- /dev/null +++ b/testutil/mocks/expected_clients_mock.go @@ -0,0 +1,321 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: finalitygadget/expected_clients.go +// +// Generated by this command: +// +// mockgen -source=finalitygadget/expected_clients.go -package mocks -destination ./testutil/mocks/expected_clients_mock.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + big "math/big" + reflect "reflect" + + types "github.com/babylonlabs-io/finality-gadget/types" + chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" + wire "github.com/btcsuite/btcd/wire" + types0 "github.com/ethereum/go-ethereum/core/types" + gomock "go.uber.org/mock/gomock" +) + +// MockIBitcoinClient is a mock of IBitcoinClient interface. +type MockIBitcoinClient struct { + ctrl *gomock.Controller + recorder *MockIBitcoinClientMockRecorder +} + +// MockIBitcoinClientMockRecorder is the mock recorder for MockIBitcoinClient. +type MockIBitcoinClientMockRecorder struct { + mock *MockIBitcoinClient +} + +// NewMockIBitcoinClient creates a new mock instance. +func NewMockIBitcoinClient(ctrl *gomock.Controller) *MockIBitcoinClient { + mock := &MockIBitcoinClient{ctrl: ctrl} + mock.recorder = &MockIBitcoinClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIBitcoinClient) EXPECT() *MockIBitcoinClientMockRecorder { + return m.recorder +} + +// GetBlockCount mocks base method. +func (m *MockIBitcoinClient) GetBlockCount() (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockCount") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockCount indicates an expected call of GetBlockCount. +func (mr *MockIBitcoinClientMockRecorder) GetBlockCount() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockCount", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockCount)) +} + +// GetBlockHashByHeight mocks base method. +func (m *MockIBitcoinClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockHashByHeight", height) + ret0, _ := ret[0].(*chainhash.Hash) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockHashByHeight indicates an expected call of GetBlockHashByHeight. +func (mr *MockIBitcoinClientMockRecorder) GetBlockHashByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHashByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHashByHeight), height) +} + +// GetBlockHeaderByHash mocks base method. +func (m *MockIBitcoinClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockHeaderByHash", blockHash) + ret0, _ := ret[0].(*wire.BlockHeader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockHeaderByHash indicates an expected call of GetBlockHeaderByHash. +func (mr *MockIBitcoinClientMockRecorder) GetBlockHeaderByHash(blockHash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeaderByHash", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeaderByHash), blockHash) +} + +// GetBlockHeightByTimestamp mocks base method. +func (m *MockIBitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockHeightByTimestamp", targetTimestamp) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockHeightByTimestamp indicates an expected call of GetBlockHeightByTimestamp. +func (mr *MockIBitcoinClientMockRecorder) GetBlockHeightByTimestamp(targetTimestamp any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockHeightByTimestamp", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockHeightByTimestamp), targetTimestamp) +} + +// GetBlockTimestampByHeight mocks base method. +func (m *MockIBitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockTimestampByHeight", height) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlockTimestampByHeight indicates an expected call of GetBlockTimestampByHeight. +func (mr *MockIBitcoinClientMockRecorder) GetBlockTimestampByHeight(height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockTimestampByHeight", reflect.TypeOf((*MockIBitcoinClient)(nil).GetBlockTimestampByHeight), height) +} + +// MockIBabylonClient is a mock of IBabylonClient interface. +type MockIBabylonClient struct { + ctrl *gomock.Controller + recorder *MockIBabylonClientMockRecorder +} + +// MockIBabylonClientMockRecorder is the mock recorder for MockIBabylonClient. +type MockIBabylonClientMockRecorder struct { + mock *MockIBabylonClient +} + +// NewMockIBabylonClient creates a new mock instance. +func NewMockIBabylonClient(ctrl *gomock.Controller) *MockIBabylonClient { + mock := &MockIBabylonClient{ctrl: ctrl} + mock.recorder = &MockIBabylonClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIBabylonClient) EXPECT() *MockIBabylonClientMockRecorder { + return m.recorder +} + +// QueryAllFpBtcPubKeys mocks base method. +func (m *MockIBabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryAllFpBtcPubKeys", consumerId) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryAllFpBtcPubKeys indicates an expected call of QueryAllFpBtcPubKeys. +func (mr *MockIBabylonClientMockRecorder) QueryAllFpBtcPubKeys(consumerId any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryAllFpBtcPubKeys", reflect.TypeOf((*MockIBabylonClient)(nil).QueryAllFpBtcPubKeys), consumerId) +} + +// QueryEarliestActiveDelBtcHeight mocks base method. +func (m *MockIBabylonClient) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryEarliestActiveDelBtcHeight", fpPubkeyHexList) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryEarliestActiveDelBtcHeight indicates an expected call of QueryEarliestActiveDelBtcHeight. +func (mr *MockIBabylonClientMockRecorder) QueryEarliestActiveDelBtcHeight(fpPubkeyHexList any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryEarliestActiveDelBtcHeight", reflect.TypeOf((*MockIBabylonClient)(nil).QueryEarliestActiveDelBtcHeight), fpPubkeyHexList) +} + +// QueryFpPower mocks base method. +func (m *MockIBabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryFpPower", fpPubkeyHex, btcHeight) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryFpPower indicates an expected call of QueryFpPower. +func (mr *MockIBabylonClientMockRecorder) QueryFpPower(fpPubkeyHex, btcHeight any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryFpPower), fpPubkeyHex, btcHeight) +} + +// QueryMultiFpPower mocks base method. +func (m *MockIBabylonClient) QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryMultiFpPower", fpPubkeyHexList, btcHeight) + ret0, _ := ret[0].(map[string]uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryMultiFpPower indicates an expected call of QueryMultiFpPower. +func (mr *MockIBabylonClientMockRecorder) QueryMultiFpPower(fpPubkeyHexList, btcHeight any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryMultiFpPower", reflect.TypeOf((*MockIBabylonClient)(nil).QueryMultiFpPower), fpPubkeyHexList, btcHeight) +} + +// MockICosmWasmClient is a mock of ICosmWasmClient interface. +type MockICosmWasmClient struct { + ctrl *gomock.Controller + recorder *MockICosmWasmClientMockRecorder +} + +// MockICosmWasmClientMockRecorder is the mock recorder for MockICosmWasmClient. +type MockICosmWasmClientMockRecorder struct { + mock *MockICosmWasmClient +} + +// NewMockICosmWasmClient creates a new mock instance. +func NewMockICosmWasmClient(ctrl *gomock.Controller) *MockICosmWasmClient { + mock := &MockICosmWasmClient{ctrl: ctrl} + mock.recorder = &MockICosmWasmClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockICosmWasmClient) EXPECT() *MockICosmWasmClientMockRecorder { + return m.recorder +} + +// QueryConsumerId mocks base method. +func (m *MockICosmWasmClient) QueryConsumerId() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryConsumerId") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryConsumerId indicates an expected call of QueryConsumerId. +func (mr *MockICosmWasmClientMockRecorder) QueryConsumerId() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryConsumerId", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryConsumerId)) +} + +// QueryIsEnabled mocks base method. +func (m *MockICosmWasmClient) QueryIsEnabled() (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryIsEnabled") + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryIsEnabled indicates an expected call of QueryIsEnabled. +func (mr *MockICosmWasmClientMockRecorder) QueryIsEnabled() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsEnabled", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryIsEnabled)) +} + +// QueryListOfVotedFinalityProviders mocks base method. +func (m *MockICosmWasmClient) QueryListOfVotedFinalityProviders(queryParams *types.Block) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryListOfVotedFinalityProviders", queryParams) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryListOfVotedFinalityProviders indicates an expected call of QueryListOfVotedFinalityProviders. +func (mr *MockICosmWasmClientMockRecorder) QueryListOfVotedFinalityProviders(queryParams any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryListOfVotedFinalityProviders", reflect.TypeOf((*MockICosmWasmClient)(nil).QueryListOfVotedFinalityProviders), queryParams) +} + +// MockIEthL2Client is a mock of IEthL2Client interface. +type MockIEthL2Client struct { + ctrl *gomock.Controller + recorder *MockIEthL2ClientMockRecorder +} + +// MockIEthL2ClientMockRecorder is the mock recorder for MockIEthL2Client. +type MockIEthL2ClientMockRecorder struct { + mock *MockIEthL2Client +} + +// NewMockIEthL2Client creates a new mock instance. +func NewMockIEthL2Client(ctrl *gomock.Controller) *MockIEthL2Client { + mock := &MockIEthL2Client{ctrl: ctrl} + mock.recorder = &MockIEthL2ClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIEthL2Client) EXPECT() *MockIEthL2ClientMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockIEthL2Client) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockIEthL2ClientMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockIEthL2Client)(nil).Close)) +} + +// HeaderByNumber mocks base method. +func (m *MockIEthL2Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types0.Header, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeaderByNumber", ctx, number) + ret0, _ := ret[0].(*types0.Header) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeaderByNumber indicates an expected call of HeaderByNumber. +func (mr *MockIEthL2ClientMockRecorder) HeaderByNumber(ctx, number any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByNumber", reflect.TypeOf((*MockIEthL2Client)(nil).HeaderByNumber), ctx, number) +} diff --git a/testutil/mocks/finalitygadget_mock.go b/testutil/mocks/finalitygadget_mock.go deleted file mode 100644 index beb798a..0000000 --- a/testutil/mocks/finalitygadget_mock.go +++ /dev/null @@ -1,174 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: finalitygadget/interface.go -// -// Generated by this command: -// -// mockgen -source=finalitygadget/interface.go -package mocks -destination ./testutil/mocks/finalitygadget_mock.go -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - reflect "reflect" - - types "github.com/babylonlabs-io/finality-gadget/types" - gomock "go.uber.org/mock/gomock" -) - -// MockIFinalityGadget is a mock of IFinalityGadget interface. -type MockIFinalityGadget struct { - ctrl *gomock.Controller - recorder *MockIFinalityGadgetMockRecorder -} - -// MockIFinalityGadgetMockRecorder is the mock recorder for MockIFinalityGadget. -type MockIFinalityGadgetMockRecorder struct { - mock *MockIFinalityGadget -} - -// NewMockIFinalityGadget creates a new mock instance. -func NewMockIFinalityGadget(ctrl *gomock.Controller) *MockIFinalityGadget { - mock := &MockIFinalityGadget{ctrl: ctrl} - mock.recorder = &MockIFinalityGadgetMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIFinalityGadget) EXPECT() *MockIFinalityGadgetMockRecorder { - return m.recorder -} - -// GetBlockByHash mocks base method. -func (m *MockIFinalityGadget) GetBlockByHash(hash string) (*types.Block, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockByHash", hash) - ret0, _ := ret[0].(*types.Block) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockByHash indicates an expected call of GetBlockByHash. -func (mr *MockIFinalityGadgetMockRecorder) GetBlockByHash(hash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHash", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockByHash), hash) -} - -// GetBlockByHeight mocks base method. -func (m *MockIFinalityGadget) GetBlockByHeight(height uint64) (*types.Block, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockByHeight", height) - ret0, _ := ret[0].(*types.Block) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockByHeight indicates an expected call of GetBlockByHeight. -func (mr *MockIFinalityGadgetMockRecorder) GetBlockByHeight(height any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHeight", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockByHeight), height) -} - -// GetBlockStatusByHash mocks base method. -func (m *MockIFinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockStatusByHash", hash) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockStatusByHash indicates an expected call of GetBlockStatusByHash. -func (mr *MockIFinalityGadgetMockRecorder) GetBlockStatusByHash(hash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHash", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockStatusByHash), hash) -} - -// GetBlockStatusByHeight mocks base method. -func (m *MockIFinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockStatusByHeight", height) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBlockStatusByHeight indicates an expected call of GetBlockStatusByHeight. -func (mr *MockIFinalityGadgetMockRecorder) GetBlockStatusByHeight(height any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHeight", reflect.TypeOf((*MockIFinalityGadget)(nil).GetBlockStatusByHeight), height) -} - -// GetLatestBlock mocks base method. -func (m *MockIFinalityGadget) GetLatestBlock() (*types.Block, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLatestBlock") - ret0, _ := ret[0].(*types.Block) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetLatestBlock indicates an expected call of GetLatestBlock. -func (mr *MockIFinalityGadgetMockRecorder) GetLatestBlock() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestBlock", reflect.TypeOf((*MockIFinalityGadget)(nil).GetLatestBlock)) -} - -// InsertBlock mocks base method. -func (m *MockIFinalityGadget) InsertBlock(block *types.Block) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InsertBlock", block) - ret0, _ := ret[0].(error) - return ret0 -} - -// InsertBlock indicates an expected call of InsertBlock. -func (mr *MockIFinalityGadgetMockRecorder) InsertBlock(block any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockIFinalityGadget)(nil).InsertBlock), block) -} - -// QueryBlockRangeBabylonFinalized mocks base method. -func (m *MockIFinalityGadget) QueryBlockRangeBabylonFinalized(queryBlocks []*types.Block) (*uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryBlockRangeBabylonFinalized", queryBlocks) - ret0, _ := ret[0].(*uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryBlockRangeBabylonFinalized indicates an expected call of QueryBlockRangeBabylonFinalized. -func (mr *MockIFinalityGadgetMockRecorder) QueryBlockRangeBabylonFinalized(queryBlocks any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBlockRangeBabylonFinalized", reflect.TypeOf((*MockIFinalityGadget)(nil).QueryBlockRangeBabylonFinalized), queryBlocks) -} - -// QueryBtcStakingActivatedTimestamp mocks base method. -func (m *MockIFinalityGadget) QueryBtcStakingActivatedTimestamp() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryBtcStakingActivatedTimestamp") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryBtcStakingActivatedTimestamp indicates an expected call of QueryBtcStakingActivatedTimestamp. -func (mr *MockIFinalityGadgetMockRecorder) QueryBtcStakingActivatedTimestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBtcStakingActivatedTimestamp", reflect.TypeOf((*MockIFinalityGadget)(nil).QueryBtcStakingActivatedTimestamp)) -} - -// QueryIsBlockBabylonFinalized mocks base method. -func (m *MockIFinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryIsBlockBabylonFinalized", block) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryIsBlockBabylonFinalized indicates an expected call of QueryIsBlockBabylonFinalized. -func (mr *MockIFinalityGadgetMockRecorder) QueryIsBlockBabylonFinalized(block any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockBabylonFinalized", reflect.TypeOf((*MockIFinalityGadget)(nil).QueryIsBlockBabylonFinalized), block) -} From 1252b28c5e9c0093c436c3728295f81cbf08b377 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:27:51 +0100 Subject: [PATCH 84/93] remove unused quit chan --- server/server.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/server.go b/server/server.go index 1d194fe..3c5a17a 100644 --- a/server/server.go +++ b/server/server.go @@ -25,7 +25,6 @@ type Server struct { logger *zap.Logger - quit chan struct{} interceptor signal.Interceptor started int32 } @@ -38,7 +37,6 @@ func NewFinalityGadgetServer(cfg *config.Config, db db.IDatabaseHandler, fg fina db: db, logger: logger, interceptor: sig, - quit: make(chan struct{}, 1), } } From e63afa961679e81ae076432f6fcb6d39a1abb40b Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:30:03 +0100 Subject: [PATCH 85/93] feat: simplify grpc insertBlock response --- client/rpcclient.go | 4 +- proto/finalitygadget.pb.go | 90 +++++++++++++++++--------------------- proto/finalitygadget.proto | 5 +-- server/rpcserver.go | 4 +- 4 files changed, 44 insertions(+), 59 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index d56cea2..d4a1d43 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -42,12 +42,12 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) BlockTimestamp: block.BlockTimestamp, } - res, err := c.client.InsertBlock(context.Background(), req) + _, err := c.client.InsertBlock(context.Background(), req) if err != nil { return false, err } - return res.Success, nil + return true, nil } func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go index 21bedbb..a11243e 100644 --- a/proto/finalitygadget.pb.go +++ b/proto/finalitygadget.pb.go @@ -90,9 +90,6 @@ type InsertBlockResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - // success is true if the block is successfully inserted - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` } func (x *InsertBlockResponse) Reset() { @@ -127,13 +124,6 @@ func (*InsertBlockResponse) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} } -func (x *InsertBlockResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - type GetBlockStatusByHeightRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -328,49 +318,47 @@ var file_proto_finalitygadget_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x2f, 0x0a, 0x13, 0x49, + 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x42, 0x0a, 0x1d, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x22, 0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, - 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x69, 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, + 0x73, 0x65, 0x22, 0x42, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0xc9, 0x02, 0x0a, 0x0e, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, 0x3b, 0x0a, + 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x1a, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x32, 0xc9, 0x02, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, - 0x79, 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x24, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, - 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, - 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, - 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x62, 0x61, - 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x2d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, - 0x61, 0x64, 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, + 0x2d, 0x69, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, + 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index d64c3d6..2a76eb3 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -30,10 +30,7 @@ message BlockInfo { uint64 block_timestamp = 3; } -message InsertBlockResponse { - // success is true if the block is successfully inserted - bool success = 1; -} +message InsertBlockResponse {} message GetBlockStatusByHeightRequest { // block_height is the height of the block diff --git a/server/rpcserver.go b/server/rpcserver.go index 543ee74..b592819 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -44,10 +44,10 @@ func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*pro }) if err != nil { - return &proto.InsertBlockResponse{Success: false}, err + return &proto.InsertBlockResponse{}, err } - return &proto.InsertBlockResponse{Success: true}, nil + return &proto.InsertBlockResponse{}, nil } // GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. From f4119cda7e0181c8f0e34e1670330b3f9bdc9d0d Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:31:52 +0100 Subject: [PATCH 86/93] chore: config.toml.example --- .gitignore | 3 ++- README.md | 8 +++++++- config.toml.example | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 config.toml.example diff --git a/.gitignore b/.gitignore index 4baa48f..a8514ac 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .DS_Store **/.env **/*.db -*.db \ No newline at end of file +*.db +config.toml \ No newline at end of file diff --git a/README.md b/README.md index 2e5339f..f86b6d8 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,13 @@ To get started, clone the repository. git clone https://github.com/babylonlabs-io/finality-gadget.git ``` -Configure the `config.toml` file: +Copy the `config.toml.example` file to `config.toml`: + +```bash +cp config.toml.example config.toml +``` + +Configure the `config.toml` file with the following parameters: ```toml L2RPCHost = # RPC URL of OP stack L2 chain diff --git a/config.toml.example b/config.toml.example new file mode 100644 index 0000000..338f0c8 --- /dev/null +++ b/config.toml.example @@ -0,0 +1,8 @@ +L2RPCHost = "https://mainnet.optimism.io" +BitcoinRPCHost = "rpc.ankr.com/btc" +DBFilePath = "data.db" +FGContractAddress = "bbn1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqxxvh0f" +BBNChainID = "euphrates-0.2.0" +BBNRPCAddress = "https://rpc-euphrates.devnet.babylonchain.io" +GRPCServerPort = "8080" +PollInterval = "10s" \ No newline at end of file From d7bb5de76588ce82663fe543d3405be123a7c153 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:37:55 +0100 Subject: [PATCH 87/93] chore: rename fns for consistency --- client/rpcclient.go | 12 ++--- db/bbolt.go | 6 +-- db/bbolt_test.go | 16 +++---- db/interface.go | 4 +- finalitygadget/finalitygadget.go | 14 +++--- finalitygadget/finalitygadget_test.go | 34 +++++++------- finalitygadget/interface.go | 8 ++-- proto/finalitygadget.pb.go | 52 +++++++++++----------- proto/finalitygadget.proto | 15 ++++--- proto/finalitygadget_grpc.pb.go | 64 +++++++++++++-------------- server/rpcserver.go | 12 ++--- testutil/mocks/db_mock.go | 24 +++++----- 12 files changed, 131 insertions(+), 130 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index d4a1d43..880bbc9 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -50,12 +50,12 @@ func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) return true, nil } -func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, error) { - req := &proto.GetBlockStatusByHeightRequest{ +func (c *FinalityGadgetGrpcClient) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) { + req := &proto.QueryIsBlockFinalizedByHeightRequest{ BlockHeight: height, } - res, err := c.client.GetBlockStatusByHeight(context.Background(), req) + res, err := c.client.QueryIsBlockFinalizedByHeight(context.Background(), req) if err != nil { return false, err } @@ -63,12 +63,12 @@ func (c *FinalityGadgetGrpcClient) GetBlockStatusByHeight(height uint64) (bool, return res.IsFinalized, nil } -func (c *FinalityGadgetGrpcClient) GetBlockStatusByHash(hash string) (bool, error) { - req := &proto.GetBlockStatusByHashRequest{ +func (c *FinalityGadgetGrpcClient) QueryIsBlockFinalizedByHash(hash string) (bool, error) { + req := &proto.QueryIsBlockFinalizedByHashRequest{ BlockHash: hash, } - res, err := c.client.GetBlockStatusByHash(context.Background(), req) + res, err := c.client.QueryIsBlockFinalizedByHash(context.Background(), req) if err != nil { return false, err } diff --git a/db/bbolt.go b/db/bbolt.go index 36ebd42..da5c8cc 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -156,7 +156,7 @@ func (bb *BBoltHandler) GetBlockByHash(hash string) (*types.Block, error) { return bb.GetBlockByHeight(blockHeight) } -func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { +func (bb *BBoltHandler) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) { _, err := bb.GetBlockByHeight(height) if err != nil { if errors.Is(err, types.ErrBlockNotFound) { @@ -167,7 +167,7 @@ func (bb *BBoltHandler) GetBlockStatusByHeight(height uint64) (bool, error) { return true, nil } -func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { +func (bb *BBoltHandler) QueryIsBlockFinalizedByHash(hash string) (bool, error) { // Fetch block number by hash var blockHeight uint64 err := bb.db.View(func(tx *bolt.Tx) error { @@ -186,7 +186,7 @@ func (bb *BBoltHandler) GetBlockStatusByHash(hash string) (bool, error) { return false, err } - return bb.GetBlockStatusByHeight(blockHeight) + return bb.QueryIsBlockFinalizedByHeight(blockHeight) } func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { diff --git a/db/bbolt_test.go b/db/bbolt_test.go index 3bfadb7..a9f2023 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -128,7 +128,7 @@ func TestGetBlockByHashForNonExistentBlock(t *testing.T) { assert.Equal(t, types.ErrBlockNotFound, err) } -func TestGetBlockStatusByHeight(t *testing.T) { +func TestQueryIsBlockFinalizedByHeight(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() @@ -142,21 +142,21 @@ func TestGetBlockStatusByHeight(t *testing.T) { assert.NoError(t, err) // Retrieve block status by height - isFinalized, err := handler.GetBlockStatusByHeight(block.BlockHeight) + isFinalized, err := handler.QueryIsBlockFinalizedByHeight(block.BlockHeight) assert.NoError(t, err) assert.Equal(t, isFinalized, true) } -func TestGetBlockStatusByHeightForNonExistentBlock(t *testing.T) { +func TestQueryIsBlockFinalizedByHeightForNonExistentBlock(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() - isFinalized, err := handler.GetBlockStatusByHeight(1) + isFinalized, err := handler.QueryIsBlockFinalizedByHeight(1) assert.NoError(t, err) assert.Equal(t, isFinalized, false) } -func TestGetBlockStatusByHash(t *testing.T) { +func TestQueryIsBlockFinalizedByHash(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() @@ -170,16 +170,16 @@ func TestGetBlockStatusByHash(t *testing.T) { assert.NoError(t, err) // Retrieve block status by hash - isFinalized, err := handler.GetBlockStatusByHash(block.BlockHash) + isFinalized, err := handler.QueryIsBlockFinalizedByHash(block.BlockHash) assert.NoError(t, err) assert.Equal(t, isFinalized, true) } -func TestGetBlockStatusByHashForNonExistentBlock(t *testing.T) { +func TestQueryIsBlockFinalizedByHashForNonExistentBlock(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() - isFinalized, err := handler.GetBlockStatusByHash("0x123") + isFinalized, err := handler.QueryIsBlockFinalizedByHash("0x123") assert.NoError(t, err) assert.Equal(t, isFinalized, false) } diff --git a/db/interface.go b/db/interface.go index 2d410ef..649fc0d 100644 --- a/db/interface.go +++ b/db/interface.go @@ -7,8 +7,8 @@ type IDatabaseHandler interface { InsertBlock(block *types.Block) error GetBlockByHeight(height uint64) (*types.Block, error) GetBlockByHash(hash string) (*types.Block, error) - GetBlockStatusByHeight(height uint64) (bool, error) - GetBlockStatusByHash(hash string) (bool, error) + QueryIsBlockFinalizedByHeight(height uint64) (bool, error) + QueryIsBlockFinalizedByHash(hash string) (bool, error) GetLatestBlock() (*types.Block, error) DeleteDB() error Close() error diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 3e33c6f..9863a9c 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -280,12 +280,12 @@ func (fg *FinalityGadget) GetBlockByHash(hash string) (*types.Block, error) { return fg.db.GetBlockByHash(normalizeBlockHash(hash)) } -func (fg *FinalityGadget) GetBlockStatusByHeight(height uint64) (bool, error) { - return fg.db.GetBlockStatusByHeight(height) +func (fg *FinalityGadget) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) { + return fg.db.QueryIsBlockFinalizedByHeight(height) } -func (fg *FinalityGadget) GetBlockStatusByHash(hash string) (bool, error) { - return fg.db.GetBlockStatusByHash(normalizeBlockHash(hash)) +func (fg *FinalityGadget) QueryIsBlockFinalizedByHash(hash string) (bool, error) { + return fg.db.QueryIsBlockFinalizedByHash(normalizeBlockHash(hash)) } func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { @@ -308,7 +308,7 @@ func (fg *FinalityGadget) ProcessBlocks(ctx context.Context) error { case <-ctx.Done(): return nil case <-ticker.C: - block, err := fg.getBlockByNumber(int64(fg.currHeight + 1)) + block, err := fg.queryBlockByHeight(int64(fg.currHeight + 1)) if err != nil { fg.logger.Fatal("error getting new block", zap.Error(err)) continue @@ -369,11 +369,11 @@ func (fg *FinalityGadget) queryAllFpBtcPubKeys() ([]string, error) { // Get last btc finalized block func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { - return fg.getBlockByNumber(ethrpc.FinalizedBlockNumber.Int64()) + return fg.queryBlockByHeight(ethrpc.FinalizedBlockNumber.Int64()) } // Get block by number -func (fg *FinalityGadget) getBlockByNumber(blockNumber int64) (*types.Block, error) { +func (fg *FinalityGadget) queryBlockByHeight(blockNumber int64) (*types.Block, error) { header, err := fg.l2Client.HeaderByNumber(context.Background(), big.NewInt(blockNumber)) if err != nil { return nil, err diff --git a/finalitygadget/finalitygadget_test.go b/finalitygadget/finalitygadget_test.go index 40b1c49..88cd57d 100644 --- a/finalitygadget/finalitygadget_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -427,94 +427,94 @@ func TestGetBlockByHashForNonExistentBlock(t *testing.T) { require.Equal(t, err, types.ErrBlockNotFound) } -func TestGetBlockStatusByHeight(t *testing.T) { +func TestQueryIsBlockFinalizedByHeight(t *testing.T) { blockHeight := uint64(1) // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetBlockStatusByHeight(blockHeight).Return(true, nil).Times(1) + mockDbHandler.EXPECT().QueryIsBlockFinalizedByHeight(blockHeight).Return(true, nil).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch block status by height - isFinalized, err := mockFinalityGadget.GetBlockStatusByHeight(1) + isFinalized, err := mockFinalityGadget.QueryIsBlockFinalizedByHeight(1) require.NoError(t, err) require.True(t, isFinalized) } -func TestGetBlockStatusByHeightForNonExistentBlock(t *testing.T) { +func TestQueryIsBlockFinalizedByHeightForNonExistentBlock(t *testing.T) { // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetBlockStatusByHeight(uint64(1)).Return(false, types.ErrBlockNotFound).Times(1) + mockDbHandler.EXPECT().QueryIsBlockFinalizedByHeight(uint64(1)).Return(false, types.ErrBlockNotFound).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch block status by height - isFinalized, err := mockFinalityGadget.GetBlockStatusByHeight(1) + isFinalized, err := mockFinalityGadget.QueryIsBlockFinalizedByHeight(1) require.False(t, isFinalized) require.Equal(t, err, types.ErrBlockNotFound) } -func TestGetBlockStatusByHashWith0xPrefix(t *testing.T) { +func TestQueryIsBlockFinalizedByHashWith0xPrefix(t *testing.T) { // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetBlockStatusByHash(normalizeBlockHash("0x123")).Return(true, nil).Times(2) + mockDbHandler.EXPECT().QueryIsBlockFinalizedByHash(normalizeBlockHash("0x123")).Return(true, nil).Times(2) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch block status by hash including 0x prefix - isFinalized, err := mockFinalityGadget.GetBlockStatusByHash("0x123") + isFinalized, err := mockFinalityGadget.QueryIsBlockFinalizedByHash("0x123") require.NoError(t, err) require.True(t, isFinalized) // fetch block status by hash excluding 0x prefix - isFinalized, err = mockFinalityGadget.GetBlockStatusByHash("123") + isFinalized, err = mockFinalityGadget.QueryIsBlockFinalizedByHash("123") require.NoError(t, err) require.True(t, isFinalized) } -func TestGetBlockStatusByHashWithout0xPrefix(t *testing.T) { +func TestQueryIsBlockFinalizedByHashWithout0xPrefix(t *testing.T) { // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetBlockStatusByHash(normalizeBlockHash("123")).Return(true, nil).Times(2) + mockDbHandler.EXPECT().QueryIsBlockFinalizedByHash(normalizeBlockHash("123")).Return(true, nil).Times(2) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch block status by hash including 0x prefix - isFinalized, err := mockFinalityGadget.GetBlockStatusByHash("0x123") + isFinalized, err := mockFinalityGadget.QueryIsBlockFinalizedByHash("0x123") require.NoError(t, err) require.True(t, isFinalized) // fetch block status by hash excluding 0x prefix - isFinalized, err = mockFinalityGadget.GetBlockStatusByHash("123") + isFinalized, err = mockFinalityGadget.QueryIsBlockFinalizedByHash("123") require.NoError(t, err) require.True(t, isFinalized) } -func TestGetBlockStatusByHashForNonExistentBlock(t *testing.T) { +func TestQueryIsBlockFinalizedByHashForNonExistentBlock(t *testing.T) { // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetBlockStatusByHash(normalizeBlockHash("123")).Return(false, types.ErrBlockNotFound).Times(1) + mockDbHandler.EXPECT().QueryIsBlockFinalizedByHash(normalizeBlockHash("123")).Return(false, types.ErrBlockNotFound).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch block status by hash - isFinalized, err := mockFinalityGadget.GetBlockStatusByHash("123") + isFinalized, err := mockFinalityGadget.QueryIsBlockFinalizedByHash("123") require.False(t, isFinalized) require.Equal(t, err, types.ErrBlockNotFound) } diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go index 4212d6a..45e8a3e 100644 --- a/finalitygadget/interface.go +++ b/finalitygadget/interface.go @@ -64,11 +64,11 @@ type IFinalityGadget interface { // GetBlockByHash returns the btc finalized block at given hash by querying the local db GetBlockByHash(hash string) (*types.Block, error) - // GetBlockStatusByHeight returns the btc finalization status of a block at given height by querying the local db - GetBlockStatusByHeight(height uint64) (bool, error) + // QueryIsBlockFinalizedByHeight returns the btc finalization status of a block at given height by querying the local db + QueryIsBlockFinalizedByHeight(height uint64) (bool, error) - // GetBlockStatusByHash returns the btc finalization status of a block at given hash by querying the local db - GetBlockStatusByHash(hash string) (bool, error) + // QueryIsBlockFinalizedByHash returns the btc finalization status of a block at given hash by querying the local db + QueryIsBlockFinalizedByHash(hash string) (bool, error) // GetLatestBlock returns the latest finalized block by querying the local db GetLatestBlock() (*types.Block, error) diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go index a11243e..c4eba93 100644 --- a/proto/finalitygadget.pb.go +++ b/proto/finalitygadget.pb.go @@ -124,7 +124,7 @@ func (*InsertBlockResponse) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} } -type GetBlockStatusByHeightRequest struct { +type QueryIsBlockFinalizedByHeightRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -133,8 +133,8 @@ type GetBlockStatusByHeightRequest struct { BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` } -func (x *GetBlockStatusByHeightRequest) Reset() { - *x = GetBlockStatusByHeightRequest{} +func (x *QueryIsBlockFinalizedByHeightRequest) Reset() { + *x = QueryIsBlockFinalizedByHeightRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -142,13 +142,13 @@ func (x *GetBlockStatusByHeightRequest) Reset() { } } -func (x *GetBlockStatusByHeightRequest) String() string { +func (x *QueryIsBlockFinalizedByHeightRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlockStatusByHeightRequest) ProtoMessage() {} +func (*QueryIsBlockFinalizedByHeightRequest) ProtoMessage() {} -func (x *GetBlockStatusByHeightRequest) ProtoReflect() protoreflect.Message { +func (x *QueryIsBlockFinalizedByHeightRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -160,19 +160,19 @@ func (x *GetBlockStatusByHeightRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlockStatusByHeightRequest.ProtoReflect.Descriptor instead. -func (*GetBlockStatusByHeightRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryIsBlockFinalizedByHeightRequest.ProtoReflect.Descriptor instead. +func (*QueryIsBlockFinalizedByHeightRequest) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} } -func (x *GetBlockStatusByHeightRequest) GetBlockHeight() uint64 { +func (x *QueryIsBlockFinalizedByHeightRequest) GetBlockHeight() uint64 { if x != nil { return x.BlockHeight } return 0 } -type GetBlockStatusByHashRequest struct { +type QueryIsBlockFinalizedByHashRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -181,8 +181,8 @@ type GetBlockStatusByHashRequest struct { BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` } -func (x *GetBlockStatusByHashRequest) Reset() { - *x = GetBlockStatusByHashRequest{} +func (x *QueryIsBlockFinalizedByHashRequest) Reset() { + *x = QueryIsBlockFinalizedByHashRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -190,13 +190,13 @@ func (x *GetBlockStatusByHashRequest) Reset() { } } -func (x *GetBlockStatusByHashRequest) String() string { +func (x *QueryIsBlockFinalizedByHashRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlockStatusByHashRequest) ProtoMessage() {} +func (*QueryIsBlockFinalizedByHashRequest) ProtoMessage() {} -func (x *GetBlockStatusByHashRequest) ProtoReflect() protoreflect.Message { +func (x *QueryIsBlockFinalizedByHashRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -208,12 +208,12 @@ func (x *GetBlockStatusByHashRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlockStatusByHashRequest.ProtoReflect.Descriptor instead. -func (*GetBlockStatusByHashRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryIsBlockFinalizedByHashRequest.ProtoReflect.Descriptor instead. +func (*QueryIsBlockFinalizedByHashRequest) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} } -func (x *GetBlockStatusByHashRequest) GetBlockHash() string { +func (x *QueryIsBlockFinalizedByHashRequest) GetBlockHash() string { if x != nil { return x.BlockHash } @@ -377,19 +377,19 @@ var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_proto_finalitygadget_proto_goTypes = []interface{}{ (*BlockInfo)(nil), // 0: proto.BlockInfo (*InsertBlockResponse)(nil), // 1: proto.InsertBlockResponse - (*GetBlockStatusByHeightRequest)(nil), // 2: proto.GetBlockStatusByHeightRequest - (*GetBlockStatusByHashRequest)(nil), // 3: proto.GetBlockStatusByHashRequest + (*QueryIsBlockFinalizedByHeightRequest)(nil), // 2: proto.QueryIsBlockFinalizedByHeightRequest + (*QueryIsBlockFinalizedByHashRequest)(nil), // 3: proto.QueryIsBlockFinalizedByHashRequest (*GetBlockStatusResponse)(nil), // 4: proto.GetBlockStatusResponse (*GetLatestBlockRequest)(nil), // 5: proto.GetLatestBlockRequest } var file_proto_finalitygadget_proto_depIdxs = []int32{ 0, // 0: proto.FinalityGadget.InsertBlock:input_type -> proto.BlockInfo - 2, // 1: proto.FinalityGadget.GetBlockStatusByHeight:input_type -> proto.GetBlockStatusByHeightRequest - 3, // 2: proto.FinalityGadget.GetBlockStatusByHash:input_type -> proto.GetBlockStatusByHashRequest + 2, // 1: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:input_type -> proto.QueryIsBlockFinalizedByHeightRequest + 3, // 2: proto.FinalityGadget.QueryIsBlockFinalizedByHash:input_type -> proto.QueryIsBlockFinalizedByHashRequest 5, // 3: proto.FinalityGadget.GetLatestBlock:input_type -> proto.GetLatestBlockRequest 1, // 4: proto.FinalityGadget.InsertBlock:output_type -> proto.InsertBlockResponse - 4, // 5: proto.FinalityGadget.GetBlockStatusByHeight:output_type -> proto.GetBlockStatusResponse - 4, // 6: proto.FinalityGadget.GetBlockStatusByHash:output_type -> proto.GetBlockStatusResponse + 4, // 5: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:output_type -> proto.GetBlockStatusResponse + 4, // 6: proto.FinalityGadget.QueryIsBlockFinalizedByHash:output_type -> proto.GetBlockStatusResponse 0, // 7: proto.FinalityGadget.GetLatestBlock:output_type -> proto.BlockInfo 4, // [4:8] is the sub-list for method output_type 0, // [0:4] is the sub-list for method input_type @@ -429,7 +429,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockStatusByHeightRequest); i { + switch v := v.(*QueryIsBlockFinalizedByHeightRequest); i { case 0: return &v.state case 1: @@ -441,7 +441,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockStatusByHashRequest); i { + switch v := v.(*QueryIsBlockFinalizedByHashRequest); i { case 0: return &v.state case 1: diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index 2a76eb3..e73ab75 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -8,13 +8,14 @@ service FinalityGadget { // InsertBlock inserts a new block into the finality gadget db rpc InsertBlock(BlockInfo) returns (InsertBlockResponse); - // GetBlockStatusByHeight returns the finality status of a block at given - // height - rpc GetBlockStatusByHeight(GetBlockStatusByHeightRequest) + // QueryIsBlockFinalizedByHeight returns the finality status of a block at + // given height + rpc QueryIsBlockFinalizedByHeight(QueryIsBlockFinalizedByHeightRequest) returns (GetBlockStatusResponse); - // GetBlockStatusByHash returns the finality status of a block with given hash - rpc GetBlockStatusByHash(GetBlockStatusByHashRequest) + // QueryIsBlockFinalizedByHash returns the finality status of a block with + // given hash + rpc QueryIsBlockFinalizedByHash(QueryIsBlockFinalizedByHashRequest) returns (GetBlockStatusResponse); // GetLatestBlock returns the latest consecutively finalized block @@ -32,12 +33,12 @@ message BlockInfo { message InsertBlockResponse {} -message GetBlockStatusByHeightRequest { +message QueryIsBlockFinalizedByHeightRequest { // block_height is the height of the block uint64 block_height = 1; } -message GetBlockStatusByHashRequest { +message QueryIsBlockFinalizedByHashRequest { // block_hash is the hash of the block string block_hash = 1; } diff --git a/proto/finalitygadget_grpc.pb.go b/proto/finalitygadget_grpc.pb.go index 5180f93..8628748 100644 --- a/proto/finalitygadget_grpc.pb.go +++ b/proto/finalitygadget_grpc.pb.go @@ -20,8 +20,8 @@ const _ = grpc.SupportPackageIsVersion7 const ( FinalityGadget_InsertBlock_FullMethodName = "/proto.FinalityGadget/InsertBlock" - FinalityGadget_GetBlockStatusByHeight_FullMethodName = "/proto.FinalityGadget/GetBlockStatusByHeight" - FinalityGadget_GetBlockStatusByHash_FullMethodName = "/proto.FinalityGadget/GetBlockStatusByHash" + FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHeight" + FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHash" FinalityGadget_GetLatestBlock_FullMethodName = "/proto.FinalityGadget/GetLatestBlock" ) @@ -31,11 +31,11 @@ const ( type FinalityGadgetClient interface { // InsertBlock inserts a new block into the finality gadget db InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) - // GetBlockStatusByHeight returns the finality status of a block at given + // QueryIsBlockFinalizedByHeight returns the finality status of a block at given // height - GetBlockStatusByHeight(ctx context.Context, in *GetBlockStatusByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) - // GetBlockStatusByHash returns the finality status of a block with given hash - GetBlockStatusByHash(ctx context.Context, in *GetBlockStatusByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) + QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) + // QueryIsBlockFinalizedByHash returns the finality status of a block with given hash + QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) // GetLatestBlock returns the latest consecutively finalized block GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*BlockInfo, error) } @@ -57,18 +57,18 @@ func (c *finalityGadgetClient) InsertBlock(ctx context.Context, in *BlockInfo, o return out, nil } -func (c *finalityGadgetClient) GetBlockStatusByHeight(ctx context.Context, in *GetBlockStatusByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { +func (c *finalityGadgetClient) QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { out := new(GetBlockStatusResponse) - err := c.cc.Invoke(ctx, FinalityGadget_GetBlockStatusByHeight_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *finalityGadgetClient) GetBlockStatusByHash(ctx context.Context, in *GetBlockStatusByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { +func (c *finalityGadgetClient) QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { out := new(GetBlockStatusResponse) - err := c.cc.Invoke(ctx, FinalityGadget_GetBlockStatusByHash_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -90,11 +90,11 @@ func (c *finalityGadgetClient) GetLatestBlock(ctx context.Context, in *GetLatest type FinalityGadgetServer interface { // InsertBlock inserts a new block into the finality gadget db InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) - // GetBlockStatusByHeight returns the finality status of a block at given + // QueryIsBlockFinalizedByHeight returns the finality status of a block at given // height - GetBlockStatusByHeight(context.Context, *GetBlockStatusByHeightRequest) (*GetBlockStatusResponse, error) - // GetBlockStatusByHash returns the finality status of a block with given hash - GetBlockStatusByHash(context.Context, *GetBlockStatusByHashRequest) (*GetBlockStatusResponse, error) + QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) + // QueryIsBlockFinalizedByHash returns the finality status of a block with given hash + QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) // GetLatestBlock returns the latest consecutively finalized block GetLatestBlock(context.Context, *GetLatestBlockRequest) (*BlockInfo, error) mustEmbedUnimplementedFinalityGadgetServer() @@ -107,11 +107,11 @@ type UnimplementedFinalityGadgetServer struct { func (UnimplementedFinalityGadgetServer) InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method InsertBlock not implemented") } -func (UnimplementedFinalityGadgetServer) GetBlockStatusByHeight(context.Context, *GetBlockStatusByHeightRequest) (*GetBlockStatusResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetBlockStatusByHeight not implemented") +func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryIsBlockFinalizedByHeight not implemented") } -func (UnimplementedFinalityGadgetServer) GetBlockStatusByHash(context.Context, *GetBlockStatusByHashRequest) (*GetBlockStatusResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetBlockStatusByHash not implemented") +func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryIsBlockFinalizedByHash not implemented") } func (UnimplementedFinalityGadgetServer) GetLatestBlock(context.Context, *GetLatestBlockRequest) (*BlockInfo, error) { return nil, status.Errorf(codes.Unimplemented, "method GetLatestBlock not implemented") @@ -147,38 +147,38 @@ func _FinalityGadget_InsertBlock_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } -func _FinalityGadget_GetBlockStatusByHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetBlockStatusByHeightRequest) +func _FinalityGadget_QueryIsBlockFinalizedByHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryIsBlockFinalizedByHeightRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(FinalityGadgetServer).GetBlockStatusByHeight(ctx, in) + return srv.(FinalityGadgetServer).QueryIsBlockFinalizedByHeight(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityGadget_GetBlockStatusByHeight_FullMethodName, + FullMethod: FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FinalityGadgetServer).GetBlockStatusByHeight(ctx, req.(*GetBlockStatusByHeightRequest)) + return srv.(FinalityGadgetServer).QueryIsBlockFinalizedByHeight(ctx, req.(*QueryIsBlockFinalizedByHeightRequest)) } return interceptor(ctx, in, info, handler) } -func _FinalityGadget_GetBlockStatusByHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetBlockStatusByHashRequest) +func _FinalityGadget_QueryIsBlockFinalizedByHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryIsBlockFinalizedByHashRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(FinalityGadgetServer).GetBlockStatusByHash(ctx, in) + return srv.(FinalityGadgetServer).QueryIsBlockFinalizedByHash(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityGadget_GetBlockStatusByHash_FullMethodName, + FullMethod: FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FinalityGadgetServer).GetBlockStatusByHash(ctx, req.(*GetBlockStatusByHashRequest)) + return srv.(FinalityGadgetServer).QueryIsBlockFinalizedByHash(ctx, req.(*QueryIsBlockFinalizedByHashRequest)) } return interceptor(ctx, in, info, handler) } @@ -213,12 +213,12 @@ var FinalityGadget_ServiceDesc = grpc.ServiceDesc{ Handler: _FinalityGadget_InsertBlock_Handler, }, { - MethodName: "GetBlockStatusByHeight", - Handler: _FinalityGadget_GetBlockStatusByHeight_Handler, + MethodName: "QueryIsBlockFinalizedByHeight", + Handler: _FinalityGadget_QueryIsBlockFinalizedByHeight_Handler, }, { - MethodName: "GetBlockStatusByHash", - Handler: _FinalityGadget_GetBlockStatusByHash_Handler, + MethodName: "QueryIsBlockFinalizedByHash", + Handler: _FinalityGadget_QueryIsBlockFinalizedByHash_Handler, }, { MethodName: "GetLatestBlock", diff --git a/server/rpcserver.go b/server/rpcserver.go index b592819..934d088 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -50,9 +50,9 @@ func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*pro return &proto.InsertBlockResponse{}, nil } -// GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. -func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBlockStatusByHeightRequest) (*proto.GetBlockStatusResponse, error) { - isFinalized, err := r.fg.GetBlockStatusByHeight(req.BlockHeight) +// QueryIsBlockFinalizedByHeight is an RPC method that returns the status of a block at a given height. +func (r *rpcServer) QueryIsBlockFinalizedByHeight(ctx context.Context, req *proto.QueryIsBlockFinalizedByHeightRequest) (*proto.GetBlockStatusResponse, error) { + isFinalized, err := r.fg.QueryIsBlockFinalizedByHeight(req.BlockHeight) if err != nil { return nil, err @@ -61,9 +61,9 @@ func (r *rpcServer) GetBlockStatusByHeight(ctx context.Context, req *proto.GetBl return &proto.GetBlockStatusResponse{IsFinalized: isFinalized}, nil } -// GetBlockStatusByHeight is an RPC method that returns the status of a block at a given height. -func (r *rpcServer) GetBlockStatusByHash(ctx context.Context, req *proto.GetBlockStatusByHashRequest) (*proto.GetBlockStatusResponse, error) { - isFinalized, err := r.fg.GetBlockStatusByHash(req.BlockHash) +// QueryIsBlockFinalizedByHeight is an RPC method that returns the status of a block at a given height. +func (r *rpcServer) QueryIsBlockFinalizedByHash(ctx context.Context, req *proto.QueryIsBlockFinalizedByHashRequest) (*proto.GetBlockStatusResponse, error) { + isFinalized, err := r.fg.QueryIsBlockFinalizedByHash(req.BlockHash) if err != nil { return nil, err diff --git a/testutil/mocks/db_mock.go b/testutil/mocks/db_mock.go index f2b4d5e..9bfcbae 100644 --- a/testutil/mocks/db_mock.go +++ b/testutil/mocks/db_mock.go @@ -111,34 +111,34 @@ func (mr *MockIDatabaseHandlerMockRecorder) GetBlockByHeight(height any) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockByHeight), height) } -// GetBlockStatusByHash mocks base method. -func (m *MockIDatabaseHandler) GetBlockStatusByHash(hash string) (bool, error) { +// QueryIsBlockFinalizedByHash mocks base method. +func (m *MockIDatabaseHandler) QueryIsBlockFinalizedByHash(hash string) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockStatusByHash", hash) + ret := m.ctrl.Call(m, "QueryIsBlockFinalizedByHash", hash) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetBlockStatusByHash indicates an expected call of GetBlockStatusByHash. -func (mr *MockIDatabaseHandlerMockRecorder) GetBlockStatusByHash(hash any) *gomock.Call { +// QueryIsBlockFinalizedByHash indicates an expected call of QueryIsBlockFinalizedByHash. +func (mr *MockIDatabaseHandlerMockRecorder) QueryIsBlockFinalizedByHash(hash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHash", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockStatusByHash), hash) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockFinalizedByHash", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryIsBlockFinalizedByHash), hash) } -// GetBlockStatusByHeight mocks base method. -func (m *MockIDatabaseHandler) GetBlockStatusByHeight(height uint64) (bool, error) { +// QueryIsBlockFinalizedByHeight mocks base method. +func (m *MockIDatabaseHandler) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockStatusByHeight", height) + ret := m.ctrl.Call(m, "QueryIsBlockFinalizedByHeight", height) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetBlockStatusByHeight indicates an expected call of GetBlockStatusByHeight. -func (mr *MockIDatabaseHandlerMockRecorder) GetBlockStatusByHeight(height any) *gomock.Call { +// QueryIsBlockFinalizedByHeight indicates an expected call of QueryIsBlockFinalizedByHeight. +func (mr *MockIDatabaseHandlerMockRecorder) QueryIsBlockFinalizedByHeight(height any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockStatusByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetBlockStatusByHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockFinalizedByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryIsBlockFinalizedByHeight), height) } // GetLatestBlock mocks base method. From d6bff6cadac4b45b048ddcecdd6f4f10e8103fdc Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:38:23 +0100 Subject: [PATCH 88/93] nit: fix comment --- db/bbolt.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/bbolt.go b/db/bbolt.go index da5c8cc..f221997 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -203,7 +203,7 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { return nil }) if err != nil { - // If no latest block has been stored yet, return empty block (block 0) + // If no latest block has been stored yet, return nil if errors.Is(err, types.ErrBlockNotFound) { return nil, nil } From 4b9a0d8658663529f479d1249d12cee1d78180cf Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:41:23 +0100 Subject: [PATCH 89/93] remove DeleteDB api --- db/bbolt.go | 14 -------------- db/bbolt_test.go | 2 +- db/interface.go | 1 - finalitygadget/finalitygadget.go | 4 ---- 4 files changed, 1 insertion(+), 20 deletions(-) diff --git a/db/bbolt.go b/db/bbolt.go index f221997..8728d1f 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -5,9 +5,6 @@ import ( "encoding/binary" "encoding/json" "errors" - "fmt" - "os" - "path/filepath" "time" "github.com/babylonlabs-io/finality-gadget/types" @@ -215,17 +212,6 @@ func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { return bb.GetBlockByHeight(latestBlockHeight) } -func (bb *BBoltHandler) DeleteDB() error { - absPath, err := filepath.Abs(bb.db.Path()) - bb.logger.Info("Deleting DB", zap.String("path", absPath)) - if err != nil { - bb.logger.Error("Error getting db absolute path", zap.Error(err)) - return fmt.Errorf("failed to get db absolute path: %w", err) - } - - return os.Remove(absPath) -} - func (bb *BBoltHandler) Close() error { return bb.db.Close() } diff --git a/db/bbolt_test.go b/db/bbolt_test.go index a9f2023..15bc6b5 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -37,7 +37,7 @@ func setupDB(t *testing.T) (*BBoltHandler, func()) { // Cleanup function to close DB and remove temp file cleanup := func() { - err := db.DeleteDB() + err := os.Remove(tempFile.Name()) if err != nil { t.Fatalf("Failed to delete DB: %v", err) } diff --git a/db/interface.go b/db/interface.go index 649fc0d..6da239a 100644 --- a/db/interface.go +++ b/db/interface.go @@ -10,6 +10,5 @@ type IDatabaseHandler interface { QueryIsBlockFinalizedByHeight(height uint64) (bool, error) QueryIsBlockFinalizedByHash(hash string) (bool, error) GetLatestBlock() (*types.Block, error) - DeleteDB() error Close() error } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 9863a9c..37ea4a7 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -340,10 +340,6 @@ func (fg *FinalityGadget) InsertBlock(block *types.Block) error { return nil } -func (fg *FinalityGadget) DeleteDB() error { - return fg.db.DeleteDB() -} - func (fg *FinalityGadget) Close() { fg.l2Client.Close() } From d6015bf602f8f372a8f430cc225a04a0b23dc66c Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:43:53 +0100 Subject: [PATCH 90/93] chore: rename fns for consistency --- client/rpcclient.go | 6 ++--- db/bbolt.go | 4 ++-- db/bbolt_test.go | 8 +++---- db/interface.go | 2 +- finalitygadget/finalitygadget.go | 10 ++++----- finalitygadget/finalitygadget_test.go | 12 +++++----- finalitygadget/interface.go | 4 ++-- proto/finalitygadget.pb.go | 24 ++++++++++---------- proto/finalitygadget.proto | 7 +++--- proto/finalitygadget_grpc.pb.go | 32 +++++++++++++-------------- server/rpcserver.go | 6 ++--- testutil/mocks/db_mock.go | 12 +++++----- 12 files changed, 64 insertions(+), 63 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index 880bbc9..eabc860 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -76,10 +76,10 @@ func (c *FinalityGadgetGrpcClient) QueryIsBlockFinalizedByHash(hash string) (boo return res.IsFinalized, nil } -func (c *FinalityGadgetGrpcClient) GetLatestBlock() (*types.Block, error) { - req := &proto.GetLatestBlockRequest{} +func (c *FinalityGadgetGrpcClient) QueryLatestFinalizedBLock() (*types.Block, error) { + req := &proto.QueryLatestFinalizedBLockRequest{} - res, err := c.client.GetLatestBlock(context.Background(), req) + res, err := c.client.QueryLatestFinalizedBLock(context.Background(), req) if err != nil { return nil, err } diff --git a/db/bbolt.go b/db/bbolt.go index 8728d1f..3d5d49e 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -90,7 +90,7 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { } // Get current latest block - latestBlock, err := bb.GetLatestBlock() + latestBlock, err := bb.QueryLatestFinalizedBLock() if latestBlock == nil { latestBlock = &types.Block{BlockHeight: 0} } @@ -186,7 +186,7 @@ func (bb *BBoltHandler) QueryIsBlockFinalizedByHash(hash string) (bool, error) { return bb.QueryIsBlockFinalizedByHeight(blockHeight) } -func (bb *BBoltHandler) GetLatestBlock() (*types.Block, error) { +func (bb *BBoltHandler) QueryLatestFinalizedBLock() (*types.Block, error) { var latestBlockHeight uint64 // Fetch latest block height diff --git a/db/bbolt_test.go b/db/bbolt_test.go index 15bc6b5..0a52ecd 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -184,7 +184,7 @@ func TestQueryIsBlockFinalizedByHashForNonExistentBlock(t *testing.T) { assert.Equal(t, isFinalized, false) } -func TestGetLatestBlock(t *testing.T) { +func TestQueryLatestFinalizedBLock(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() @@ -205,18 +205,18 @@ func TestGetLatestBlock(t *testing.T) { assert.NoError(t, err) // Retrieve latest block - latestBlock, err := handler.GetLatestBlock() + latestBlock, err := handler.QueryLatestFinalizedBLock() assert.NoError(t, err) assert.Equal(t, latestBlock.BlockHeight, second.BlockHeight) assert.Equal(t, latestBlock.BlockHash, second.BlockHash) assert.Equal(t, latestBlock.BlockTimestamp, second.BlockTimestamp) } -func TestGetLatestBlockNonExistent(t *testing.T) { +func TestQueryLatestFinalizedBLockNonExistent(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() - latestBlock, err := handler.GetLatestBlock() + latestBlock, err := handler.QueryLatestFinalizedBLock() assert.Nil(t, latestBlock) assert.NoError(t, err) } diff --git a/db/interface.go b/db/interface.go index 6da239a..6db4a3c 100644 --- a/db/interface.go +++ b/db/interface.go @@ -9,6 +9,6 @@ type IDatabaseHandler interface { GetBlockByHash(hash string) (*types.Block, error) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) QueryIsBlockFinalizedByHash(hash string) (bool, error) - GetLatestBlock() (*types.Block, error) + QueryLatestFinalizedBLock() (*types.Block, error) Close() error } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 37ea4a7..0ce841f 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -288,8 +288,8 @@ func (fg *FinalityGadget) QueryIsBlockFinalizedByHash(hash string) (bool, error) return fg.db.QueryIsBlockFinalizedByHash(normalizeBlockHash(hash)) } -func (fg *FinalityGadget) GetLatestBlock() (*types.Block, error) { - return fg.db.GetLatestBlock() +func (fg *FinalityGadget) QueryLatestFinalizedBLock() (*types.Block, error) { + return fg.db.QueryLatestFinalizedBLock() } // This function process blocks indefinitely, starting from the last finalized block. @@ -364,7 +364,7 @@ func (fg *FinalityGadget) queryAllFpBtcPubKeys() ([]string, error) { } // Get last btc finalized block -func (fg *FinalityGadget) getLatestFinalizedBlock() (*types.Block, error) { +func (fg *FinalityGadget) queryLatestFinalizedBlock() (*types.Block, error) { return fg.queryBlockByHeight(ethrpc.FinalizedBlockNumber.Int64()) } @@ -384,13 +384,13 @@ func (fg *FinalityGadget) queryBlockByHeight(blockNumber int64) (*types.Block, e // Start service at last finalized block func (fg *FinalityGadget) startService() error { // Query L2 node for last finalized block - block, err := fg.getLatestFinalizedBlock() + block, err := fg.queryLatestFinalizedBlock() if err != nil { return fmt.Errorf("error getting last finalized block: %v", err) } // Query local DB for last block processed - localBlock, err := fg.db.GetLatestBlock() + localBlock, err := fg.db.QueryLatestFinalizedBLock() if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } diff --git a/finalitygadget/finalitygadget_test.go b/finalitygadget/finalitygadget_test.go index 88cd57d..b67fc2a 100644 --- a/finalitygadget/finalitygadget_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -519,7 +519,7 @@ func TestQueryIsBlockFinalizedByHashForNonExistentBlock(t *testing.T) { require.Equal(t, err, types.ErrBlockNotFound) } -func TestGetLatestBlock(t *testing.T) { +func TestQueryLatestFinalizedBLock(t *testing.T) { // define blocks first := &types.Block{ BlockHeight: 1, @@ -539,7 +539,7 @@ func TestGetLatestBlock(t *testing.T) { mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) mockDbHandler.EXPECT().InsertBlock(normalizedFirst).Return(nil).Times(1) mockDbHandler.EXPECT().InsertBlock(normalizedSecond).Return(nil).Times(1) - mockDbHandler.EXPECT().GetLatestBlock().Return(normalizedSecond, nil).Times(1) + mockDbHandler.EXPECT().QueryLatestFinalizedBLock().Return(normalizedSecond, nil).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, @@ -552,25 +552,25 @@ func TestGetLatestBlock(t *testing.T) { require.NoError(t, err) // fetch latest block - latestBlock, err := mockFinalityGadget.GetLatestBlock() + latestBlock, err := mockFinalityGadget.QueryLatestFinalizedBLock() require.NoError(t, err) require.Equal(t, normalizedSecond.BlockHeight, latestBlock.BlockHeight) require.Equal(t, normalizedSecond.BlockHash, latestBlock.BlockHash) require.Equal(t, normalizedSecond.BlockTimestamp, latestBlock.BlockTimestamp) } -func TestGetLatestBlockForNonExistentBlock(t *testing.T) { +func TestQueryLatestFinalizedBLockForNonExistentBlock(t *testing.T) { // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().GetLatestBlock().Return(nil, types.ErrBlockNotFound).Times(1) + mockDbHandler.EXPECT().QueryLatestFinalizedBLock().Return(nil, types.ErrBlockNotFound).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch latest block - latestBlock, err := mockFinalityGadget.GetLatestBlock() + latestBlock, err := mockFinalityGadget.QueryLatestFinalizedBLock() require.Nil(t, latestBlock) require.Equal(t, err, types.ErrBlockNotFound) } diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go index 45e8a3e..89eeeb6 100644 --- a/finalitygadget/interface.go +++ b/finalitygadget/interface.go @@ -70,6 +70,6 @@ type IFinalityGadget interface { // QueryIsBlockFinalizedByHash returns the btc finalization status of a block at given hash by querying the local db QueryIsBlockFinalizedByHash(hash string) (bool, error) - // GetLatestBlock returns the latest finalized block by querying the local db - GetLatestBlock() (*types.Block, error) + // QueryLatestFinalizedBLock returns the latest finalized block by querying the local db + QueryLatestFinalizedBLock() (*types.Block, error) } diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go index c4eba93..8fa8a08 100644 --- a/proto/finalitygadget.pb.go +++ b/proto/finalitygadget.pb.go @@ -268,14 +268,14 @@ func (x *GetBlockStatusResponse) GetIsFinalized() bool { return false } -type GetLatestBlockRequest struct { +type QueryLatestFinalizedBLockRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *GetLatestBlockRequest) Reset() { - *x = GetLatestBlockRequest{} +func (x *QueryLatestFinalizedBLockRequest) Reset() { + *x = QueryLatestFinalizedBLockRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -283,13 +283,13 @@ func (x *GetLatestBlockRequest) Reset() { } } -func (x *GetLatestBlockRequest) String() string { +func (x *QueryLatestFinalizedBLockRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetLatestBlockRequest) ProtoMessage() {} +func (*QueryLatestFinalizedBLockRequest) ProtoMessage() {} -func (x *GetLatestBlockRequest) ProtoReflect() protoreflect.Message { +func (x *QueryLatestFinalizedBLockRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -301,8 +301,8 @@ func (x *GetLatestBlockRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetLatestBlockRequest.ProtoReflect.Descriptor instead. -func (*GetLatestBlockRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryLatestFinalizedBLockRequest.ProtoReflect.Descriptor instead. +func (*QueryLatestFinalizedBLockRequest) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{5} } @@ -380,17 +380,17 @@ var file_proto_finalitygadget_proto_goTypes = []interface{}{ (*QueryIsBlockFinalizedByHeightRequest)(nil), // 2: proto.QueryIsBlockFinalizedByHeightRequest (*QueryIsBlockFinalizedByHashRequest)(nil), // 3: proto.QueryIsBlockFinalizedByHashRequest (*GetBlockStatusResponse)(nil), // 4: proto.GetBlockStatusResponse - (*GetLatestBlockRequest)(nil), // 5: proto.GetLatestBlockRequest + (*QueryLatestFinalizedBLockRequest)(nil), // 5: proto.QueryLatestFinalizedBLockRequest } var file_proto_finalitygadget_proto_depIdxs = []int32{ 0, // 0: proto.FinalityGadget.InsertBlock:input_type -> proto.BlockInfo 2, // 1: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:input_type -> proto.QueryIsBlockFinalizedByHeightRequest 3, // 2: proto.FinalityGadget.QueryIsBlockFinalizedByHash:input_type -> proto.QueryIsBlockFinalizedByHashRequest - 5, // 3: proto.FinalityGadget.GetLatestBlock:input_type -> proto.GetLatestBlockRequest + 5, // 3: proto.FinalityGadget.QueryLatestFinalizedBLock:input_type -> proto.QueryLatestFinalizedBLockRequest 1, // 4: proto.FinalityGadget.InsertBlock:output_type -> proto.InsertBlockResponse 4, // 5: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:output_type -> proto.GetBlockStatusResponse 4, // 6: proto.FinalityGadget.QueryIsBlockFinalizedByHash:output_type -> proto.GetBlockStatusResponse - 0, // 7: proto.FinalityGadget.GetLatestBlock:output_type -> proto.BlockInfo + 0, // 7: proto.FinalityGadget.QueryLatestFinalizedBLock:output_type -> proto.BlockInfo 4, // [4:8] is the sub-list for method output_type 0, // [0:4] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name @@ -465,7 +465,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetLatestBlockRequest); i { + switch v := v.(*QueryLatestFinalizedBLockRequest); i { case 0: return &v.state case 1: diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index e73ab75..c7413f7 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -18,8 +18,9 @@ service FinalityGadget { rpc QueryIsBlockFinalizedByHash(QueryIsBlockFinalizedByHashRequest) returns (GetBlockStatusResponse); - // GetLatestBlock returns the latest consecutively finalized block - rpc GetLatestBlock(GetLatestBlockRequest) returns (BlockInfo); + // QueryLatestFinalizedBLock returns the latest consecutively finalized block + rpc QueryLatestFinalizedBLock(QueryLatestFinalizedBLockRequest) + returns (BlockInfo); } message BlockInfo { @@ -48,4 +49,4 @@ message GetBlockStatusResponse { bool is_finalized = 1; } -message GetLatestBlockRequest {} \ No newline at end of file +message QueryLatestFinalizedBLockRequest {} \ No newline at end of file diff --git a/proto/finalitygadget_grpc.pb.go b/proto/finalitygadget_grpc.pb.go index 8628748..3775ed4 100644 --- a/proto/finalitygadget_grpc.pb.go +++ b/proto/finalitygadget_grpc.pb.go @@ -22,7 +22,7 @@ const ( FinalityGadget_InsertBlock_FullMethodName = "/proto.FinalityGadget/InsertBlock" FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHeight" FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHash" - FinalityGadget_GetLatestBlock_FullMethodName = "/proto.FinalityGadget/GetLatestBlock" + FinalityGadget_QueryLatestFinalizedBLock_FullMethodName = "/proto.FinalityGadget/QueryLatestFinalizedBLock" ) // FinalityGadgetClient is the client API for FinalityGadget service. @@ -36,8 +36,8 @@ type FinalityGadgetClient interface { QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) // QueryIsBlockFinalizedByHash returns the finality status of a block with given hash QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) - // GetLatestBlock returns the latest consecutively finalized block - GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*BlockInfo, error) + // QueryLatestFinalizedBLock returns the latest consecutively finalized block + QueryLatestFinalizedBLock(ctx context.Context, in *QueryLatestFinalizedBLockRequest, opts ...grpc.CallOption) (*BlockInfo, error) } type finalityGadgetClient struct { @@ -75,9 +75,9 @@ func (c *finalityGadgetClient) QueryIsBlockFinalizedByHash(ctx context.Context, return out, nil } -func (c *finalityGadgetClient) GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*BlockInfo, error) { +func (c *finalityGadgetClient) QueryLatestFinalizedBLock(ctx context.Context, in *QueryLatestFinalizedBLockRequest, opts ...grpc.CallOption) (*BlockInfo, error) { out := new(BlockInfo) - err := c.cc.Invoke(ctx, FinalityGadget_GetLatestBlock_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, FinalityGadget_QueryLatestFinalizedBLock_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -95,8 +95,8 @@ type FinalityGadgetServer interface { QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) // QueryIsBlockFinalizedByHash returns the finality status of a block with given hash QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) - // GetLatestBlock returns the latest consecutively finalized block - GetLatestBlock(context.Context, *GetLatestBlockRequest) (*BlockInfo, error) + // QueryLatestFinalizedBLock returns the latest consecutively finalized block + QueryLatestFinalizedBLock(context.Context, *QueryLatestFinalizedBLockRequest) (*BlockInfo, error) mustEmbedUnimplementedFinalityGadgetServer() } @@ -113,8 +113,8 @@ func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHeight(context.C func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryIsBlockFinalizedByHash not implemented") } -func (UnimplementedFinalityGadgetServer) GetLatestBlock(context.Context, *GetLatestBlockRequest) (*BlockInfo, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetLatestBlock not implemented") +func (UnimplementedFinalityGadgetServer) QueryLatestFinalizedBLock(context.Context, *QueryLatestFinalizedBLockRequest) (*BlockInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryLatestFinalizedBLock not implemented") } func (UnimplementedFinalityGadgetServer) mustEmbedUnimplementedFinalityGadgetServer() {} @@ -183,20 +183,20 @@ func _FinalityGadget_QueryIsBlockFinalizedByHash_Handler(srv interface{}, ctx co return interceptor(ctx, in, info, handler) } -func _FinalityGadget_GetLatestBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetLatestBlockRequest) +func _FinalityGadget_QueryLatestFinalizedBLock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryLatestFinalizedBLockRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(FinalityGadgetServer).GetLatestBlock(ctx, in) + return srv.(FinalityGadgetServer).QueryLatestFinalizedBLock(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityGadget_GetLatestBlock_FullMethodName, + FullMethod: FinalityGadget_QueryLatestFinalizedBLock_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FinalityGadgetServer).GetLatestBlock(ctx, req.(*GetLatestBlockRequest)) + return srv.(FinalityGadgetServer).QueryLatestFinalizedBLock(ctx, req.(*QueryLatestFinalizedBLockRequest)) } return interceptor(ctx, in, info, handler) } @@ -221,8 +221,8 @@ var FinalityGadget_ServiceDesc = grpc.ServiceDesc{ Handler: _FinalityGadget_QueryIsBlockFinalizedByHash_Handler, }, { - MethodName: "GetLatestBlock", - Handler: _FinalityGadget_GetLatestBlock_Handler, + MethodName: "QueryLatestFinalizedBLock", + Handler: _FinalityGadget_QueryLatestFinalizedBLock_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/server/rpcserver.go b/server/rpcserver.go index 934d088..8e3a839 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -72,9 +72,9 @@ func (r *rpcServer) QueryIsBlockFinalizedByHash(ctx context.Context, req *proto. return &proto.GetBlockStatusResponse{IsFinalized: isFinalized}, nil } -// GetLatestBlock is an RPC method that returns the latest consecutively finalized block. -func (r *rpcServer) GetLatestBlock(ctx context.Context, req *proto.GetLatestBlockRequest) (*proto.BlockInfo, error) { - block, err := r.fg.GetLatestBlock() +// QueryLatestFinalizedBLock is an RPC method that returns the latest consecutively finalized block. +func (r *rpcServer) QueryLatestFinalizedBLock(ctx context.Context, req *proto.QueryLatestFinalizedBLockRequest) (*proto.BlockInfo, error) { + block, err := r.fg.QueryLatestFinalizedBLock() if err != nil { return nil, err diff --git a/testutil/mocks/db_mock.go b/testutil/mocks/db_mock.go index 9bfcbae..d4d2a3f 100644 --- a/testutil/mocks/db_mock.go +++ b/testutil/mocks/db_mock.go @@ -141,19 +141,19 @@ func (mr *MockIDatabaseHandlerMockRecorder) QueryIsBlockFinalizedByHeight(height return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockFinalizedByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryIsBlockFinalizedByHeight), height) } -// GetLatestBlock mocks base method. -func (m *MockIDatabaseHandler) GetLatestBlock() (*types.Block, error) { +// QueryLatestFinalizedBLock mocks base method. +func (m *MockIDatabaseHandler) QueryLatestFinalizedBLock() (*types.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLatestBlock") + ret := m.ctrl.Call(m, "QueryLatestFinalizedBLock") ret0, _ := ret[0].(*types.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetLatestBlock indicates an expected call of GetLatestBlock. -func (mr *MockIDatabaseHandlerMockRecorder) GetLatestBlock() *gomock.Call { +// QueryLatestFinalizedBLock indicates an expected call of QueryLatestFinalizedBLock. +func (mr *MockIDatabaseHandlerMockRecorder) QueryLatestFinalizedBLock() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestBlock", reflect.TypeOf((*MockIDatabaseHandler)(nil).GetLatestBlock)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryLatestFinalizedBLock", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryLatestFinalizedBLock)) } // InsertBlock mocks base method. From e22c82f0182ea68198f7f9eed3f0e8a13ad0b7fb Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:45:25 +0100 Subject: [PATCH 91/93] remove InsertBlock from grpc --- client/rpcclient.go | 15 --- proto/finalitygadget.pb.go | 190 ++++++++++++-------------------- proto/finalitygadget.proto | 5 - proto/finalitygadget_grpc.pb.go | 55 ++------- server/rpcserver.go | 16 --- 5 files changed, 77 insertions(+), 204 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index eabc860..cc771b9 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -35,21 +35,6 @@ func NewFinalityGadgetGrpcClient( return gClient, nil } -func (c *FinalityGadgetGrpcClient) InsertBlock(block *types.Block) (bool, error) { - req := &proto.BlockInfo{ - BlockHash: block.BlockHash, - BlockHeight: block.BlockHeight, - BlockTimestamp: block.BlockTimestamp, - } - - _, err := c.client.InsertBlock(context.Background(), req) - if err != nil { - return false, err - } - - return true, nil -} - func (c *FinalityGadgetGrpcClient) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) { req := &proto.QueryIsBlockFinalizedByHeightRequest{ BlockHeight: height, diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go index 8fa8a08..516e0cd 100644 --- a/proto/finalitygadget.pb.go +++ b/proto/finalitygadget.pb.go @@ -86,44 +86,6 @@ func (x *BlockInfo) GetBlockTimestamp() uint64 { return 0 } -type InsertBlockResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *InsertBlockResponse) Reset() { - *x = InsertBlockResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InsertBlockResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InsertBlockResponse) ProtoMessage() {} - -func (x *InsertBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InsertBlockResponse.ProtoReflect.Descriptor instead. -func (*InsertBlockResponse) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} -} - type QueryIsBlockFinalizedByHeightRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -136,7 +98,7 @@ type QueryIsBlockFinalizedByHeightRequest struct { func (x *QueryIsBlockFinalizedByHeightRequest) Reset() { *x = QueryIsBlockFinalizedByHeightRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[2] + mi := &file_proto_finalitygadget_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -149,7 +111,7 @@ func (x *QueryIsBlockFinalizedByHeightRequest) String() string { func (*QueryIsBlockFinalizedByHeightRequest) ProtoMessage() {} func (x *QueryIsBlockFinalizedByHeightRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[2] + mi := &file_proto_finalitygadget_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -162,7 +124,7 @@ func (x *QueryIsBlockFinalizedByHeightRequest) ProtoReflect() protoreflect.Messa // Deprecated: Use QueryIsBlockFinalizedByHeightRequest.ProtoReflect.Descriptor instead. func (*QueryIsBlockFinalizedByHeightRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} } func (x *QueryIsBlockFinalizedByHeightRequest) GetBlockHeight() uint64 { @@ -184,7 +146,7 @@ type QueryIsBlockFinalizedByHashRequest struct { func (x *QueryIsBlockFinalizedByHashRequest) Reset() { *x = QueryIsBlockFinalizedByHashRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[3] + mi := &file_proto_finalitygadget_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -197,7 +159,7 @@ func (x *QueryIsBlockFinalizedByHashRequest) String() string { func (*QueryIsBlockFinalizedByHashRequest) ProtoMessage() {} func (x *QueryIsBlockFinalizedByHashRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[3] + mi := &file_proto_finalitygadget_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -210,7 +172,7 @@ func (x *QueryIsBlockFinalizedByHashRequest) ProtoReflect() protoreflect.Message // Deprecated: Use QueryIsBlockFinalizedByHashRequest.ProtoReflect.Descriptor instead. func (*QueryIsBlockFinalizedByHashRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} } func (x *QueryIsBlockFinalizedByHashRequest) GetBlockHash() string { @@ -232,7 +194,7 @@ type GetBlockStatusResponse struct { func (x *GetBlockStatusResponse) Reset() { *x = GetBlockStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[4] + mi := &file_proto_finalitygadget_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -245,7 +207,7 @@ func (x *GetBlockStatusResponse) String() string { func (*GetBlockStatusResponse) ProtoMessage() {} func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[4] + mi := &file_proto_finalitygadget_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -258,7 +220,7 @@ func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockStatusResponse.ProtoReflect.Descriptor instead. func (*GetBlockStatusResponse) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{4} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} } func (x *GetBlockStatusResponse) GetIsFinalized() bool { @@ -277,7 +239,7 @@ type QueryLatestFinalizedBLockRequest struct { func (x *QueryLatestFinalizedBLockRequest) Reset() { *x = QueryLatestFinalizedBLockRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_finalitygadget_proto_msgTypes[5] + mi := &file_proto_finalitygadget_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -290,7 +252,7 @@ func (x *QueryLatestFinalizedBLockRequest) String() string { func (*QueryLatestFinalizedBLockRequest) ProtoMessage() {} func (x *QueryLatestFinalizedBLockRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_finalitygadget_proto_msgTypes[5] + mi := &file_proto_finalitygadget_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -303,7 +265,7 @@ func (x *QueryLatestFinalizedBLockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryLatestFinalizedBLockRequest.ProtoReflect.Descriptor instead. func (*QueryLatestFinalizedBLockRequest) Descriptor() ([]byte, []int) { - return file_proto_finalitygadget_proto_rawDescGZIP(), []int{5} + return file_proto_finalitygadget_proto_rawDescGZIP(), []int{4} } var File_proto_finalitygadget_proto protoreflect.FileDescriptor @@ -318,47 +280,46 @@ var file_proto_finalitygadget_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x15, 0x0a, 0x13, 0x49, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x42, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x49, 0x0a, 0x24, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, - 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0xc9, 0x02, 0x0a, 0x0e, 0x46, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, 0x3b, 0x0a, - 0x0b, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x10, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x1a, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, - 0x68, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, - 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, - 0x2d, 0x69, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, - 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x43, 0x0a, 0x22, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, + 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, + 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, 0x0a, 0x16, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x22, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, + 0x42, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0xbe, 0x02, 0x0a, + 0x0e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, + 0x6b, 0x0a, 0x1d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x1b, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x29, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x61, + 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x4c, 0x6f, + 0x63, 0x6b, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, + 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x31, 0x5a, + 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, + 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -373,26 +334,23 @@ func file_proto_finalitygadget_proto_rawDescGZIP() []byte { return file_proto_finalitygadget_proto_rawDescData } -var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_proto_finalitygadget_proto_goTypes = []interface{}{ - (*BlockInfo)(nil), // 0: proto.BlockInfo - (*InsertBlockResponse)(nil), // 1: proto.InsertBlockResponse - (*QueryIsBlockFinalizedByHeightRequest)(nil), // 2: proto.QueryIsBlockFinalizedByHeightRequest - (*QueryIsBlockFinalizedByHashRequest)(nil), // 3: proto.QueryIsBlockFinalizedByHashRequest - (*GetBlockStatusResponse)(nil), // 4: proto.GetBlockStatusResponse - (*QueryLatestFinalizedBLockRequest)(nil), // 5: proto.QueryLatestFinalizedBLockRequest + (*BlockInfo)(nil), // 0: proto.BlockInfo + (*QueryIsBlockFinalizedByHeightRequest)(nil), // 1: proto.QueryIsBlockFinalizedByHeightRequest + (*QueryIsBlockFinalizedByHashRequest)(nil), // 2: proto.QueryIsBlockFinalizedByHashRequest + (*GetBlockStatusResponse)(nil), // 3: proto.GetBlockStatusResponse + (*QueryLatestFinalizedBLockRequest)(nil), // 4: proto.QueryLatestFinalizedBLockRequest } var file_proto_finalitygadget_proto_depIdxs = []int32{ - 0, // 0: proto.FinalityGadget.InsertBlock:input_type -> proto.BlockInfo - 2, // 1: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:input_type -> proto.QueryIsBlockFinalizedByHeightRequest - 3, // 2: proto.FinalityGadget.QueryIsBlockFinalizedByHash:input_type -> proto.QueryIsBlockFinalizedByHashRequest - 5, // 3: proto.FinalityGadget.QueryLatestFinalizedBLock:input_type -> proto.QueryLatestFinalizedBLockRequest - 1, // 4: proto.FinalityGadget.InsertBlock:output_type -> proto.InsertBlockResponse - 4, // 5: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:output_type -> proto.GetBlockStatusResponse - 4, // 6: proto.FinalityGadget.QueryIsBlockFinalizedByHash:output_type -> proto.GetBlockStatusResponse - 0, // 7: proto.FinalityGadget.QueryLatestFinalizedBLock:output_type -> proto.BlockInfo - 4, // [4:8] is the sub-list for method output_type - 0, // [0:4] is the sub-list for method input_type + 1, // 0: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:input_type -> proto.QueryIsBlockFinalizedByHeightRequest + 2, // 1: proto.FinalityGadget.QueryIsBlockFinalizedByHash:input_type -> proto.QueryIsBlockFinalizedByHashRequest + 4, // 2: proto.FinalityGadget.QueryLatestFinalizedBLock:input_type -> proto.QueryLatestFinalizedBLockRequest + 3, // 3: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:output_type -> proto.GetBlockStatusResponse + 3, // 4: proto.FinalityGadget.QueryIsBlockFinalizedByHash:output_type -> proto.GetBlockStatusResponse + 0, // 5: proto.FinalityGadget.QueryLatestFinalizedBLock:output_type -> proto.BlockInfo + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -417,18 +375,6 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InsertBlockResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryIsBlockFinalizedByHeightRequest); i { case 0: return &v.state @@ -440,7 +386,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryIsBlockFinalizedByHashRequest); i { case 0: return &v.state @@ -452,7 +398,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockStatusResponse); i { case 0: return &v.state @@ -464,7 +410,7 @@ func file_proto_finalitygadget_proto_init() { return nil } } - file_proto_finalitygadget_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_proto_finalitygadget_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryLatestFinalizedBLockRequest); i { case 0: return &v.state @@ -483,7 +429,7 @@ func file_proto_finalitygadget_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_finalitygadget_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 5, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index c7413f7..11c9e5a 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -5,9 +5,6 @@ package proto; option go_package = "github.com/babylonlabs-io/finality-gadget/proto"; service FinalityGadget { - // InsertBlock inserts a new block into the finality gadget db - rpc InsertBlock(BlockInfo) returns (InsertBlockResponse); - // QueryIsBlockFinalizedByHeight returns the finality status of a block at // given height rpc QueryIsBlockFinalizedByHeight(QueryIsBlockFinalizedByHeightRequest) @@ -32,8 +29,6 @@ message BlockInfo { uint64 block_timestamp = 3; } -message InsertBlockResponse {} - message QueryIsBlockFinalizedByHeightRequest { // block_height is the height of the block uint64 block_height = 1; diff --git a/proto/finalitygadget_grpc.pb.go b/proto/finalitygadget_grpc.pb.go index 3775ed4..d8eee6b 100644 --- a/proto/finalitygadget_grpc.pb.go +++ b/proto/finalitygadget_grpc.pb.go @@ -19,22 +19,20 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - FinalityGadget_InsertBlock_FullMethodName = "/proto.FinalityGadget/InsertBlock" FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHeight" FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHash" - FinalityGadget_QueryLatestFinalizedBLock_FullMethodName = "/proto.FinalityGadget/QueryLatestFinalizedBLock" + FinalityGadget_QueryLatestFinalizedBLock_FullMethodName = "/proto.FinalityGadget/QueryLatestFinalizedBLock" ) // FinalityGadgetClient is the client API for FinalityGadget service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type FinalityGadgetClient interface { - // InsertBlock inserts a new block into the finality gadget db - InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) - // QueryIsBlockFinalizedByHeight returns the finality status of a block at given - // height + // QueryIsBlockFinalizedByHeight returns the finality status of a block at + // given height QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) - // QueryIsBlockFinalizedByHash returns the finality status of a block with given hash + // QueryIsBlockFinalizedByHash returns the finality status of a block with + // given hash QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) // QueryLatestFinalizedBLock returns the latest consecutively finalized block QueryLatestFinalizedBLock(ctx context.Context, in *QueryLatestFinalizedBLockRequest, opts ...grpc.CallOption) (*BlockInfo, error) @@ -48,15 +46,6 @@ func NewFinalityGadgetClient(cc grpc.ClientConnInterface) FinalityGadgetClient { return &finalityGadgetClient{cc} } -func (c *finalityGadgetClient) InsertBlock(ctx context.Context, in *BlockInfo, opts ...grpc.CallOption) (*InsertBlockResponse, error) { - out := new(InsertBlockResponse) - err := c.cc.Invoke(ctx, FinalityGadget_InsertBlock_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *finalityGadgetClient) QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { out := new(GetBlockStatusResponse) err := c.cc.Invoke(ctx, FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName, in, out, opts...) @@ -88,12 +77,11 @@ func (c *finalityGadgetClient) QueryLatestFinalizedBLock(ctx context.Context, in // All implementations must embed UnimplementedFinalityGadgetServer // for forward compatibility type FinalityGadgetServer interface { - // InsertBlock inserts a new block into the finality gadget db - InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) - // QueryIsBlockFinalizedByHeight returns the finality status of a block at given - // height + // QueryIsBlockFinalizedByHeight returns the finality status of a block at + // given height QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) - // QueryIsBlockFinalizedByHash returns the finality status of a block with given hash + // QueryIsBlockFinalizedByHash returns the finality status of a block with + // given hash QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) // QueryLatestFinalizedBLock returns the latest consecutively finalized block QueryLatestFinalizedBLock(context.Context, *QueryLatestFinalizedBLockRequest) (*BlockInfo, error) @@ -104,9 +92,6 @@ type FinalityGadgetServer interface { type UnimplementedFinalityGadgetServer struct { } -func (UnimplementedFinalityGadgetServer) InsertBlock(context.Context, *BlockInfo) (*InsertBlockResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method InsertBlock not implemented") -} func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryIsBlockFinalizedByHeight not implemented") } @@ -129,24 +114,6 @@ func RegisterFinalityGadgetServer(s grpc.ServiceRegistrar, srv FinalityGadgetSer s.RegisterService(&FinalityGadget_ServiceDesc, srv) } -func _FinalityGadget_InsertBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(BlockInfo) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(FinalityGadgetServer).InsertBlock(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: FinalityGadget_InsertBlock_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FinalityGadgetServer).InsertBlock(ctx, req.(*BlockInfo)) - } - return interceptor(ctx, in, info, handler) -} - func _FinalityGadget_QueryIsBlockFinalizedByHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryIsBlockFinalizedByHeightRequest) if err := dec(in); err != nil { @@ -208,10 +175,6 @@ var FinalityGadget_ServiceDesc = grpc.ServiceDesc{ ServiceName: "proto.FinalityGadget", HandlerType: (*FinalityGadgetServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "InsertBlock", - Handler: _FinalityGadget_InsertBlock_Handler, - }, { MethodName: "QueryIsBlockFinalizedByHeight", Handler: _FinalityGadget_QueryIsBlockFinalizedByHeight_Handler, diff --git a/server/rpcserver.go b/server/rpcserver.go index 8e3a839..b0402de 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -7,7 +7,6 @@ import ( "github.com/babylonlabs-io/finality-gadget/finalitygadget" "github.com/babylonlabs-io/finality-gadget/proto" - "github.com/babylonlabs-io/finality-gadget/types" ) // rpcServer is the main RPC server for the finality gadget daemon that handles @@ -35,21 +34,6 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { return nil } -// InsertBlock is an RPC method that inserts a block into the database. -func (r *rpcServer) InsertBlock(ctx context.Context, req *proto.BlockInfo) (*proto.InsertBlockResponse, error) { - err := r.fg.InsertBlock(&types.Block{ - BlockHash: req.BlockHash, - BlockHeight: req.BlockHeight, - BlockTimestamp: req.BlockTimestamp, - }) - - if err != nil { - return &proto.InsertBlockResponse{}, err - } - - return &proto.InsertBlockResponse{}, nil -} - // QueryIsBlockFinalizedByHeight is an RPC method that returns the status of a block at a given height. func (r *rpcServer) QueryIsBlockFinalizedByHeight(ctx context.Context, req *proto.QueryIsBlockFinalizedByHeightRequest) (*proto.GetBlockStatusResponse, error) { isFinalized, err := r.fg.QueryIsBlockFinalizedByHeight(req.BlockHeight) From 4f1c34835c533bca86495edcaa8930f1f551a94c Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:46:49 +0100 Subject: [PATCH 92/93] nit: fix comments --- server/server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/server.go b/server/server.go index 3c5a17a..2fb9299 100644 --- a/server/server.go +++ b/server/server.go @@ -15,9 +15,9 @@ import ( "google.golang.org/grpc" ) -// Server is the main daemon construct for the EOTS manager server. It handles +// Server is the main daemon construct for the finality gadget server. It handles // spinning up the RPC sever, the database, and any other components that the -// EOTS manager server needs to function. +// the finality gadget server needs to run. type Server struct { rpcServer *rpcServer cfg *config.Config @@ -29,7 +29,7 @@ type Server struct { started int32 } -// NewEOTSManagerServer creates a new server with the given config. +// NewFinalityGadgetServer creates a new server with the given config. func NewFinalityGadgetServer(cfg *config.Config, db db.IDatabaseHandler, fg finalitygadget.IFinalityGadget, sig signal.Interceptor, logger *zap.Logger) *Server { return &Server{ cfg: cfg, From a7ac2fe939e3083e04c5a7660d8aae0b242e3ce6 Mon Sep 17 00:00:00 2001 From: parketh Date: Thu, 8 Aug 2024 06:51:23 +0100 Subject: [PATCH 93/93] chore: rename fns for consistency --- client/rpcclient.go | 6 +- db/bbolt.go | 4 +- db/bbolt_test.go | 8 +- db/interface.go | 2 +- finalitygadget/finalitygadget.go | 6 +- finalitygadget/finalitygadget_test.go | 12 +- finalitygadget/interface.go | 4 +- proto/finalitygadget.pb.go | 280 +++++++++++++------------- proto/finalitygadget.proto | 32 +-- proto/finalitygadget_grpc.pb.go | 54 ++--- server/rpcserver.go | 16 +- testutil/mocks/db_mock.go | 12 +- 12 files changed, 219 insertions(+), 217 deletions(-) diff --git a/client/rpcclient.go b/client/rpcclient.go index cc771b9..5080c88 100644 --- a/client/rpcclient.go +++ b/client/rpcclient.go @@ -61,10 +61,10 @@ func (c *FinalityGadgetGrpcClient) QueryIsBlockFinalizedByHash(hash string) (boo return res.IsFinalized, nil } -func (c *FinalityGadgetGrpcClient) QueryLatestFinalizedBLock() (*types.Block, error) { - req := &proto.QueryLatestFinalizedBLockRequest{} +func (c *FinalityGadgetGrpcClient) QueryLatestFinalizedBlock() (*types.Block, error) { + req := &proto.QueryLatestFinalizedBlockRequest{} - res, err := c.client.QueryLatestFinalizedBLock(context.Background(), req) + res, err := c.client.QueryLatestFinalizedBlock(context.Background(), req) if err != nil { return nil, err } diff --git a/db/bbolt.go b/db/bbolt.go index 3d5d49e..55639c9 100644 --- a/db/bbolt.go +++ b/db/bbolt.go @@ -90,7 +90,7 @@ func (bb *BBoltHandler) InsertBlock(block *types.Block) error { } // Get current latest block - latestBlock, err := bb.QueryLatestFinalizedBLock() + latestBlock, err := bb.QueryLatestFinalizedBlock() if latestBlock == nil { latestBlock = &types.Block{BlockHeight: 0} } @@ -186,7 +186,7 @@ func (bb *BBoltHandler) QueryIsBlockFinalizedByHash(hash string) (bool, error) { return bb.QueryIsBlockFinalizedByHeight(blockHeight) } -func (bb *BBoltHandler) QueryLatestFinalizedBLock() (*types.Block, error) { +func (bb *BBoltHandler) QueryLatestFinalizedBlock() (*types.Block, error) { var latestBlockHeight uint64 // Fetch latest block height diff --git a/db/bbolt_test.go b/db/bbolt_test.go index 0a52ecd..76a933b 100644 --- a/db/bbolt_test.go +++ b/db/bbolt_test.go @@ -184,7 +184,7 @@ func TestQueryIsBlockFinalizedByHashForNonExistentBlock(t *testing.T) { assert.Equal(t, isFinalized, false) } -func TestQueryLatestFinalizedBLock(t *testing.T) { +func TestQueryLatestFinalizedBlock(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() @@ -205,18 +205,18 @@ func TestQueryLatestFinalizedBLock(t *testing.T) { assert.NoError(t, err) // Retrieve latest block - latestBlock, err := handler.QueryLatestFinalizedBLock() + latestBlock, err := handler.QueryLatestFinalizedBlock() assert.NoError(t, err) assert.Equal(t, latestBlock.BlockHeight, second.BlockHeight) assert.Equal(t, latestBlock.BlockHash, second.BlockHash) assert.Equal(t, latestBlock.BlockTimestamp, second.BlockTimestamp) } -func TestQueryLatestFinalizedBLockNonExistent(t *testing.T) { +func TestQueryLatestFinalizedBlockNonExistent(t *testing.T) { handler, cleanup := setupDB(t) defer cleanup() - latestBlock, err := handler.QueryLatestFinalizedBLock() + latestBlock, err := handler.QueryLatestFinalizedBlock() assert.Nil(t, latestBlock) assert.NoError(t, err) } diff --git a/db/interface.go b/db/interface.go index 6db4a3c..1a25695 100644 --- a/db/interface.go +++ b/db/interface.go @@ -9,6 +9,6 @@ type IDatabaseHandler interface { GetBlockByHash(hash string) (*types.Block, error) QueryIsBlockFinalizedByHeight(height uint64) (bool, error) QueryIsBlockFinalizedByHash(hash string) (bool, error) - QueryLatestFinalizedBLock() (*types.Block, error) + QueryLatestFinalizedBlock() (*types.Block, error) Close() error } diff --git a/finalitygadget/finalitygadget.go b/finalitygadget/finalitygadget.go index 0ce841f..ecc52bc 100644 --- a/finalitygadget/finalitygadget.go +++ b/finalitygadget/finalitygadget.go @@ -288,8 +288,8 @@ func (fg *FinalityGadget) QueryIsBlockFinalizedByHash(hash string) (bool, error) return fg.db.QueryIsBlockFinalizedByHash(normalizeBlockHash(hash)) } -func (fg *FinalityGadget) QueryLatestFinalizedBLock() (*types.Block, error) { - return fg.db.QueryLatestFinalizedBLock() +func (fg *FinalityGadget) QueryLatestFinalizedBlock() (*types.Block, error) { + return fg.db.QueryLatestFinalizedBlock() } // This function process blocks indefinitely, starting from the last finalized block. @@ -390,7 +390,7 @@ func (fg *FinalityGadget) startService() error { } // Query local DB for last block processed - localBlock, err := fg.db.QueryLatestFinalizedBLock() + localBlock, err := fg.db.QueryLatestFinalizedBlock() if err != nil { return fmt.Errorf("error getting latest block from db: %v", err) } diff --git a/finalitygadget/finalitygadget_test.go b/finalitygadget/finalitygadget_test.go index b67fc2a..9cdc4fb 100644 --- a/finalitygadget/finalitygadget_test.go +++ b/finalitygadget/finalitygadget_test.go @@ -519,7 +519,7 @@ func TestQueryIsBlockFinalizedByHashForNonExistentBlock(t *testing.T) { require.Equal(t, err, types.ErrBlockNotFound) } -func TestQueryLatestFinalizedBLock(t *testing.T) { +func TestQueryLatestFinalizedBlock(t *testing.T) { // define blocks first := &types.Block{ BlockHeight: 1, @@ -539,7 +539,7 @@ func TestQueryLatestFinalizedBLock(t *testing.T) { mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) mockDbHandler.EXPECT().InsertBlock(normalizedFirst).Return(nil).Times(1) mockDbHandler.EXPECT().InsertBlock(normalizedSecond).Return(nil).Times(1) - mockDbHandler.EXPECT().QueryLatestFinalizedBLock().Return(normalizedSecond, nil).Times(1) + mockDbHandler.EXPECT().QueryLatestFinalizedBlock().Return(normalizedSecond, nil).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, @@ -552,25 +552,25 @@ func TestQueryLatestFinalizedBLock(t *testing.T) { require.NoError(t, err) // fetch latest block - latestBlock, err := mockFinalityGadget.QueryLatestFinalizedBLock() + latestBlock, err := mockFinalityGadget.QueryLatestFinalizedBlock() require.NoError(t, err) require.Equal(t, normalizedSecond.BlockHeight, latestBlock.BlockHeight) require.Equal(t, normalizedSecond.BlockHash, latestBlock.BlockHash) require.Equal(t, normalizedSecond.BlockTimestamp, latestBlock.BlockTimestamp) } -func TestQueryLatestFinalizedBLockForNonExistentBlock(t *testing.T) { +func TestQueryLatestFinalizedBlockForNonExistentBlock(t *testing.T) { // mock db and finality gadget ctl := gomock.NewController(t) mockDbHandler := mocks.NewMockIDatabaseHandler(ctl) - mockDbHandler.EXPECT().QueryLatestFinalizedBLock().Return(nil, types.ErrBlockNotFound).Times(1) + mockDbHandler.EXPECT().QueryLatestFinalizedBlock().Return(nil, types.ErrBlockNotFound).Times(1) mockFinalityGadget := &FinalityGadget{ db: mockDbHandler, } // fetch latest block - latestBlock, err := mockFinalityGadget.QueryLatestFinalizedBLock() + latestBlock, err := mockFinalityGadget.QueryLatestFinalizedBlock() require.Nil(t, latestBlock) require.Equal(t, err, types.ErrBlockNotFound) } diff --git a/finalitygadget/interface.go b/finalitygadget/interface.go index 89eeeb6..e6689c0 100644 --- a/finalitygadget/interface.go +++ b/finalitygadget/interface.go @@ -70,6 +70,6 @@ type IFinalityGadget interface { // QueryIsBlockFinalizedByHash returns the btc finalization status of a block at given hash by querying the local db QueryIsBlockFinalizedByHash(hash string) (bool, error) - // QueryLatestFinalizedBLock returns the latest finalized block by querying the local db - QueryLatestFinalizedBLock() (*types.Block, error) + // QueryLatestFinalizedBlock returns the latest finalized block by querying the local db + QueryLatestFinalizedBlock() (*types.Block, error) } diff --git a/proto/finalitygadget.pb.go b/proto/finalitygadget.pb.go index 516e0cd..99d010c 100644 --- a/proto/finalitygadget.pb.go +++ b/proto/finalitygadget.pb.go @@ -20,21 +20,17 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type BlockInfo struct { +type QueryIsBlockFinalizedByHeightRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // block_hash is the hash of the block - BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` // block_height is the height of the block - BlockHeight uint64 `protobuf:"varint,2,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` - // block_timestamp is the unix timestamp of the block - BlockTimestamp uint64 `protobuf:"varint,3,opt,name=block_timestamp,json=blockTimestamp,proto3" json:"block_timestamp,omitempty"` + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` } -func (x *BlockInfo) Reset() { - *x = BlockInfo{} +func (x *QueryIsBlockFinalizedByHeightRequest) Reset() { + *x = QueryIsBlockFinalizedByHeightRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -42,13 +38,13 @@ func (x *BlockInfo) Reset() { } } -func (x *BlockInfo) String() string { +func (x *QueryIsBlockFinalizedByHeightRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BlockInfo) ProtoMessage() {} +func (*QueryIsBlockFinalizedByHeightRequest) ProtoMessage() {} -func (x *BlockInfo) ProtoReflect() protoreflect.Message { +func (x *QueryIsBlockFinalizedByHeightRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -60,43 +56,29 @@ func (x *BlockInfo) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BlockInfo.ProtoReflect.Descriptor instead. -func (*BlockInfo) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryIsBlockFinalizedByHeightRequest.ProtoReflect.Descriptor instead. +func (*QueryIsBlockFinalizedByHeightRequest) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{0} } -func (x *BlockInfo) GetBlockHash() string { - if x != nil { - return x.BlockHash - } - return "" -} - -func (x *BlockInfo) GetBlockHeight() uint64 { +func (x *QueryIsBlockFinalizedByHeightRequest) GetBlockHeight() uint64 { if x != nil { return x.BlockHeight } return 0 } -func (x *BlockInfo) GetBlockTimestamp() uint64 { - if x != nil { - return x.BlockTimestamp - } - return 0 -} - -type QueryIsBlockFinalizedByHeightRequest struct { +type QueryIsBlockFinalizedByHashRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // block_height is the height of the block - BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // block_hash is the hash of the block + BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` } -func (x *QueryIsBlockFinalizedByHeightRequest) Reset() { - *x = QueryIsBlockFinalizedByHeightRequest{} +func (x *QueryIsBlockFinalizedByHashRequest) Reset() { + *x = QueryIsBlockFinalizedByHashRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -104,13 +86,13 @@ func (x *QueryIsBlockFinalizedByHeightRequest) Reset() { } } -func (x *QueryIsBlockFinalizedByHeightRequest) String() string { +func (x *QueryIsBlockFinalizedByHashRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryIsBlockFinalizedByHeightRequest) ProtoMessage() {} +func (*QueryIsBlockFinalizedByHashRequest) ProtoMessage() {} -func (x *QueryIsBlockFinalizedByHeightRequest) ProtoReflect() protoreflect.Message { +func (x *QueryIsBlockFinalizedByHashRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -122,29 +104,29 @@ func (x *QueryIsBlockFinalizedByHeightRequest) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use QueryIsBlockFinalizedByHeightRequest.ProtoReflect.Descriptor instead. -func (*QueryIsBlockFinalizedByHeightRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryIsBlockFinalizedByHashRequest.ProtoReflect.Descriptor instead. +func (*QueryIsBlockFinalizedByHashRequest) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{1} } -func (x *QueryIsBlockFinalizedByHeightRequest) GetBlockHeight() uint64 { +func (x *QueryIsBlockFinalizedByHashRequest) GetBlockHash() string { if x != nil { - return x.BlockHeight + return x.BlockHash } - return 0 + return "" } -type QueryIsBlockFinalizedByHashRequest struct { +type QueryIsBlockFinalizedResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // block_hash is the hash of the block - BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + // is_finalized is true if the block is finalized + IsFinalized bool `protobuf:"varint,1,opt,name=is_finalized,json=isFinalized,proto3" json:"is_finalized,omitempty"` } -func (x *QueryIsBlockFinalizedByHashRequest) Reset() { - *x = QueryIsBlockFinalizedByHashRequest{} +func (x *QueryIsBlockFinalizedResponse) Reset() { + *x = QueryIsBlockFinalizedResponse{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -152,13 +134,13 @@ func (x *QueryIsBlockFinalizedByHashRequest) Reset() { } } -func (x *QueryIsBlockFinalizedByHashRequest) String() string { +func (x *QueryIsBlockFinalizedResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryIsBlockFinalizedByHashRequest) ProtoMessage() {} +func (*QueryIsBlockFinalizedResponse) ProtoMessage() {} -func (x *QueryIsBlockFinalizedByHashRequest) ProtoReflect() protoreflect.Message { +func (x *QueryIsBlockFinalizedResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -170,29 +152,26 @@ func (x *QueryIsBlockFinalizedByHashRequest) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use QueryIsBlockFinalizedByHashRequest.ProtoReflect.Descriptor instead. -func (*QueryIsBlockFinalizedByHashRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryIsBlockFinalizedResponse.ProtoReflect.Descriptor instead. +func (*QueryIsBlockFinalizedResponse) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{2} } -func (x *QueryIsBlockFinalizedByHashRequest) GetBlockHash() string { +func (x *QueryIsBlockFinalizedResponse) GetIsFinalized() bool { if x != nil { - return x.BlockHash + return x.IsFinalized } - return "" + return false } -type GetBlockStatusResponse struct { +type QueryLatestFinalizedBlockRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - // is_finalized is true if the block is finalized - IsFinalized bool `protobuf:"varint,1,opt,name=is_finalized,json=isFinalized,proto3" json:"is_finalized,omitempty"` } -func (x *GetBlockStatusResponse) Reset() { - *x = GetBlockStatusResponse{} +func (x *QueryLatestFinalizedBlockRequest) Reset() { + *x = QueryLatestFinalizedBlockRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -200,13 +179,13 @@ func (x *GetBlockStatusResponse) Reset() { } } -func (x *GetBlockStatusResponse) String() string { +func (x *QueryLatestFinalizedBlockRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetBlockStatusResponse) ProtoMessage() {} +func (*QueryLatestFinalizedBlockRequest) ProtoMessage() {} -func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { +func (x *QueryLatestFinalizedBlockRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -218,26 +197,26 @@ func (x *GetBlockStatusResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetBlockStatusResponse.ProtoReflect.Descriptor instead. -func (*GetBlockStatusResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryLatestFinalizedBlockRequest.ProtoReflect.Descriptor instead. +func (*QueryLatestFinalizedBlockRequest) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{3} } -func (x *GetBlockStatusResponse) GetIsFinalized() bool { - if x != nil { - return x.IsFinalized - } - return false -} - -type QueryLatestFinalizedBLockRequest struct { +type QueryBlockResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // block_hash is the hash of the block + BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + // block_height is the height of the block + BlockHeight uint64 `protobuf:"varint,2,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // block_timestamp is the unix timestamp of the block + BlockTimestamp uint64 `protobuf:"varint,3,opt,name=block_timestamp,json=blockTimestamp,proto3" json:"block_timestamp,omitempty"` } -func (x *QueryLatestFinalizedBLockRequest) Reset() { - *x = QueryLatestFinalizedBLockRequest{} +func (x *QueryBlockResponse) Reset() { + *x = QueryBlockResponse{} if protoimpl.UnsafeEnabled { mi := &file_proto_finalitygadget_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -245,13 +224,13 @@ func (x *QueryLatestFinalizedBLockRequest) Reset() { } } -func (x *QueryLatestFinalizedBLockRequest) String() string { +func (x *QueryBlockResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryLatestFinalizedBLockRequest) ProtoMessage() {} +func (*QueryBlockResponse) ProtoMessage() {} -func (x *QueryLatestFinalizedBLockRequest) ProtoReflect() protoreflect.Message { +func (x *QueryBlockResponse) ProtoReflect() protoreflect.Message { mi := &file_proto_finalitygadget_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -263,63 +242,86 @@ func (x *QueryLatestFinalizedBLockRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryLatestFinalizedBLockRequest.ProtoReflect.Descriptor instead. -func (*QueryLatestFinalizedBLockRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlockResponse.ProtoReflect.Descriptor instead. +func (*QueryBlockResponse) Descriptor() ([]byte, []int) { return file_proto_finalitygadget_proto_rawDescGZIP(), []int{4} } +func (x *QueryBlockResponse) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *QueryBlockResponse) GetBlockHeight() uint64 { + if x != nil { + return x.BlockHeight + } + return 0 +} + +func (x *QueryBlockResponse) GetBlockTimestamp() uint64 { + if x != nil { + return x.BlockTimestamp + } + return 0 +} + var File_proto_finalitygadget_proto protoreflect.FileDescriptor var file_proto_finalitygadget_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x76, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x49, 0x0a, 0x24, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x43, 0x0a, 0x22, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, - 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, - 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3b, 0x0a, 0x16, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x22, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, - 0x42, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0xbe, 0x02, 0x0a, + 0x6f, 0x74, 0x6f, 0x22, 0x49, 0x0a, 0x24, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x43, + 0x0a, 0x22, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x61, 0x73, 0x68, 0x22, 0x42, 0x0a, 0x1d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x22, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x7f, 0x0a, 0x12, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x32, 0xd5, 0x02, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x47, 0x61, 0x64, 0x67, 0x65, 0x74, 0x12, - 0x6b, 0x0a, 0x1d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, + 0x72, 0x0a, 0x1d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x1b, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x29, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x61, - 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x4c, 0x6f, - 0x63, 0x6b, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, - 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x31, 0x5a, - 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, - 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x1b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x79, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x49, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, + 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x73, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x61, 0x74, 0x65, + 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x61, + 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, 0x2d, 0x69, + 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x67, 0x61, 0x64, 0x67, 0x65, + 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -336,19 +338,19 @@ func file_proto_finalitygadget_proto_rawDescGZIP() []byte { var file_proto_finalitygadget_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_proto_finalitygadget_proto_goTypes = []interface{}{ - (*BlockInfo)(nil), // 0: proto.BlockInfo - (*QueryIsBlockFinalizedByHeightRequest)(nil), // 1: proto.QueryIsBlockFinalizedByHeightRequest - (*QueryIsBlockFinalizedByHashRequest)(nil), // 2: proto.QueryIsBlockFinalizedByHashRequest - (*GetBlockStatusResponse)(nil), // 3: proto.GetBlockStatusResponse - (*QueryLatestFinalizedBLockRequest)(nil), // 4: proto.QueryLatestFinalizedBLockRequest + (*QueryIsBlockFinalizedByHeightRequest)(nil), // 0: proto.QueryIsBlockFinalizedByHeightRequest + (*QueryIsBlockFinalizedByHashRequest)(nil), // 1: proto.QueryIsBlockFinalizedByHashRequest + (*QueryIsBlockFinalizedResponse)(nil), // 2: proto.QueryIsBlockFinalizedResponse + (*QueryLatestFinalizedBlockRequest)(nil), // 3: proto.QueryLatestFinalizedBlockRequest + (*QueryBlockResponse)(nil), // 4: proto.QueryBlockResponse } var file_proto_finalitygadget_proto_depIdxs = []int32{ - 1, // 0: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:input_type -> proto.QueryIsBlockFinalizedByHeightRequest - 2, // 1: proto.FinalityGadget.QueryIsBlockFinalizedByHash:input_type -> proto.QueryIsBlockFinalizedByHashRequest - 4, // 2: proto.FinalityGadget.QueryLatestFinalizedBLock:input_type -> proto.QueryLatestFinalizedBLockRequest - 3, // 3: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:output_type -> proto.GetBlockStatusResponse - 3, // 4: proto.FinalityGadget.QueryIsBlockFinalizedByHash:output_type -> proto.GetBlockStatusResponse - 0, // 5: proto.FinalityGadget.QueryLatestFinalizedBLock:output_type -> proto.BlockInfo + 0, // 0: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:input_type -> proto.QueryIsBlockFinalizedByHeightRequest + 1, // 1: proto.FinalityGadget.QueryIsBlockFinalizedByHash:input_type -> proto.QueryIsBlockFinalizedByHashRequest + 3, // 2: proto.FinalityGadget.QueryLatestFinalizedBlock:input_type -> proto.QueryLatestFinalizedBlockRequest + 2, // 3: proto.FinalityGadget.QueryIsBlockFinalizedByHeight:output_type -> proto.QueryIsBlockFinalizedResponse + 2, // 4: proto.FinalityGadget.QueryIsBlockFinalizedByHash:output_type -> proto.QueryIsBlockFinalizedResponse + 4, // 5: proto.FinalityGadget.QueryLatestFinalizedBlock:output_type -> proto.QueryBlockResponse 3, // [3:6] is the sub-list for method output_type 0, // [0:3] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name @@ -363,7 +365,7 @@ func file_proto_finalitygadget_proto_init() { } if !protoimpl.UnsafeEnabled { file_proto_finalitygadget_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlockInfo); i { + switch v := v.(*QueryIsBlockFinalizedByHeightRequest); i { case 0: return &v.state case 1: @@ -375,7 +377,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryIsBlockFinalizedByHeightRequest); i { + switch v := v.(*QueryIsBlockFinalizedByHashRequest); i { case 0: return &v.state case 1: @@ -387,7 +389,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryIsBlockFinalizedByHashRequest); i { + switch v := v.(*QueryIsBlockFinalizedResponse); i { case 0: return &v.state case 1: @@ -399,7 +401,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBlockStatusResponse); i { + switch v := v.(*QueryLatestFinalizedBlockRequest); i { case 0: return &v.state case 1: @@ -411,7 +413,7 @@ func file_proto_finalitygadget_proto_init() { } } file_proto_finalitygadget_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryLatestFinalizedBLockRequest); i { + switch v := v.(*QueryBlockResponse); i { case 0: return &v.state case 1: diff --git a/proto/finalitygadget.proto b/proto/finalitygadget.proto index 11c9e5a..9e9aec3 100644 --- a/proto/finalitygadget.proto +++ b/proto/finalitygadget.proto @@ -8,25 +8,16 @@ service FinalityGadget { // QueryIsBlockFinalizedByHeight returns the finality status of a block at // given height rpc QueryIsBlockFinalizedByHeight(QueryIsBlockFinalizedByHeightRequest) - returns (GetBlockStatusResponse); + returns (QueryIsBlockFinalizedResponse); // QueryIsBlockFinalizedByHash returns the finality status of a block with // given hash rpc QueryIsBlockFinalizedByHash(QueryIsBlockFinalizedByHashRequest) - returns (GetBlockStatusResponse); + returns (QueryIsBlockFinalizedResponse); - // QueryLatestFinalizedBLock returns the latest consecutively finalized block - rpc QueryLatestFinalizedBLock(QueryLatestFinalizedBLockRequest) - returns (BlockInfo); -} - -message BlockInfo { - // block_hash is the hash of the block - string block_hash = 1; - // block_height is the height of the block - uint64 block_height = 2; - // block_timestamp is the unix timestamp of the block - uint64 block_timestamp = 3; + // QueryLatestFinalizedBlock returns the latest consecutively finalized block + rpc QueryLatestFinalizedBlock(QueryLatestFinalizedBlockRequest) + returns (QueryBlockResponse); } message QueryIsBlockFinalizedByHeightRequest { @@ -39,9 +30,18 @@ message QueryIsBlockFinalizedByHashRequest { string block_hash = 1; } -message GetBlockStatusResponse { +message QueryIsBlockFinalizedResponse { // is_finalized is true if the block is finalized bool is_finalized = 1; } -message QueryLatestFinalizedBLockRequest {} \ No newline at end of file +message QueryLatestFinalizedBlockRequest {} + +message QueryBlockResponse { + // block_hash is the hash of the block + string block_hash = 1; + // block_height is the height of the block + uint64 block_height = 2; + // block_timestamp is the unix timestamp of the block + uint64 block_timestamp = 3; +} \ No newline at end of file diff --git a/proto/finalitygadget_grpc.pb.go b/proto/finalitygadget_grpc.pb.go index d8eee6b..a67cc91 100644 --- a/proto/finalitygadget_grpc.pb.go +++ b/proto/finalitygadget_grpc.pb.go @@ -21,7 +21,7 @@ const _ = grpc.SupportPackageIsVersion7 const ( FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHeight" FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName = "/proto.FinalityGadget/QueryIsBlockFinalizedByHash" - FinalityGadget_QueryLatestFinalizedBLock_FullMethodName = "/proto.FinalityGadget/QueryLatestFinalizedBLock" + FinalityGadget_QueryLatestFinalizedBlock_FullMethodName = "/proto.FinalityGadget/QueryLatestFinalizedBlock" ) // FinalityGadgetClient is the client API for FinalityGadget service. @@ -30,12 +30,12 @@ const ( type FinalityGadgetClient interface { // QueryIsBlockFinalizedByHeight returns the finality status of a block at // given height - QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) + QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*QueryIsBlockFinalizedResponse, error) // QueryIsBlockFinalizedByHash returns the finality status of a block with // given hash - QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) - // QueryLatestFinalizedBLock returns the latest consecutively finalized block - QueryLatestFinalizedBLock(ctx context.Context, in *QueryLatestFinalizedBLockRequest, opts ...grpc.CallOption) (*BlockInfo, error) + QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*QueryIsBlockFinalizedResponse, error) + // QueryLatestFinalizedBlock returns the latest consecutively finalized block + QueryLatestFinalizedBlock(ctx context.Context, in *QueryLatestFinalizedBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) } type finalityGadgetClient struct { @@ -46,8 +46,8 @@ func NewFinalityGadgetClient(cc grpc.ClientConnInterface) FinalityGadgetClient { return &finalityGadgetClient{cc} } -func (c *finalityGadgetClient) QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { - out := new(GetBlockStatusResponse) +func (c *finalityGadgetClient) QueryIsBlockFinalizedByHeight(ctx context.Context, in *QueryIsBlockFinalizedByHeightRequest, opts ...grpc.CallOption) (*QueryIsBlockFinalizedResponse, error) { + out := new(QueryIsBlockFinalizedResponse) err := c.cc.Invoke(ctx, FinalityGadget_QueryIsBlockFinalizedByHeight_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -55,8 +55,8 @@ func (c *finalityGadgetClient) QueryIsBlockFinalizedByHeight(ctx context.Context return out, nil } -func (c *finalityGadgetClient) QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*GetBlockStatusResponse, error) { - out := new(GetBlockStatusResponse) +func (c *finalityGadgetClient) QueryIsBlockFinalizedByHash(ctx context.Context, in *QueryIsBlockFinalizedByHashRequest, opts ...grpc.CallOption) (*QueryIsBlockFinalizedResponse, error) { + out := new(QueryIsBlockFinalizedResponse) err := c.cc.Invoke(ctx, FinalityGadget_QueryIsBlockFinalizedByHash_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -64,9 +64,9 @@ func (c *finalityGadgetClient) QueryIsBlockFinalizedByHash(ctx context.Context, return out, nil } -func (c *finalityGadgetClient) QueryLatestFinalizedBLock(ctx context.Context, in *QueryLatestFinalizedBLockRequest, opts ...grpc.CallOption) (*BlockInfo, error) { - out := new(BlockInfo) - err := c.cc.Invoke(ctx, FinalityGadget_QueryLatestFinalizedBLock_FullMethodName, in, out, opts...) +func (c *finalityGadgetClient) QueryLatestFinalizedBlock(ctx context.Context, in *QueryLatestFinalizedBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) { + out := new(QueryBlockResponse) + err := c.cc.Invoke(ctx, FinalityGadget_QueryLatestFinalizedBlock_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -79,12 +79,12 @@ func (c *finalityGadgetClient) QueryLatestFinalizedBLock(ctx context.Context, in type FinalityGadgetServer interface { // QueryIsBlockFinalizedByHeight returns the finality status of a block at // given height - QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) + QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*QueryIsBlockFinalizedResponse, error) // QueryIsBlockFinalizedByHash returns the finality status of a block with // given hash - QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) - // QueryLatestFinalizedBLock returns the latest consecutively finalized block - QueryLatestFinalizedBLock(context.Context, *QueryLatestFinalizedBLockRequest) (*BlockInfo, error) + QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*QueryIsBlockFinalizedResponse, error) + // QueryLatestFinalizedBlock returns the latest consecutively finalized block + QueryLatestFinalizedBlock(context.Context, *QueryLatestFinalizedBlockRequest) (*QueryBlockResponse, error) mustEmbedUnimplementedFinalityGadgetServer() } @@ -92,14 +92,14 @@ type FinalityGadgetServer interface { type UnimplementedFinalityGadgetServer struct { } -func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*GetBlockStatusResponse, error) { +func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHeight(context.Context, *QueryIsBlockFinalizedByHeightRequest) (*QueryIsBlockFinalizedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryIsBlockFinalizedByHeight not implemented") } -func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*GetBlockStatusResponse, error) { +func (UnimplementedFinalityGadgetServer) QueryIsBlockFinalizedByHash(context.Context, *QueryIsBlockFinalizedByHashRequest) (*QueryIsBlockFinalizedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryIsBlockFinalizedByHash not implemented") } -func (UnimplementedFinalityGadgetServer) QueryLatestFinalizedBLock(context.Context, *QueryLatestFinalizedBLockRequest) (*BlockInfo, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryLatestFinalizedBLock not implemented") +func (UnimplementedFinalityGadgetServer) QueryLatestFinalizedBlock(context.Context, *QueryLatestFinalizedBlockRequest) (*QueryBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryLatestFinalizedBlock not implemented") } func (UnimplementedFinalityGadgetServer) mustEmbedUnimplementedFinalityGadgetServer() {} @@ -150,20 +150,20 @@ func _FinalityGadget_QueryIsBlockFinalizedByHash_Handler(srv interface{}, ctx co return interceptor(ctx, in, info, handler) } -func _FinalityGadget_QueryLatestFinalizedBLock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryLatestFinalizedBLockRequest) +func _FinalityGadget_QueryLatestFinalizedBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryLatestFinalizedBlockRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(FinalityGadgetServer).QueryLatestFinalizedBLock(ctx, in) + return srv.(FinalityGadgetServer).QueryLatestFinalizedBlock(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityGadget_QueryLatestFinalizedBLock_FullMethodName, + FullMethod: FinalityGadget_QueryLatestFinalizedBlock_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FinalityGadgetServer).QueryLatestFinalizedBLock(ctx, req.(*QueryLatestFinalizedBLockRequest)) + return srv.(FinalityGadgetServer).QueryLatestFinalizedBlock(ctx, req.(*QueryLatestFinalizedBlockRequest)) } return interceptor(ctx, in, info, handler) } @@ -184,8 +184,8 @@ var FinalityGadget_ServiceDesc = grpc.ServiceDesc{ Handler: _FinalityGadget_QueryIsBlockFinalizedByHash_Handler, }, { - MethodName: "QueryLatestFinalizedBLock", - Handler: _FinalityGadget_QueryLatestFinalizedBLock_Handler, + MethodName: "QueryLatestFinalizedBlock", + Handler: _FinalityGadget_QueryLatestFinalizedBlock_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/server/rpcserver.go b/server/rpcserver.go index b0402de..25a49eb 100644 --- a/server/rpcserver.go +++ b/server/rpcserver.go @@ -35,36 +35,36 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error { } // QueryIsBlockFinalizedByHeight is an RPC method that returns the status of a block at a given height. -func (r *rpcServer) QueryIsBlockFinalizedByHeight(ctx context.Context, req *proto.QueryIsBlockFinalizedByHeightRequest) (*proto.GetBlockStatusResponse, error) { +func (r *rpcServer) QueryIsBlockFinalizedByHeight(ctx context.Context, req *proto.QueryIsBlockFinalizedByHeightRequest) (*proto.QueryIsBlockFinalizedResponse, error) { isFinalized, err := r.fg.QueryIsBlockFinalizedByHeight(req.BlockHeight) if err != nil { return nil, err } - return &proto.GetBlockStatusResponse{IsFinalized: isFinalized}, nil + return &proto.QueryIsBlockFinalizedResponse{IsFinalized: isFinalized}, nil } // QueryIsBlockFinalizedByHeight is an RPC method that returns the status of a block at a given height. -func (r *rpcServer) QueryIsBlockFinalizedByHash(ctx context.Context, req *proto.QueryIsBlockFinalizedByHashRequest) (*proto.GetBlockStatusResponse, error) { +func (r *rpcServer) QueryIsBlockFinalizedByHash(ctx context.Context, req *proto.QueryIsBlockFinalizedByHashRequest) (*proto.QueryIsBlockFinalizedResponse, error) { isFinalized, err := r.fg.QueryIsBlockFinalizedByHash(req.BlockHash) if err != nil { return nil, err } - return &proto.GetBlockStatusResponse{IsFinalized: isFinalized}, nil + return &proto.QueryIsBlockFinalizedResponse{IsFinalized: isFinalized}, nil } -// QueryLatestFinalizedBLock is an RPC method that returns the latest consecutively finalized block. -func (r *rpcServer) QueryLatestFinalizedBLock(ctx context.Context, req *proto.QueryLatestFinalizedBLockRequest) (*proto.BlockInfo, error) { - block, err := r.fg.QueryLatestFinalizedBLock() +// QueryLatestFinalizedBlock is an RPC method that returns the latest consecutively finalized block. +func (r *rpcServer) QueryLatestFinalizedBlock(ctx context.Context, req *proto.QueryLatestFinalizedBlockRequest) (*proto.QueryBlockResponse, error) { + block, err := r.fg.QueryLatestFinalizedBlock() if err != nil { return nil, err } - return &proto.BlockInfo{ + return &proto.QueryBlockResponse{ BlockHash: block.BlockHash, BlockHeight: block.BlockHeight, BlockTimestamp: block.BlockTimestamp, diff --git a/testutil/mocks/db_mock.go b/testutil/mocks/db_mock.go index d4d2a3f..bdff601 100644 --- a/testutil/mocks/db_mock.go +++ b/testutil/mocks/db_mock.go @@ -141,19 +141,19 @@ func (mr *MockIDatabaseHandlerMockRecorder) QueryIsBlockFinalizedByHeight(height return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIsBlockFinalizedByHeight", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryIsBlockFinalizedByHeight), height) } -// QueryLatestFinalizedBLock mocks base method. -func (m *MockIDatabaseHandler) QueryLatestFinalizedBLock() (*types.Block, error) { +// QueryLatestFinalizedBlock mocks base method. +func (m *MockIDatabaseHandler) QueryLatestFinalizedBlock() (*types.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryLatestFinalizedBLock") + ret := m.ctrl.Call(m, "QueryLatestFinalizedBlock") ret0, _ := ret[0].(*types.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// QueryLatestFinalizedBLock indicates an expected call of QueryLatestFinalizedBLock. -func (mr *MockIDatabaseHandlerMockRecorder) QueryLatestFinalizedBLock() *gomock.Call { +// QueryLatestFinalizedBlock indicates an expected call of QueryLatestFinalizedBlock. +func (mr *MockIDatabaseHandlerMockRecorder) QueryLatestFinalizedBlock() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryLatestFinalizedBLock", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryLatestFinalizedBLock)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryLatestFinalizedBlock", reflect.TypeOf((*MockIDatabaseHandler)(nil).QueryLatestFinalizedBlock)) } // InsertBlock mocks base method.