From 6d30197aa14576a06ef8fbeb461e993540647226 Mon Sep 17 00:00:00 2001 From: Hwangjae Lee Date: Fri, 17 May 2024 15:45:38 +0900 Subject: [PATCH 01/21] Add keyring-backend option to sign-schnorr command in eots.md (#330) This commit updates the eots.md documentation to include the --keyring-backend file option in the eotsd sign-schnorr command example. This addition ensures that the command specifies the use of the file-based keyring backend for managing keys. Changes: - Added --keyring-backend file option to the eotsd sign-schnorr command example. This enhancement improves clarity and accuracy in the documentation, ensuring users are aware of the necessary flag to specify the keyring backend. Signed-off-by: Hwangjae Lee --- docs/eots.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/eots.md b/docs/eots.md index 36fa324c..5e414e3c 100644 --- a/docs/eots.md +++ b/docs/eots.md @@ -131,7 +131,7 @@ given `key-name` or `btc-pk`. If both flags `--key-name` and `--btc-pk` are provided, `btc-pk` takes priority. ```shell -eotsd sign-schnorr /path/to/data/file --home /path/to/eotsd/home/ --key-name my-key-name +eotsd sign-schnorr /path/to/data/file --home /path/to/eotsd/home/ --key-name my-key-name --keyring-backend file { "key_name": "my-key-name", "pub_key_hex": "50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383", From af82543bec494fedc79e0b6adb446752ab409279 Mon Sep 17 00:00:00 2001 From: bap2pecs <111917526+bap2pecs@users.noreply.github.com> Date: Wed, 22 May 2024 09:37:31 -0400 Subject: [PATCH 02/21] Fix make test (#342) --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index c8d6b32c..cc42df6a 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,7 @@ build-docker: .PHONY: build build-docker +.PHONY: test test: go test ./... From fcf14de3cdd5772e83d5c9035f9fba98013ede80 Mon Sep 17 00:00:00 2001 From: bap2pecs <111917526+bap2pecs@users.noreply.github.com> Date: Thu, 23 May 2024 07:58:33 -0400 Subject: [PATCH 03/21] chore: add check-mock-gen to the CI (#352) --- .circleci/config.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ceb95006..485db950 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,6 +5,31 @@ orbs: aws-ecr: circleci/aws-ecr@8.2.1 jobs: + check-mock-gen: + machine: + image: ubuntu-2204:2024.01.1 + steps: + - checkout + - go/install: + version: "1.21.4" + - go/load-cache: + key: go-mod-v6-{{ checksum "go.sum" }} + - go/mod-download + - go/save-cache: + key: go-mod-v6-{{ checksum "go.sum" }} + path: "/home/circleci/.go_workspace/pkg/mod" + - run: + name: Run make mock-gen + command: | + make mock-gen + - run: + name: Check for uncommitted changes + command: | + if ! git diff --exit-code; then + echo "Uncommitted changes detected. Please run 'make mock-gen' before committing." + exit 1 + fi + build_lint_test: machine: image: ubuntu-2204:2024.01.1 @@ -85,6 +110,7 @@ jobs: workflows: CI: jobs: + - check-mock-gen - build_lint_test - build_docker: filters: From 9ebc0313db2096b40629dd1319f346b4daeac84d Mon Sep 17 00:00:00 2001 From: Filippos Malandrakis <35352222+filippos47@users.noreply.github.com> Date: Wed, 29 May 2024 05:31:54 +0300 Subject: [PATCH 04/21] docs: Specify keyring backend at every eotsd cmd (#317) --- docs/eots.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/eots.md b/docs/eots.md index 5e414e3c..925d3cb6 100644 --- a/docs/eots.md +++ b/docs/eots.md @@ -152,7 +152,8 @@ Otherwise, an error message will be printed out. ```shell eotsd verify-schnorr-sig /path/to/data/file --btc-pk 50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383 \ ---signature b91fc06b30b78c0ca66a7e033184d89b61cd6ab572329b20f6052411ab83502effb5c9a1173ed69f20f6502a741eeb5105519bb3f67d37612bc2bcce411f8d72 +--signature b91fc06b30b78c0ca66a7e033184d89b61cd6ab572329b20f6052411ab83502effb5c9a1173ed69f20f6502a741eeb5105519bb3f67d37612bc2bcce411f8d72 \ +--keyring-backend file ``` ## 4. Starting the EOTS Daemon From 9a7ca95bf9e3778a0e66685d26ee1e07e24b1775 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 19:44:14 +0800 Subject: [PATCH 05/21] chore(deps): bump github.com/cosmos/ibc-go/v8 from 8.0.0 to 8.2.0 (#281) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 46201905..c32914f6 100644 --- a/go.mod +++ b/go.mod @@ -91,7 +91,7 @@ require ( github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.0.1 // indirect github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect - github.com/cosmos/ibc-go/v8 v8.0.0 // indirect + github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect diff --git a/go.sum b/go.sum index 4fbc1398..f79f38ca 100644 --- a/go.sum +++ b/go.sum @@ -425,8 +425,8 @@ github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= -github.com/cosmos/ibc-go/v8 v8.0.0/go.mod h1:C6IiJom0F3cIQCD5fKwVPDrDK9j/xTu563AWuOmXois= +github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE= +github.com/cosmos/ibc-go/v8 v8.2.0/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= From eb6fa7d447a1284c65f5ee4ae7ee63dee01c2316 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 19:44:42 +0800 Subject: [PATCH 06/21] chore(deps): bump github.com/cosmos/ibc-go/v8 from 8.0.0 to 8.2.0 in /tools (#280) --- tools/go.mod | 48 +++++++++++++----------- tools/go.sum | 103 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 90 insertions(+), 61 deletions(-) diff --git a/tools/go.mod b/tools/go.mod index 71cc1f36..ed0155fe 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -7,11 +7,11 @@ toolchain go1.21.4 require github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b require ( - cloud.google.com/go v0.110.10 // indirect - cloud.google.com/go/compute v1.23.3 // indirect + cloud.google.com/go v0.112.0 // indirect + cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.5 // indirect - cloud.google.com/go/storage v1.35.1 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/storage v1.36.0 // indirect cosmossdk.io/api v0.7.3 // indirect cosmossdk.io/client/v2 v2.0.0-beta.1 // indirect cosmossdk.io/collections v0.4.0 // indirect @@ -19,14 +19,14 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect - cosmossdk.io/math v1.2.0 // indirect + cosmossdk.io/math v1.3.0 // indirect cosmossdk.io/store v1.0.2 // indirect cosmossdk.io/tools/confix v0.1.0 // indirect cosmossdk.io/x/circuit v0.1.0 // indirect cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect cosmossdk.io/x/nft v0.1.0 // indirect - cosmossdk.io/x/tx v0.13.0 // indirect + cosmossdk.io/x/tx v0.13.1 // indirect cosmossdk.io/x/upgrade v0.1.0 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -60,15 +60,15 @@ require ( github.com/cometbft/cometbft v0.38.5 // indirect github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-db v1.0.0 // indirect + github.com/cosmos/cosmos-db v1.0.2 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.4 // indirect - github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987 // indirect + github.com/cosmos/cosmos-sdk v0.50.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/gogoproto v1.4.11 // indirect github.com/cosmos/iavl v1.0.1 // indirect github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect - github.com/cosmos/ibc-go/v8 v8.0.0 // indirect + github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/creachadair/atomicfile v0.3.1 // indirect @@ -93,20 +93,22 @@ require ( github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect 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/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/s2a-go v0.1.7 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect @@ -135,7 +137,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.7 // indirect @@ -175,7 +177,7 @@ require ( 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/stretchr/testify v1.8.4 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -186,9 +188,14 @@ require ( 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.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sync v0.6.0 // indirect @@ -196,14 +203,13 @@ require ( golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.153.0 // indirect + google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/grpc v1.60.1 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect + google.golang.org/grpc v1.62.0 // indirect + google.golang.org/protobuf v1.33.0 // 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/tools/go.sum b/tools/go.sum index f701268d..5b909011 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -30,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -68,8 +68,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= @@ -109,8 +109,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= @@ -171,8 +171,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= -cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -198,8 +198,8 @@ cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= -cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= -cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= cosmossdk.io/tools/confix v0.1.0 h1:2OOZTtQsDT5e7P3FM5xqM0bPfluAxZlAwxqaDmYBE+E= @@ -212,8 +212,8 @@ cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= cosmossdk.io/x/nft v0.1.0 h1:VhcsFiEK33ODN27kxKLa0r/CeFd8laBfbDBwYqCyYCM= cosmossdk.io/x/nft v0.1.0/go.mod h1:ec4j4QAO4mJZ+45jeYRnW7awLHby1JZANqe1hNZ4S3g= -cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= -cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= +cosmossdk.io/x/tx v0.13.1 h1:Mg+EMp67Pz+NukbJqYxuo8uRp7N/a9uR+oVS9pONtj8= +cosmossdk.io/x/tx v0.13.1/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= cosmossdk.io/x/upgrade v0.1.0 h1:z1ZZG4UL9ICTNbJDYZ6jOnF9GdEK9wyoEFi4BUScHXE= cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -348,6 +348,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -378,12 +380,12 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV 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= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= -github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= +github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= +github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987 h1:Pjvcy7wHUoYh253LvNv5Dyx+d3SNkRPsDZH+FytqZ3w= -github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987/go.mod h1:0D9mrUy1eAUMQuvYzf2xvhEPk2ta9w7XH1zcYvyFiuM= +github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA= +github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= @@ -395,8 +397,8 @@ github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= -github.com/cosmos/ibc-go/v8 v8.0.0/go.mod h1:C6IiJom0F3cIQCD5fKwVPDrDK9j/xTu563AWuOmXois= +github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE= +github.com/cosmos/ibc-go/v8 v8.2.0/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= @@ -468,6 +470,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= @@ -510,6 +514,11 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= @@ -582,8 +591,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -643,8 +652,8 @@ github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -787,8 +796,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -1033,8 +1042,9 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1045,8 +1055,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -1099,6 +1110,18 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1139,8 +1162,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1520,8 +1543,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= +google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1638,12 +1661,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 h1:x9PwdEgd11LgK+orcck69WVRo7DezSO4VUMPI4xpc8A= +google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1685,8 +1708,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= +google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1703,8 +1726,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 37429abec0a514c4dbf95074fb231ff8464fdca8 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 30 May 2024 12:17:07 +1000 Subject: [PATCH 07/21] feat(finality): merkle-tree-based public randomness commitment (#354) Closes #350 This PR implements Merkle tree-based public randomness commitment. This includes - reverting the BIP-32 thing that is vulnerable - introducing storage of Merkle proofs - revising semantics of submitting public randomness and finality signatures Future works that will be done in subsequent PRs: - **DB schema:** instead of storing all proofs (which is O(n log n)), we need to find an efficient way to store Merkle tree and keep it in memory when it's used. - **Optimisation of proof generation/veirfictaion:** we are considering to use pollarding of Merkle tree, i.e., babylon side remembers the top X levels in the Merkle tree and the Merkle proof will become hashses in the levels lower than X. see https://github.com/wealdtech/go-merkletree/blob/master/pollard.go - **Better vector commitment schemes:** Merkle tree has other variants that have better performance in scenarios with millions of leaves. Ethereum community has stuff like Verkle tree and SSZ --- Dockerfile | 6 +- clientcontroller/babylon.go | 149 ++++--- clientcontroller/interface.go | 19 +- eotsmanager/client/rpcclient.go | 25 +- eotsmanager/eotsmanager.go | 11 +- eotsmanager/localmanager.go | 49 ++- eotsmanager/localmanager_test.go | 32 +- eotsmanager/proto/eotsmanager.pb.go | 248 ++++++----- eotsmanager/proto/eotsmanager.proto | 20 +- eotsmanager/proto/eotsmanager_grpc.pb.go | 65 ++- eotsmanager/randgenerator/randgenerator.go | 29 ++ eotsmanager/service/rpcserver.go | 17 +- finality-provider/cmd/fpcli/daemon/export.go | 11 +- finality-provider/proto/finality_providers.go | 2 - .../proto/finality_providers.pb.go | 366 +++++++--------- .../proto/finality_providers.proto | 28 +- .../proto/finality_providers_grpc.pb.go | 42 +- finality-provider/service/app.go | 112 +++-- finality-provider/service/app_test.go | 5 +- .../service/eots_manager_adapter.go | 68 +++ finality-provider/service/fastsync.go | 8 + finality-provider/service/fastsync_test.go | 85 +++- finality-provider/service/fp_instance.go | 401 ++++++++++++++++-- finality-provider/service/fp_instance_test.go | 70 ++- finality-provider/service/fp_manager.go | 15 +- finality-provider/service/fp_manager_test.go | 32 +- .../service/{types.go => fp_store_adapter.go} | 59 +-- .../service/pub_rand_store_adapter.go | 30 ++ finality-provider/store/errors.go | 6 + finality-provider/store/fpstore.go | 19 +- finality-provider/store/fpstore_test.go | 2 - finality-provider/store/pub_rand.go | 136 ++++++ finality-provider/store/storedfp.go | 7 - go.mod | 71 ++-- go.sum | 140 +++--- itest/babylon_node_handler.go | 1 - itest/e2e_test.go | 28 +- itest/test_manager.go | 184 ++------ keyring/randgenerator.go | 24 -- metrics/eots_collectors.go | 36 +- testutil/datagen.go | 24 +- testutil/mocks/babylon.go | 84 ++-- tools/go.mod | 68 +-- tools/go.sum | 144 +++---- types/chainkey.go | 4 - types/pub_rand_commit.go | 17 + 46 files changed, 1796 insertions(+), 1203 deletions(-) create mode 100644 eotsmanager/randgenerator/randgenerator.go create mode 100644 finality-provider/service/eots_manager_adapter.go rename finality-provider/service/{types.go => fp_store_adapter.go} (77%) create mode 100644 finality-provider/service/pub_rand_store_adapter.go create mode 100644 finality-provider/store/pub_rand.go delete mode 100644 keyring/randgenerator.go create mode 100644 types/pub_rand_commit.go diff --git a/Dockerfile b/Dockerfile index dd5a7b21..6f9899cc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,12 +21,12 @@ RUN go mod download COPY ./ /go/src/github.com/babylonchain/finality-provider/ # Cosmwasm - Download correct libwasmvm version -RUN WASMVM_VERSION=$(go list -m github.com/CosmWasm/wasmvm | cut -d ' ' -f 2) && \ +RUN WASMVM_VERSION=$(grep github.com/CosmWasm/wasmvm go.mod | cut -d' ' -f2) && \ wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/libwasmvm_muslc.$(uname -m).a \ - -O /lib/libwasmvm_muslc.a && \ + -O /lib/libwasmvm_muslc.$(uname -m).a && \ # verify checksum wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/checksums.txt -O /tmp/checksums.txt && \ - sha256sum /lib/libwasmvm_muslc.a | grep $(cat /tmp/checksums.txt | grep libwasmvm_muslc.$(uname -m) | cut -d ' ' -f 1) + sha256sum /lib/libwasmvm_muslc.$(uname -m).a | grep $(cat /tmp/checksums.txt | grep libwasmvm_muslc.$(uname -m) | cut -d ' ' -f 1) RUN CGO_LDFLAGS="$CGO_LDFLAGS -lstdc++ -lm -lsodium" \ CGO_ENABLED=1 \ diff --git a/clientcontroller/babylon.go b/clientcontroller/babylon.go index a2396c59..d5ba0f25 100644 --- a/clientcontroller/babylon.go +++ b/clientcontroller/babylon.go @@ -6,19 +6,18 @@ import ( "time" sdkErr "cosmossdk.io/errors" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcutil" - "cosmossdk.io/math" bbnclient "github.com/babylonchain/babylon/client/client" bbntypes "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" finalitytypes "github.com/babylonchain/babylon/x/finality/types" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" + cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" @@ -110,55 +109,94 @@ func (bc *BabylonController) reliablySendMsgs(msgs []sdk.Msg, expectedErrs []*sd } // RegisterFinalityProvider registers a finality provider via a MsgCreateFinalityProvider to Babylon -// it returns tx hash, registered epoch, and error +// it returns tx hash and error func (bc *BabylonController) RegisterFinalityProvider( chainPk []byte, fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, description []byte, - masterPubRand string, -) (*types.TxResponse, uint64, error) { +) (*types.TxResponse, error) { var bbnPop btcstakingtypes.ProofOfPossession if err := bbnPop.Unmarshal(pop); err != nil { - return nil, 0, fmt.Errorf("invalid proof-of-possession: %w", err) + return nil, fmt.Errorf("invalid proof-of-possession: %w", err) } var sdkDescription sttypes.Description if err := sdkDescription.Unmarshal(description); err != nil { - return nil, 0, fmt.Errorf("invalid description: %w", err) + return nil, fmt.Errorf("invalid description: %w", err) } msg := &btcstakingtypes.MsgCreateFinalityProvider{ - Signer: bc.mustGetTxSigner(), - BabylonPk: &secp256k1.PubKey{Key: chainPk}, - BtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk), - Pop: &bbnPop, - Commission: commission, - Description: &sdkDescription, - MasterPubRand: masterPubRand, + Signer: bc.mustGetTxSigner(), + BabylonPk: &secp256k1.PubKey{Key: chainPk}, + BtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk), + Pop: &bbnPop, + Commission: commission, + Description: &sdkDescription, } res, err := bc.reliablySendMsg(msg, emptyErrs, emptyErrs) if err != nil { - return nil, 0, err + return nil, err + } + + return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil +} + +// CommitPubRandList commits a list of Schnorr public randomness via a MsgCommitPubRand to Babylon +// it returns tx hash and error +func (bc *BabylonController) CommitPubRandList( + fpPk *btcec.PublicKey, + startHeight uint64, + numPubRand uint64, + commitment []byte, + sig *schnorr.Signature, +) (*types.TxResponse, error) { + msg := &finalitytypes.MsgCommitPubRandList{ + Signer: bc.mustGetTxSigner(), + FpBtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk), + StartHeight: startHeight, + NumPubRand: numPubRand, + Commitment: commitment, + Sig: bbntypes.NewBIP340SignatureFromBTCSig(sig), } - registeredEpoch, err := bc.QueryFinalityProviderRegisteredEpoch(fpPk) + unrecoverableErrs := []*sdkErr.Error{ + finalitytypes.ErrInvalidPubRand, + finalitytypes.ErrTooFewPubRand, + finalitytypes.ErrNoPubRandYet, + btcstakingtypes.ErrFpNotFound, + } + + res, err := bc.reliablySendMsg(msg, emptyErrs, unrecoverableErrs) if err != nil { - return nil, 0, err + return nil, err } - return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, registeredEpoch, nil + return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil } // SubmitFinalitySig submits the finality signature via a MsgAddVote to Babylon -func (bc *BabylonController) SubmitFinalitySig(fpPk *btcec.PublicKey, blockHeight uint64, blockHash []byte, sig *btcec.ModNScalar) (*types.TxResponse, error) { +func (bc *BabylonController) SubmitFinalitySig( + fpPk *btcec.PublicKey, + block *types.BlockInfo, + pubRand *btcec.FieldVal, + proof []byte, // TODO: have a type for proof + sig *btcec.ModNScalar, +) (*types.TxResponse, error) { + cmtProof := cmtcrypto.Proof{} + if err := cmtProof.Unmarshal(proof); err != nil { + return nil, err + } + msg := &finalitytypes.MsgAddFinalitySig{ Signer: bc.mustGetTxSigner(), FpBtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk), - BlockHeight: blockHeight, - BlockAppHash: blockHash, + BlockHeight: block.Height, + PubRand: bbntypes.NewSchnorrPubRandFromFieldVal(pubRand), + Proof: &cmtProof, + BlockAppHash: block.Hash, FinalitySig: bbntypes.NewSchnorrEOTSSigFromModNScalar(sig), } @@ -177,17 +215,30 @@ func (bc *BabylonController) SubmitFinalitySig(fpPk *btcec.PublicKey, blockHeigh } // SubmitBatchFinalitySigs submits a batch of finality signatures to Babylon -func (bc *BabylonController) SubmitBatchFinalitySigs(fpPk *btcec.PublicKey, blocks []*types.BlockInfo, sigs []*btcec.ModNScalar) (*types.TxResponse, error) { +func (bc *BabylonController) SubmitBatchFinalitySigs( + fpPk *btcec.PublicKey, + blocks []*types.BlockInfo, + pubRandList []*btcec.FieldVal, + proofList [][]byte, + sigs []*btcec.ModNScalar, +) (*types.TxResponse, error) { if len(blocks) != len(sigs) { return nil, fmt.Errorf("the number of blocks %v should match the number of finality signatures %v", len(blocks), len(sigs)) } msgs := make([]sdk.Msg, 0, len(blocks)) for i, b := range blocks { + cmtProof := cmtcrypto.Proof{} + if err := cmtProof.Unmarshal(proofList[i]); err != nil { + return nil, err + } + msg := &finalitytypes.MsgAddFinalitySig{ Signer: bc.mustGetTxSigner(), FpBtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk), BlockHeight: b.Height, + PubRand: bbntypes.NewSchnorrPubRandFromFieldVal(pubRandList[i]), + Proof: &cmtProof, BlockAppHash: b.Hash, FinalitySig: bbntypes.NewSchnorrEOTSSigFromModNScalar(sigs[i]), } @@ -227,34 +278,32 @@ func (bc *BabylonController) QueryFinalityProviderVotingPower(fpPk *btcec.Public blockHeight, ) if err != nil { - return 0, fmt.Errorf("failed to query the finality provider's voting power at height %d: %w", blockHeight, err) + return 0, fmt.Errorf("failed to query BTC delegations: %w", err) } return res.VotingPower, nil } -// QueryFinalityProviderRegisteredEpoch queries the registered epoch of the finality provider -func (bc *BabylonController) QueryFinalityProviderRegisteredEpoch(fpPk *btcec.PublicKey) (uint64, error) { - res, err := bc.bbnClient.QueryClient.FinalityProvider( - bbntypes.NewBIP340PubKeyFromBTCPK(fpPk).MarshalHex(), - ) - if err != nil { - return 0, fmt.Errorf("failed to query finality provider registered epoch: %w", err) - } - - return res.FinalityProvider.RegisteredEpoch, nil -} - func (bc *BabylonController) QueryLatestFinalizedBlocks(count uint64) ([]*types.BlockInfo, error) { return bc.queryLatestBlocks(nil, count, finalitytypes.QueriedBlockStatus_FINALIZED, true) } -func (bc *BabylonController) QueryLastFinalizedEpoch() (uint64, error) { - resp, err := bc.bbnClient.LatestEpochFromStatus(ckpttypes.Finalized) +// QueryLastCommittedPublicRand returns the last public randomness commitments +func (bc *BabylonController) QueryLastCommittedPublicRand(fpPk *btcec.PublicKey, count uint64) (map[uint64]*finalitytypes.PubRandCommitResponse, error) { + fpBtcPk := bbntypes.NewBIP340PubKeyFromBTCPK(fpPk) + + pagination := &sdkquery.PageRequest{ + // NOTE: the count is limited by pagination queries + Limit: count, + Reverse: true, + } + + res, err := bc.bbnClient.QueryClient.ListPubRandCommit(fpBtcPk.MarshalHex(), pagination) if err != nil { - return 0, err + return nil, fmt.Errorf("failed to query committed public randomness: %w", err) } - return resp.RawCheckpoint.EpochNum, nil + + return res.PubRandCommitMap, nil } func (bc *BabylonController) QueryBlocks(startHeight, endHeight, limit uint64) ([]*types.BlockInfo, error) { @@ -359,10 +408,6 @@ func (bc *BabylonController) Close() error { Implementations for e2e tests only */ -func (bc *BabylonController) GetBBNClient() *bbnclient.Client { - return bc.bbnClient -} - func (bc *BabylonController) CreateBTCDelegation( delBabylonPk *secp256k1.PubKey, delBtcPk *bbntypes.BIP340PubKey, @@ -550,17 +595,3 @@ func (bc *BabylonController) SubmitCovenantSigs( return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil } - -func (bc *BabylonController) InsertSpvProofs(submitter string, proofs []*btcctypes.BTCSpvProof) (*provider.RelayerTxResponse, error) { - msg := &btcctypes.MsgInsertBTCSpvProof{ - Submitter: submitter, - Proofs: proofs, - } - - res, err := bc.reliablySendMsg(msg, emptyErrs, emptyErrs) - if err != nil { - return nil, err - } - - return res, nil -} diff --git a/clientcontroller/interface.go b/clientcontroller/interface.go index f6597c21..6590e005 100644 --- a/clientcontroller/interface.go +++ b/clientcontroller/interface.go @@ -5,9 +5,11 @@ import ( "cosmossdk.io/math" "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg" "go.uber.org/zap" + finalitytypes "github.com/babylonchain/babylon/x/finality/types" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" "github.com/babylonchain/finality-provider/types" ) @@ -26,14 +28,17 @@ type ClientController interface { pop []byte, commission *math.LegacyDec, description []byte, - masterPubRand string, - ) (*types.TxResponse, uint64, error) + ) (*types.TxResponse, error) + + // CommitPubRandList commits a list of EOTS public randomness the consumer chain + // it returns tx hash and error + CommitPubRandList(fpPk *btcec.PublicKey, startHeight uint64, numPubRand uint64, commitment []byte, sig *schnorr.Signature) (*types.TxResponse, error) // SubmitFinalitySig submits the finality signature to the consumer chain - SubmitFinalitySig(fpPk *btcec.PublicKey, blockHeight uint64, blockHash []byte, sig *btcec.ModNScalar) (*types.TxResponse, error) + SubmitFinalitySig(fpPk *btcec.PublicKey, block *types.BlockInfo, pubRand *btcec.FieldVal, proof []byte, sig *btcec.ModNScalar) (*types.TxResponse, error) // SubmitBatchFinalitySigs submits a batch of finality signatures to the consumer chain - SubmitBatchFinalitySigs(fpPk *btcec.PublicKey, blocks []*types.BlockInfo, sigs []*btcec.ModNScalar) (*types.TxResponse, error) + SubmitBatchFinalitySigs(fpPk *btcec.PublicKey, blocks []*types.BlockInfo, pubRandList []*btcec.FieldVal, proofList [][]byte, sigs []*btcec.ModNScalar) (*types.TxResponse, error) // Note: the following queries are only for PoC @@ -46,6 +51,9 @@ type ClientController interface { // QueryLatestFinalizedBlocks returns the latest finalized blocks QueryLatestFinalizedBlocks(count uint64) ([]*types.BlockInfo, error) + // QueryLastCommittedPublicRand returns the last committed public randomness + QueryLastCommittedPublicRand(fpPk *btcec.PublicKey, count uint64) (map[uint64]*finalitytypes.PubRandCommitResponse, error) + // QueryBlock queries the block at the given height QueryBlock(height uint64) (*types.BlockInfo, error) @@ -59,9 +67,6 @@ type ClientController interface { // error will be returned if the consumer chain has not been activated QueryActivatedHeight() (uint64, error) - // QueryLastFinalizedEpoch returns the last finalised epoch of Babylon - QueryLastFinalizedEpoch() (uint64, error) - Close() error } diff --git a/eotsmanager/client/rpcclient.go b/eotsmanager/client/rpcclient.go index d35f9fc6..585e9daf 100644 --- a/eotsmanager/client/rpcclient.go +++ b/eotsmanager/client/rpcclient.go @@ -60,18 +60,27 @@ func (c *EOTSManagerGRpcClient) CreateKey(name, passphrase, hdPath string) ([]by return res.Pk, nil } -func (c *EOTSManagerGRpcClient) CreateMasterRandPair(uid, chainID []byte, passphrase string) (string, error) { - req := &proto.CreateMasterRandPairRequest{ - Uid: uid, - ChainId: chainID, - Passphrase: passphrase, +func (c *EOTSManagerGRpcClient) CreateRandomnessPairList(uid, chainID []byte, startHeight uint64, num uint32, passphrase string) ([]*btcec.FieldVal, error) { + req := &proto.CreateRandomnessPairListRequest{ + Uid: uid, + ChainId: chainID, + StartHeight: startHeight, + Num: num, + Passphrase: passphrase, } - res, err := c.client.CreateMasterRandPair(context.Background(), req) + res, err := c.client.CreateRandomnessPairList(context.Background(), req) if err != nil { - return "", err + return nil, err + } + + pubRandFieldValList := make([]*btcec.FieldVal, 0, len(res.PubRandList)) + for _, r := range res.PubRandList { + var fieldVal btcec.FieldVal + fieldVal.SetByteSlice(r) + pubRandFieldValList = append(pubRandFieldValList, &fieldVal) } - return res.MasterPubRand, nil + return pubRandFieldValList, nil } func (c *EOTSManagerGRpcClient) KeyRecord(uid []byte, passphrase string) (*types.KeyRecord, error) { diff --git a/eotsmanager/eotsmanager.go b/eotsmanager/eotsmanager.go index 57db75ce..2e8e1619 100644 --- a/eotsmanager/eotsmanager.go +++ b/eotsmanager/eotsmanager.go @@ -13,10 +13,13 @@ type EOTSManager interface { // It fails if there is an existing key Info with the same name or public key. CreateKey(name, passphrase, hdPath string) ([]byte, error) - // CreateMasterRandPair generates a pair of master secret/public randomness - // It fails if the finality provider does not exist or passPhrase is incorrect - // NOTE: the master randomness pair is deterministically generated based on the EOTS key and chainID - CreateMasterRandPair(uid []byte, chainID []byte, passphrase string) (string, error) + // CreateRandomnessPairList generates a list of Schnorr randomness pairs from + // startHeight to startHeight+(num-1) where num means the number of public randomness + // It fails if the finality provider does not exist or a randomness pair has been created before + // or passPhrase is incorrect + // NOTE: the randomness is deterministically generated based on the EOTS key, chainID and + // block height + CreateRandomnessPairList(uid []byte, chainID []byte, startHeight uint64, num uint32, passphrase string) ([]*btcec.FieldVal, error) // KeyRecord returns the finality provider record // It fails if the finality provider does not exist or passPhrase is incorrect diff --git a/eotsmanager/localmanager.go b/eotsmanager/localmanager.go index 4362c690..8e7aa2ee 100644 --- a/eotsmanager/localmanager.go +++ b/eotsmanager/localmanager.go @@ -18,9 +18,9 @@ import ( "go.uber.org/zap" "github.com/babylonchain/finality-provider/codec" + "github.com/babylonchain/finality-provider/eotsmanager/randgenerator" "github.com/babylonchain/finality-provider/eotsmanager/store" eotstypes "github.com/babylonchain/finality-provider/eotsmanager/types" - fpkeyring "github.com/babylonchain/finality-provider/keyring" ) const ( @@ -161,30 +161,32 @@ func loadBIP340PubKeyFromKeyringRecord(record *keyring.Record) (*bbntypes.BIP340 } } -// CreateMasterRandPair creates a pair of master secret/public randomness deterministically -// from the finality provider's secret key and chain ID -func (lm *LocalEOTSManager) CreateMasterRandPair(fpPk []byte, chainID []byte, passphrase string) (string, error) { - _, mpr, err := lm.getMasterRandPair(fpPk, chainID, passphrase) - if err != nil { - return "", err +// TODO the current implementation is a PoC, which does not contain any anti-slasher mechanism +// +// a simple anti-slasher mechanism could be that the manager remembers the tuple (fpPk, chainID, height) or +// the hash of each generated randomness and return error if the same randomness is requested tweice +func (lm *LocalEOTSManager) CreateRandomnessPairList(fpPk []byte, chainID []byte, startHeight uint64, num uint32, passphrase string) ([]*btcec.FieldVal, error) { + prList := make([]*btcec.FieldVal, 0, num) + + for i := uint32(0); i < num; i++ { + height := startHeight + uint64(i) + _, pubRand, err := lm.getRandomnessPair(fpPk, chainID, height, passphrase) + if err != nil { + return nil, err + } + + prList = append(prList, pubRand) } + lm.metrics.IncrementEotsFpTotalGeneratedRandomnessCounter(hex.EncodeToString(fpPk)) + lm.metrics.SetEotsFpLastGeneratedRandomnessHeight(hex.EncodeToString(fpPk), float64(startHeight)) - return mpr.MarshalBase58(), nil + return prList, nil } func (lm *LocalEOTSManager) SignEOTS(fpPk []byte, chainID []byte, msg []byte, height uint64, passphrase string) (*btcec.ModNScalar, error) { - // get master secret randomness - // TODO: instead of calculating master secret randomness everytime, is it possible - // to manage it in the keyring? - msr, _, err := lm.getMasterRandPair(fpPk, chainID, passphrase) - if err != nil { - return nil, fmt.Errorf("failed to get master secret randomness: %w", err) - } - - // derive secret randomness - sr, _, err := msr.DeriveRandPair(uint32(height)) // TODO: generalise to uint64 + privRand, _, err := lm.getRandomnessPair(fpPk, chainID, height, passphrase) if err != nil { - return nil, fmt.Errorf("failed to get secret randomness: %w", err) + return nil, fmt.Errorf("failed to get private randomness: %w", err) } privKey, err := lm.getEOTSPrivKey(fpPk, passphrase) @@ -196,7 +198,7 @@ func (lm *LocalEOTSManager) SignEOTS(fpPk []byte, chainID []byte, msg []byte, he lm.metrics.IncrementEotsFpTotalEotsSignCounter(hex.EncodeToString(fpPk)) lm.metrics.SetEotsFpLastEotsSignHeight(hex.EncodeToString(fpPk), float64(height)) - return eots.Sign(privKey, sr, msg) + return eots.Sign(privKey, privRand, msg) } func (lm *LocalEOTSManager) SignSchnorrSig(fpPk []byte, msg []byte, passphrase string) (*schnorr.Signature, error) { @@ -243,13 +245,14 @@ func (lm *LocalEOTSManager) Close() error { return nil } -// getMasterRandPair returns a randomness pair generated based on the given finality provider key, chainID and height -func (lm *LocalEOTSManager) getMasterRandPair(fpPk []byte, chainID []byte, passphrase string) (*eots.MasterSecretRand, *eots.MasterPublicRand, error) { +// getRandomnessPair returns a randomness pair generated based on the given finality provider key, chainID and height +func (lm *LocalEOTSManager) getRandomnessPair(fpPk []byte, chainID []byte, height uint64, passphrase string) (*eots.PrivateRand, *eots.PublicRand, error) { record, err := lm.KeyRecord(fpPk, passphrase) if err != nil { return nil, nil, err } - return fpkeyring.GenerateMasterRandPair(record.PrivKey.Serialize(), chainID) + privRand, pubRand := randgenerator.GenerateRandomness(record.PrivKey.Serialize(), chainID, height) + return privRand, pubRand, nil } // TODO: we ignore passPhrase in local implementation for now diff --git a/eotsmanager/localmanager_test.go b/eotsmanager/localmanager_test.go index 5696fe92..adea480c 100644 --- a/eotsmanager/localmanager_test.go +++ b/eotsmanager/localmanager_test.go @@ -6,15 +6,14 @@ import ( "path/filepath" "testing" - "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "github.com/babylonchain/finality-provider/eotsmanager" eotscfg "github.com/babylonchain/finality-provider/eotsmanager/config" "github.com/babylonchain/finality-provider/eotsmanager/types" "github.com/babylonchain/finality-provider/testutil" - "github.com/stretchr/testify/require" - "go.uber.org/zap" ) var ( @@ -58,7 +57,7 @@ func FuzzCreateKey(f *testing.F) { }) } -func FuzzCreateMasterRandPair(f *testing.F) { +func FuzzCreateRandomnessPairList(f *testing.F) { testutil.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) @@ -78,33 +77,18 @@ func FuzzCreateMasterRandPair(f *testing.F) { fpPk, err := lm.CreateKey(fpName, passphrase, hdPath) require.NoError(t, err) - fpBTCPK, err := bbn.NewBIP340PubKey(fpPk) - require.NoError(t, err) chainID := datagen.GenRandomByteArray(r, 10) - - mprStr, err := lm.CreateMasterRandPair(fpPk, chainID, passphrase) - require.NoError(t, err) - mpr, err := eots.NewMasterPublicRandFromBase58(mprStr) - require.NoError(t, err) - startHeight := datagen.RandomInt(r, 100) num := r.Intn(10) + 1 + pubRandList, err := lm.CreateRandomnessPairList(fpPk, chainID, startHeight, uint32(num), passphrase) + require.NoError(t, err) + require.Len(t, pubRandList, num) for i := 0; i < num; i++ { - height := startHeight + uint64(i) - msg := datagen.GenRandomByteArray(r, 32) - - // sign EOTS signature at each height - sig, err := lm.SignEOTS(fpPk, chainID, msg, height, passphrase) + sig, err := lm.SignEOTS(fpPk, chainID, datagen.GenRandomByteArray(r, 32), startHeight+uint64(i), passphrase) require.NoError(t, err) require.NotNil(t, sig) - - // verify using the master public randomness and height - pr, err := mpr.DerivePubRand(uint32(height)) - require.NoError(t, err) - err = eots.Verify(fpBTCPK.MustToBTCPK(), pr, msg, sig) - require.NoError(t, err) } }) } diff --git a/eotsmanager/proto/eotsmanager.pb.go b/eotsmanager/proto/eotsmanager.pb.go index e1ea111d..be042366 100644 --- a/eotsmanager/proto/eotsmanager.pb.go +++ b/eotsmanager/proto/eotsmanager.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.32.0 // protoc (unknown) // source: eotsmanager.proto @@ -210,7 +210,7 @@ func (x *CreateKeyResponse) GetPk() []byte { return nil } -type CreateMasterRandPairRequest struct { +type CreateRandomnessPairListRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -219,12 +219,16 @@ type CreateMasterRandPairRequest struct { Uid []byte `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` // chain_id is the identifier of the consumer chain that the randomness is committed to ChainId []byte `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // start_height is the start height of the randomness pair list + StartHeight uint64 `protobuf:"varint,3,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` + // num is the number of randomness pair list + Num uint32 `protobuf:"varint,4,opt,name=num,proto3" json:"num,omitempty"` // passphrase is used to decrypt the EOTS key - Passphrase string `protobuf:"bytes,3,opt,name=passphrase,proto3" json:"passphrase,omitempty"` + Passphrase string `protobuf:"bytes,5,opt,name=passphrase,proto3" json:"passphrase,omitempty"` } -func (x *CreateMasterRandPairRequest) Reset() { - *x = CreateMasterRandPairRequest{} +func (x *CreateRandomnessPairListRequest) Reset() { + *x = CreateRandomnessPairListRequest{} if protoimpl.UnsafeEnabled { mi := &file_eotsmanager_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -232,13 +236,13 @@ func (x *CreateMasterRandPairRequest) Reset() { } } -func (x *CreateMasterRandPairRequest) String() string { +func (x *CreateRandomnessPairListRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateMasterRandPairRequest) ProtoMessage() {} +func (*CreateRandomnessPairListRequest) ProtoMessage() {} -func (x *CreateMasterRandPairRequest) ProtoReflect() protoreflect.Message { +func (x *CreateRandomnessPairListRequest) ProtoReflect() protoreflect.Message { mi := &file_eotsmanager_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -250,43 +254,57 @@ func (x *CreateMasterRandPairRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateMasterRandPairRequest.ProtoReflect.Descriptor instead. -func (*CreateMasterRandPairRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use CreateRandomnessPairListRequest.ProtoReflect.Descriptor instead. +func (*CreateRandomnessPairListRequest) Descriptor() ([]byte, []int) { return file_eotsmanager_proto_rawDescGZIP(), []int{4} } -func (x *CreateMasterRandPairRequest) GetUid() []byte { +func (x *CreateRandomnessPairListRequest) GetUid() []byte { if x != nil { return x.Uid } return nil } -func (x *CreateMasterRandPairRequest) GetChainId() []byte { +func (x *CreateRandomnessPairListRequest) GetChainId() []byte { if x != nil { return x.ChainId } return nil } -func (x *CreateMasterRandPairRequest) GetPassphrase() string { +func (x *CreateRandomnessPairListRequest) GetStartHeight() uint64 { + if x != nil { + return x.StartHeight + } + return 0 +} + +func (x *CreateRandomnessPairListRequest) GetNum() uint32 { + if x != nil { + return x.Num + } + return 0 +} + +func (x *CreateRandomnessPairListRequest) GetPassphrase() string { if x != nil { return x.Passphrase } return "" } -type CreateMasterRandPairResponse struct { +type CreateRandomnessPairListResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // master_pub_rand is a master public randomness in base58 format - MasterPubRand string `protobuf:"bytes,1,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` + // pub_rand_list is a list of Schnorr public randomness + PubRandList [][]byte `protobuf:"bytes,1,rep,name=pub_rand_list,json=pubRandList,proto3" json:"pub_rand_list,omitempty"` } -func (x *CreateMasterRandPairResponse) Reset() { - *x = CreateMasterRandPairResponse{} +func (x *CreateRandomnessPairListResponse) Reset() { + *x = CreateRandomnessPairListResponse{} if protoimpl.UnsafeEnabled { mi := &file_eotsmanager_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -294,13 +312,13 @@ func (x *CreateMasterRandPairResponse) Reset() { } } -func (x *CreateMasterRandPairResponse) String() string { +func (x *CreateRandomnessPairListResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateMasterRandPairResponse) ProtoMessage() {} +func (*CreateRandomnessPairListResponse) ProtoMessage() {} -func (x *CreateMasterRandPairResponse) ProtoReflect() protoreflect.Message { +func (x *CreateRandomnessPairListResponse) ProtoReflect() protoreflect.Message { mi := &file_eotsmanager_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -312,16 +330,16 @@ func (x *CreateMasterRandPairResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateMasterRandPairResponse.ProtoReflect.Descriptor instead. -func (*CreateMasterRandPairResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use CreateRandomnessPairListResponse.ProtoReflect.Descriptor instead. +func (*CreateRandomnessPairListResponse) Descriptor() ([]byte, []int) { return file_eotsmanager_proto_rawDescGZIP(), []int{5} } -func (x *CreateMasterRandPairResponse) GetMasterPubRand() string { +func (x *CreateRandomnessPairListResponse) GetPubRandList() [][]byte { if x != nil { - return x.MasterPubRand + return x.PubRandList } - return "" + return nil } type KeyRecordRequest struct { @@ -699,78 +717,82 @@ var file_eotsmanager_proto_rawDesc = []byte{ 0x28, 0x09, 0x52, 0x06, 0x68, 0x64, 0x50, 0x61, 0x74, 0x68, 0x22, 0x23, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x70, 0x6b, 0x22, - 0x6a, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x52, - 0x61, 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, - 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x75, 0x69, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, - 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x1c, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x52, 0x61, 0x6e, 0x64, 0x50, - 0x61, 0x69, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x50, 0x75, 0x62, 0x52, - 0x61, 0x6e, 0x64, 0x22, 0x44, 0x0a, 0x10, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0xa3, 0x01, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x6e, 0x65, 0x73, 0x73, 0x50, 0x61, 0x69, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73, 0x50, 0x61, 0x69, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x75, 0x62, + 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x0b, 0x70, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x44, 0x0a, + 0x10, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, + 0x75, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x22, 0x48, 0x0a, 0x11, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x88, 0x01, + 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, + 0x75, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x10, + 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, + 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, + 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, + 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x24, 0x0a, 0x10, 0x53, 0x69, 0x67, 0x6e, + 0x45, 0x4f, 0x54, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x5b, + 0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, - 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, - 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x48, 0x0a, 0x11, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x22, 0x88, 0x01, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, 0x53, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1e, - 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x24, - 0x0a, 0x10, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x03, 0x73, 0x69, 0x67, 0x22, 0x5b, 0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, - 0x6f, 0x72, 0x72, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, - 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, - 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, - 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, - 0x65, 0x22, 0x2a, 0x0a, 0x16, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, - 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, - 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x32, 0xab, 0x03, - 0x0a, 0x0b, 0x45, 0x4f, 0x54, 0x53, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 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, 0x3e, - 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, - 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x52, 0x61, - 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x52, 0x61, 0x6e, 0x64, 0x50, - 0x61, 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x52, - 0x61, 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3e, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x17, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, - 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3b, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, 0x53, 0x12, 0x16, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, 0x53, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, - 0x45, 0x4f, 0x54, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, - 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x53, 0x69, 0x67, 0x12, 0x1c, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, - 0x72, 0x72, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, - 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x41, 0x5a, 0x3f, 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, 0x74, 0x63, 0x2d, 0x66, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x65, 0x6f, 0x74, - 0x73, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x70, + 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x16, 0x53, + 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x32, 0xb7, 0x03, 0x0a, 0x0b, 0x45, 0x4f, 0x54, 0x53, + 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 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, 0x3e, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73, 0x50, 0x61, 0x69, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73, 0x50, 0x61, 0x69, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x64, 0x6f, + 0x6d, 0x6e, 0x65, 0x73, 0x73, 0x50, 0x61, 0x69, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, + 0x53, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, + 0x54, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x4f, 0x54, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, + 0x72, 0x53, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, + 0x6e, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x53, + 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x41, 0x5a, 0x3f, 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, 0x74, 0x63, + 0x2d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2f, 0x65, 0x6f, 0x74, 0x73, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -787,29 +809,29 @@ func file_eotsmanager_proto_rawDescGZIP() []byte { var file_eotsmanager_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_eotsmanager_proto_goTypes = []interface{}{ - (*PingRequest)(nil), // 0: proto.PingRequest - (*PingResponse)(nil), // 1: proto.PingResponse - (*CreateKeyRequest)(nil), // 2: proto.CreateKeyRequest - (*CreateKeyResponse)(nil), // 3: proto.CreateKeyResponse - (*CreateMasterRandPairRequest)(nil), // 4: proto.CreateMasterRandPairRequest - (*CreateMasterRandPairResponse)(nil), // 5: proto.CreateMasterRandPairResponse - (*KeyRecordRequest)(nil), // 6: proto.KeyRecordRequest - (*KeyRecordResponse)(nil), // 7: proto.KeyRecordResponse - (*SignEOTSRequest)(nil), // 8: proto.SignEOTSRequest - (*SignEOTSResponse)(nil), // 9: proto.SignEOTSResponse - (*SignSchnorrSigRequest)(nil), // 10: proto.SignSchnorrSigRequest - (*SignSchnorrSigResponse)(nil), // 11: proto.SignSchnorrSigResponse + (*PingRequest)(nil), // 0: proto.PingRequest + (*PingResponse)(nil), // 1: proto.PingResponse + (*CreateKeyRequest)(nil), // 2: proto.CreateKeyRequest + (*CreateKeyResponse)(nil), // 3: proto.CreateKeyResponse + (*CreateRandomnessPairListRequest)(nil), // 4: proto.CreateRandomnessPairListRequest + (*CreateRandomnessPairListResponse)(nil), // 5: proto.CreateRandomnessPairListResponse + (*KeyRecordRequest)(nil), // 6: proto.KeyRecordRequest + (*KeyRecordResponse)(nil), // 7: proto.KeyRecordResponse + (*SignEOTSRequest)(nil), // 8: proto.SignEOTSRequest + (*SignEOTSResponse)(nil), // 9: proto.SignEOTSResponse + (*SignSchnorrSigRequest)(nil), // 10: proto.SignSchnorrSigRequest + (*SignSchnorrSigResponse)(nil), // 11: proto.SignSchnorrSigResponse } var file_eotsmanager_proto_depIdxs = []int32{ 0, // 0: proto.EOTSManager.Ping:input_type -> proto.PingRequest 2, // 1: proto.EOTSManager.CreateKey:input_type -> proto.CreateKeyRequest - 4, // 2: proto.EOTSManager.CreateMasterRandPair:input_type -> proto.CreateMasterRandPairRequest + 4, // 2: proto.EOTSManager.CreateRandomnessPairList:input_type -> proto.CreateRandomnessPairListRequest 6, // 3: proto.EOTSManager.KeyRecord:input_type -> proto.KeyRecordRequest 8, // 4: proto.EOTSManager.SignEOTS:input_type -> proto.SignEOTSRequest 10, // 5: proto.EOTSManager.SignSchnorrSig:input_type -> proto.SignSchnorrSigRequest 1, // 6: proto.EOTSManager.Ping:output_type -> proto.PingResponse 3, // 7: proto.EOTSManager.CreateKey:output_type -> proto.CreateKeyResponse - 5, // 8: proto.EOTSManager.CreateMasterRandPair:output_type -> proto.CreateMasterRandPairResponse + 5, // 8: proto.EOTSManager.CreateRandomnessPairList:output_type -> proto.CreateRandomnessPairListResponse 7, // 9: proto.EOTSManager.KeyRecord:output_type -> proto.KeyRecordResponse 9, // 10: proto.EOTSManager.SignEOTS:output_type -> proto.SignEOTSResponse 11, // 11: proto.EOTSManager.SignSchnorrSig:output_type -> proto.SignSchnorrSigResponse @@ -875,7 +897,7 @@ func file_eotsmanager_proto_init() { } } file_eotsmanager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMasterRandPairRequest); i { + switch v := v.(*CreateRandomnessPairListRequest); i { case 0: return &v.state case 1: @@ -887,7 +909,7 @@ func file_eotsmanager_proto_init() { } } file_eotsmanager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMasterRandPairResponse); i { + switch v := v.(*CreateRandomnessPairListResponse); i { case 0: return &v.state case 1: diff --git a/eotsmanager/proto/eotsmanager.proto b/eotsmanager/proto/eotsmanager.proto index 7997dc2a..866a9de0 100644 --- a/eotsmanager/proto/eotsmanager.proto +++ b/eotsmanager/proto/eotsmanager.proto @@ -11,9 +11,9 @@ service EOTSManager { rpc CreateKey (CreateKeyRequest) returns (CreateKeyResponse); - // CreateMasterRandPair creates a pair of master secret/public randomness - rpc CreateMasterRandPair (CreateMasterRandPairRequest) - returns (CreateMasterRandPairResponse); + // CreateRandomnessPairList returns a list of Schnorr randomness pairs + rpc CreateRandomnessPairList (CreateRandomnessPairListRequest) + returns (CreateRandomnessPairListResponse); // KeyRecord returns the key record rpc KeyRecord(KeyRecordRequest) @@ -46,18 +46,22 @@ message CreateKeyResponse { bytes pk = 1; } -message CreateMasterRandPairRequest { +message CreateRandomnessPairListRequest { // uid is the identifier of an EOTS key, i.e., public key following BIP-340 spec bytes uid = 1; // chain_id is the identifier of the consumer chain that the randomness is committed to bytes chain_id = 2; + // start_height is the start height of the randomness pair list + uint64 start_height = 3; + // num is the number of randomness pair list + uint32 num = 4; // passphrase is used to decrypt the EOTS key - string passphrase = 3; + string passphrase = 5; } -message CreateMasterRandPairResponse { - // master_pub_rand is a master public randomness in base58 format - string master_pub_rand = 1; +message CreateRandomnessPairListResponse { + // pub_rand_list is a list of Schnorr public randomness + repeated bytes pub_rand_list = 1; } message KeyRecordRequest { diff --git a/eotsmanager/proto/eotsmanager_grpc.pb.go b/eotsmanager/proto/eotsmanager_grpc.pb.go index 9db90b12..75b1e5cf 100644 --- a/eotsmanager/proto/eotsmanager_grpc.pb.go +++ b/eotsmanager/proto/eotsmanager_grpc.pb.go @@ -1,8 +1,4 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: eotsmanager.proto package proto @@ -18,15 +14,6 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 -const ( - EOTSManager_Ping_FullMethodName = "/proto.EOTSManager/Ping" - EOTSManager_CreateKey_FullMethodName = "/proto.EOTSManager/CreateKey" - EOTSManager_CreateMasterRandPair_FullMethodName = "/proto.EOTSManager/CreateMasterRandPair" - EOTSManager_KeyRecord_FullMethodName = "/proto.EOTSManager/KeyRecord" - EOTSManager_SignEOTS_FullMethodName = "/proto.EOTSManager/SignEOTS" - EOTSManager_SignSchnorrSig_FullMethodName = "/proto.EOTSManager/SignSchnorrSig" -) - // EOTSManagerClient is the client API for EOTSManager 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. @@ -34,8 +21,8 @@ type EOTSManagerClient interface { Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) // CreateKey generates and saves an EOTS key CreateKey(ctx context.Context, in *CreateKeyRequest, opts ...grpc.CallOption) (*CreateKeyResponse, error) - // CreateMasterRandPair creates a pair of master secret/public randomness - CreateMasterRandPair(ctx context.Context, in *CreateMasterRandPairRequest, opts ...grpc.CallOption) (*CreateMasterRandPairResponse, error) + // CreateRandomnessPairList returns a list of Schnorr randomness pairs + CreateRandomnessPairList(ctx context.Context, in *CreateRandomnessPairListRequest, opts ...grpc.CallOption) (*CreateRandomnessPairListResponse, error) // KeyRecord returns the key record KeyRecord(ctx context.Context, in *KeyRecordRequest, opts ...grpc.CallOption) (*KeyRecordResponse, error) // SignEOTS signs an EOTS with the EOTS private key and the relevant randomness @@ -54,7 +41,7 @@ func NewEOTSManagerClient(cc grpc.ClientConnInterface) EOTSManagerClient { func (c *eOTSManagerClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { out := new(PingResponse) - err := c.cc.Invoke(ctx, EOTSManager_Ping_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.EOTSManager/Ping", in, out, opts...) if err != nil { return nil, err } @@ -63,16 +50,16 @@ func (c *eOTSManagerClient) Ping(ctx context.Context, in *PingRequest, opts ...g func (c *eOTSManagerClient) CreateKey(ctx context.Context, in *CreateKeyRequest, opts ...grpc.CallOption) (*CreateKeyResponse, error) { out := new(CreateKeyResponse) - err := c.cc.Invoke(ctx, EOTSManager_CreateKey_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.EOTSManager/CreateKey", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *eOTSManagerClient) CreateMasterRandPair(ctx context.Context, in *CreateMasterRandPairRequest, opts ...grpc.CallOption) (*CreateMasterRandPairResponse, error) { - out := new(CreateMasterRandPairResponse) - err := c.cc.Invoke(ctx, EOTSManager_CreateMasterRandPair_FullMethodName, in, out, opts...) +func (c *eOTSManagerClient) CreateRandomnessPairList(ctx context.Context, in *CreateRandomnessPairListRequest, opts ...grpc.CallOption) (*CreateRandomnessPairListResponse, error) { + out := new(CreateRandomnessPairListResponse) + err := c.cc.Invoke(ctx, "/proto.EOTSManager/CreateRandomnessPairList", in, out, opts...) if err != nil { return nil, err } @@ -81,7 +68,7 @@ func (c *eOTSManagerClient) CreateMasterRandPair(ctx context.Context, in *Create func (c *eOTSManagerClient) KeyRecord(ctx context.Context, in *KeyRecordRequest, opts ...grpc.CallOption) (*KeyRecordResponse, error) { out := new(KeyRecordResponse) - err := c.cc.Invoke(ctx, EOTSManager_KeyRecord_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.EOTSManager/KeyRecord", in, out, opts...) if err != nil { return nil, err } @@ -90,7 +77,7 @@ func (c *eOTSManagerClient) KeyRecord(ctx context.Context, in *KeyRecordRequest, func (c *eOTSManagerClient) SignEOTS(ctx context.Context, in *SignEOTSRequest, opts ...grpc.CallOption) (*SignEOTSResponse, error) { out := new(SignEOTSResponse) - err := c.cc.Invoke(ctx, EOTSManager_SignEOTS_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.EOTSManager/SignEOTS", in, out, opts...) if err != nil { return nil, err } @@ -99,7 +86,7 @@ func (c *eOTSManagerClient) SignEOTS(ctx context.Context, in *SignEOTSRequest, o func (c *eOTSManagerClient) SignSchnorrSig(ctx context.Context, in *SignSchnorrSigRequest, opts ...grpc.CallOption) (*SignSchnorrSigResponse, error) { out := new(SignSchnorrSigResponse) - err := c.cc.Invoke(ctx, EOTSManager_SignSchnorrSig_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.EOTSManager/SignSchnorrSig", in, out, opts...) if err != nil { return nil, err } @@ -113,8 +100,8 @@ type EOTSManagerServer interface { Ping(context.Context, *PingRequest) (*PingResponse, error) // CreateKey generates and saves an EOTS key CreateKey(context.Context, *CreateKeyRequest) (*CreateKeyResponse, error) - // CreateMasterRandPair creates a pair of master secret/public randomness - CreateMasterRandPair(context.Context, *CreateMasterRandPairRequest) (*CreateMasterRandPairResponse, error) + // CreateRandomnessPairList returns a list of Schnorr randomness pairs + CreateRandomnessPairList(context.Context, *CreateRandomnessPairListRequest) (*CreateRandomnessPairListResponse, error) // KeyRecord returns the key record KeyRecord(context.Context, *KeyRecordRequest) (*KeyRecordResponse, error) // SignEOTS signs an EOTS with the EOTS private key and the relevant randomness @@ -134,8 +121,8 @@ func (UnimplementedEOTSManagerServer) Ping(context.Context, *PingRequest) (*Ping func (UnimplementedEOTSManagerServer) CreateKey(context.Context, *CreateKeyRequest) (*CreateKeyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateKey not implemented") } -func (UnimplementedEOTSManagerServer) CreateMasterRandPair(context.Context, *CreateMasterRandPairRequest) (*CreateMasterRandPairResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateMasterRandPair not implemented") +func (UnimplementedEOTSManagerServer) CreateRandomnessPairList(context.Context, *CreateRandomnessPairListRequest) (*CreateRandomnessPairListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateRandomnessPairList not implemented") } func (UnimplementedEOTSManagerServer) KeyRecord(context.Context, *KeyRecordRequest) (*KeyRecordResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method KeyRecord not implemented") @@ -169,7 +156,7 @@ func _EOTSManager_Ping_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: EOTSManager_Ping_FullMethodName, + FullMethod: "/proto.EOTSManager/Ping", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).Ping(ctx, req.(*PingRequest)) @@ -187,7 +174,7 @@ func _EOTSManager_CreateKey_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: EOTSManager_CreateKey_FullMethodName, + FullMethod: "/proto.EOTSManager/CreateKey", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).CreateKey(ctx, req.(*CreateKeyRequest)) @@ -195,20 +182,20 @@ func _EOTSManager_CreateKey_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -func _EOTSManager_CreateMasterRandPair_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateMasterRandPairRequest) +func _EOTSManager_CreateRandomnessPairList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateRandomnessPairListRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(EOTSManagerServer).CreateMasterRandPair(ctx, in) + return srv.(EOTSManagerServer).CreateRandomnessPairList(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: EOTSManager_CreateMasterRandPair_FullMethodName, + FullMethod: "/proto.EOTSManager/CreateRandomnessPairList", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EOTSManagerServer).CreateMasterRandPair(ctx, req.(*CreateMasterRandPairRequest)) + return srv.(EOTSManagerServer).CreateRandomnessPairList(ctx, req.(*CreateRandomnessPairListRequest)) } return interceptor(ctx, in, info, handler) } @@ -223,7 +210,7 @@ func _EOTSManager_KeyRecord_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: EOTSManager_KeyRecord_FullMethodName, + FullMethod: "/proto.EOTSManager/KeyRecord", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).KeyRecord(ctx, req.(*KeyRecordRequest)) @@ -241,7 +228,7 @@ func _EOTSManager_SignEOTS_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: EOTSManager_SignEOTS_FullMethodName, + FullMethod: "/proto.EOTSManager/SignEOTS", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).SignEOTS(ctx, req.(*SignEOTSRequest)) @@ -259,7 +246,7 @@ func _EOTSManager_SignSchnorrSig_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: EOTSManager_SignSchnorrSig_FullMethodName, + FullMethod: "/proto.EOTSManager/SignSchnorrSig", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).SignSchnorrSig(ctx, req.(*SignSchnorrSigRequest)) @@ -283,8 +270,8 @@ var EOTSManager_ServiceDesc = grpc.ServiceDesc{ Handler: _EOTSManager_CreateKey_Handler, }, { - MethodName: "CreateMasterRandPair", - Handler: _EOTSManager_CreateMasterRandPair_Handler, + MethodName: "CreateRandomnessPairList", + Handler: _EOTSManager_CreateRandomnessPairList_Handler, }, { MethodName: "KeyRecord", diff --git a/eotsmanager/randgenerator/randgenerator.go b/eotsmanager/randgenerator/randgenerator.go new file mode 100644 index 00000000..570031f0 --- /dev/null +++ b/eotsmanager/randgenerator/randgenerator.go @@ -0,0 +1,29 @@ +package randgenerator + +import ( + "crypto/hmac" + "crypto/sha256" + + "github.com/babylonchain/babylon/crypto/eots" + "github.com/btcsuite/btcd/btcec/v2" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// GenerateRandomness generates a random scalar with the given key and src +// the result is deterministic with each given input +func GenerateRandomness(key []byte, chainID []byte, height uint64) (*eots.PrivateRand, *eots.PublicRand) { + // calculate the randomn hash of the key concatenated with chainID and height + digest := hmac.New(sha256.New, key) + digest.Write(append(sdk.Uint64ToBigEndian(height), chainID...)) + randPre := digest.Sum(nil) + + // convert the hash into private random + var randScalar btcec.ModNScalar + randScalar.SetByteSlice(randPre) + privRand := secp256k1.NewPrivateKey(&randScalar) + var j secp256k1.JacobianPoint + privRand.PubKey().AsJacobian(&j) + + return &privRand.Key, &j.X +} diff --git a/eotsmanager/service/rpcserver.go b/eotsmanager/service/rpcserver.go index 13acb351..b8cc4990 100644 --- a/eotsmanager/service/rpcserver.go +++ b/eotsmanager/service/rpcserver.go @@ -52,16 +52,23 @@ func (r *rpcServer) CreateKey(ctx context.Context, req *proto.CreateKeyRequest) return &proto.CreateKeyResponse{Pk: pk}, nil } -// CreateMasterRandPair returns a list of Schnorr randomness pairs -func (r *rpcServer) CreateMasterRandPair(ctx context.Context, req *proto.CreateMasterRandPairRequest) (*proto.CreateMasterRandPairResponse, error) { +// CreateRandomnessPairList returns a list of Schnorr randomness pairs +func (r *rpcServer) CreateRandomnessPairList(ctx context.Context, req *proto.CreateRandomnessPairListRequest) ( + *proto.CreateRandomnessPairListResponse, error) { + + pubRandList, err := r.em.CreateRandomnessPairList(req.Uid, req.ChainId, req.StartHeight, req.Num, req.Passphrase) - mpr, err := r.em.CreateMasterRandPair(req.Uid, req.ChainId, req.Passphrase) if err != nil { return nil, err } - return &proto.CreateMasterRandPairResponse{ - MasterPubRand: mpr, + pubRandBytesList := make([][]byte, 0, len(pubRandList)) + for _, p := range pubRandList { + pubRandBytesList = append(pubRandBytesList, p.Bytes()[:]) + } + + return &proto.CreateRandomnessPairListResponse{ + PubRandList: pubRandBytesList, }, nil } diff --git a/finality-provider/cmd/fpcli/daemon/export.go b/finality-provider/cmd/fpcli/daemon/export.go index 5a73b9ea..a1cb6bf1 100644 --- a/finality-provider/cmd/fpcli/daemon/export.go +++ b/finality-provider/cmd/fpcli/daemon/export.go @@ -108,14 +108,6 @@ func exportFp(ctx *cli.Context) error { desc := fpInfo.Description fp := btcstktypes.FinalityProvider{ - BtcPk: fpPk, - MasterPubRand: fpInfo.MasterPubRand, - Pop: &btcstktypes.ProofOfPossession{ - BtcSigType: btcstktypes.BTCSigType_BIP340, - BabylonSig: fpInfo.Pop.ChainSig, - BtcSig: fpInfo.Pop.BtcSig, - }, - BabylonPk: cosmosPubKey, Description: &types.Description{ Moniker: desc.Moniker, Identity: desc.Identity, @@ -124,6 +116,9 @@ func exportFp(ctx *cli.Context) error { Details: desc.Details, }, Commission: &comm, + BtcPk: fpPk, + BabylonPk: cosmosPubKey, + Pop: nil, // TODO: fill PoP? } if !ctx.Bool(signedFlag) { diff --git a/finality-provider/proto/finality_providers.go b/finality-provider/proto/finality_providers.go index 86f69819..6762ecb4 100644 --- a/finality-provider/proto/finality_providers.go +++ b/finality-provider/proto/finality_providers.go @@ -49,8 +49,6 @@ func NewFinalityProviderInfo(sfp *FinalityProvider) (*FinalityProviderInfo, erro SecurityContact: des.SecurityContact, Details: des.Details, }, - RegisteredEpoch: sfp.RegisteredEpoch, - MasterPubRand: sfp.MasterPubRand, LastVotedHeight: sfp.LastVotedHeight, Status: sfp.Status.String(), }, nil diff --git a/finality-provider/proto/finality_providers.pb.go b/finality-provider/proto/finality_providers.pb.go index 5a05b1ae..3446847f 100644 --- a/finality-provider/proto/finality_providers.pb.go +++ b/finality-provider/proto/finality_providers.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.32.0 // protoc (unknown) // source: finality_providers.proto @@ -756,22 +756,17 @@ type FinalityProvider struct { Commission string `protobuf:"bytes,4,opt,name=commission,proto3" json:"commission,omitempty"` // pop is the proof of possession of chain_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` - // registered_epoch is the epoch number when the finality provider is registered on Babylon - RegisteredEpoch uint64 `protobuf:"varint,7,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // key_name is the identifier of the keyring - KeyName string `protobuf:"bytes,8,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + KeyName string `protobuf:"bytes,6,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` // chain_id is the identifier of the consumer chain that the finality provider connected to - ChainId string `protobuf:"bytes,9,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ChainId string `protobuf:"bytes,7,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // last_voted_height defines the height of the last voted chain block - LastVotedHeight uint64 `protobuf:"varint,10,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` + LastVotedHeight uint64 `protobuf:"varint,8,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` // last_processed_height defines the height of the last successfully processed block // even though the vote is not cast - LastProcessedHeight uint64 `protobuf:"varint,11,opt,name=last_processed_height,json=lastProcessedHeight,proto3" json:"last_processed_height,omitempty"` + LastProcessedHeight uint64 `protobuf:"varint,9,opt,name=last_processed_height,json=lastProcessedHeight,proto3" json:"last_processed_height,omitempty"` // status defines the current finality provider status - Status FinalityProviderStatus `protobuf:"varint,12,opt,name=status,proto3,enum=proto.FinalityProviderStatus" json:"status,omitempty"` + Status FinalityProviderStatus `protobuf:"varint,10,opt,name=status,proto3,enum=proto.FinalityProviderStatus" json:"status,omitempty"` } func (x *FinalityProvider) Reset() { @@ -841,20 +836,6 @@ func (x *FinalityProvider) GetPop() *ProofOfPossession { return nil } -func (x *FinalityProvider) GetMasterPubRand() string { - if x != nil { - return x.MasterPubRand - } - return "" -} - -func (x *FinalityProvider) GetRegisteredEpoch() uint64 { - if x != nil { - return x.RegisteredEpoch - } - return 0 -} - func (x *FinalityProvider) GetKeyName() string { if x != nil { return x.KeyName @@ -904,19 +885,12 @@ type FinalityProviderInfo struct { Description *Description `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // commission defines the commission rate for the finality provider Commission string `protobuf:"bytes,4,opt,name=commission,proto3" json:"commission,omitempty"` - // registered_epoch is the epoch number when the finality provider is registered on Babylon - RegisteredEpoch uint64 `protobuf:"varint,5,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // last_voted_height defines the height of the last voted chain block - LastVotedHeight uint64 `protobuf:"varint,7,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` + LastVotedHeight uint64 `protobuf:"varint,5,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` // status defines the current finality provider status - Status string `protobuf:"bytes,8,opt,name=status,proto3" json:"status,omitempty"` + Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"` // is_running shows whether the finality provider is running within the daemon - IsRunning bool `protobuf:"varint,9,opt,name=is_running,json=isRunning,proto3" json:"is_running,omitempty"` - // pop is the proof of possession of chain_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,10,opt,name=pop,proto3" json:"pop,omitempty"` + IsRunning bool `protobuf:"varint,7,opt,name=is_running,json=isRunning,proto3" json:"is_running,omitempty"` } func (x *FinalityProviderInfo) Reset() { @@ -979,20 +953,6 @@ func (x *FinalityProviderInfo) GetCommission() string { return "" } -func (x *FinalityProviderInfo) GetRegisteredEpoch() uint64 { - if x != nil { - return x.RegisteredEpoch - } - return 0 -} - -func (x *FinalityProviderInfo) GetMasterPubRand() string { - if x != nil { - return x.MasterPubRand - } - return "" -} - func (x *FinalityProviderInfo) GetLastVotedHeight() uint64 { if x != nil { return x.LastVotedHeight @@ -1014,13 +974,6 @@ func (x *FinalityProviderInfo) GetIsRunning() bool { return false } -func (x *FinalityProviderInfo) GetPop() *ProofOfPossession { - if x != nil { - return x.Pop - } - return nil -} - // Description defines description fields for a finality provider type Description struct { state protoimpl.MessageState @@ -1420,7 +1373,7 @@ var file_finality_providers_proto_rawDesc = []byte{ 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xf7, 0x03, 0x0a, 0x10, 0x46, 0x69, 0x6e, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xa4, 0x03, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x6b, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x74, 0x63, 0x5f, @@ -1434,145 +1387,131 @@ var file_finality_providers_proto_rawDesc = []byte{ 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x03, 0x70, 0x6f, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, - 0x6f, 0x70, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, - 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x50, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, - 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, - 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x35, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x22, 0xb3, 0x03, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x1c, 0x0a, - 0x0a, 0x62, 0x74, 0x63, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x62, 0x74, 0x63, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x43, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, - 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x65, 0x64, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x45, 0x70, 0x6f, 0x63, - 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x5f, - 0x72, 0x61, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x50, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, - 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x2a, 0x0a, 0x03, - 0x70, 0x6f, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, 0x6f, 0x70, 0x22, 0xa2, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x69, - 0x6b, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, - 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x18, - 0x0a, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x49, 0x0a, - 0x11, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x12, - 0x17, 0x0a, 0x07, 0x62, 0x74, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x62, 0x74, 0x63, 0x53, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x6e, - 0x6f, 0x72, 0x72, 0x52, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x70, - 0x75, 0x62, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, - 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x5f, 0x72, 0x61, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x63, 0x52, 0x61, 0x6e, - 0x64, 0x22, 0x94, 0x01, 0x0a, 0x1e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x6d, 0x73, 0x67, 0x5f, 0x74, 0x6f, 0x5f, 0x73, - 0x69, 0x67, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x54, 0x6f, - 0x53, 0x69, 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, - 0x17, 0x0a, 0x07, 0x68, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x68, 0x64, 0x50, 0x61, 0x74, 0x68, 0x22, 0x3f, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2a, 0xa6, 0x01, 0x0a, 0x16, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, - 0x00, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x12, 0x1e, - 0x0a, 0x0a, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0e, - 0x8a, 0x9d, 0x20, 0x0a, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x12, 0x16, - 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, - 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, - 0x56, 0x45, 0x10, 0x03, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, - 0x56, 0x45, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x04, 0x1a, - 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x1a, 0x04, 0x88, 0xa3, - 0x1e, 0x00, 0x32, 0xc0, 0x05, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x19, 0x51, + 0x6f, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0xb4, 0x02, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x0a, 0x62, 0x74, + 0x63, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x62, 0x74, 0x63, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, + 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x23, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, + 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, + 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, + 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x52, + 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0xa2, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, + 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, + 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, + 0x74, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x49, 0x0a, 0x11, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x12, 0x17, 0x0a, + 0x07, 0x62, 0x74, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x62, 0x74, 0x63, 0x53, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, + 0x72, 0x52, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x62, + 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, + 0x52, 0x61, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x22, + 0x94, 0x01, 0x0a, 0x1e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, + 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x6d, 0x73, 0x67, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x69, 0x67, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x54, 0x6f, 0x53, 0x69, + 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x17, 0x0a, + 0x07, 0x68, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x68, 0x64, 0x50, 0x61, 0x74, 0x68, 0x22, 0x3f, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2a, 0xa6, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x1a, + 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x12, 0x1e, 0x0a, 0x0a, + 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0e, 0x8a, 0x9d, + 0x20, 0x0a, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x12, 0x16, 0x0a, 0x06, + 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x41, 0x43, + 0x54, 0x49, 0x56, 0x45, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x10, 0x03, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x12, 0x18, 0x0a, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x04, 0x1a, 0x0b, 0x8a, + 0x9d, 0x20, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, + 0x32, 0xc0, 0x05, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x65, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, + 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x23, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x19, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x17, 0x53, - 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, - 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x17, 0x53, 0x69, 0x67, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, + 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1618,26 +1557,25 @@ var file_finality_providers_proto_depIdxs = []int32{ 16, // 3: proto.FinalityProvider.pop:type_name -> proto.ProofOfPossession 0, // 4: proto.FinalityProvider.status:type_name -> proto.FinalityProviderStatus 15, // 5: proto.FinalityProviderInfo.description:type_name -> proto.Description - 16, // 6: proto.FinalityProviderInfo.pop:type_name -> proto.ProofOfPossession - 1, // 7: proto.FinalityProviders.GetInfo:input_type -> proto.GetInfoRequest - 3, // 8: proto.FinalityProviders.CreateFinalityProvider:input_type -> proto.CreateFinalityProviderRequest - 5, // 9: proto.FinalityProviders.RegisterFinalityProvider:input_type -> proto.RegisterFinalityProviderRequest - 7, // 10: proto.FinalityProviders.AddFinalitySignature:input_type -> proto.AddFinalitySignatureRequest - 9, // 11: proto.FinalityProviders.QueryFinalityProvider:input_type -> proto.QueryFinalityProviderRequest - 11, // 12: proto.FinalityProviders.QueryFinalityProviderList:input_type -> proto.QueryFinalityProviderListRequest - 18, // 13: proto.FinalityProviders.SignMessageFromChainKey:input_type -> proto.SignMessageFromChainKeyRequest - 2, // 14: proto.FinalityProviders.GetInfo:output_type -> proto.GetInfoResponse - 4, // 15: proto.FinalityProviders.CreateFinalityProvider:output_type -> proto.CreateFinalityProviderResponse - 6, // 16: proto.FinalityProviders.RegisterFinalityProvider:output_type -> proto.RegisterFinalityProviderResponse - 8, // 17: proto.FinalityProviders.AddFinalitySignature:output_type -> proto.AddFinalitySignatureResponse - 10, // 18: proto.FinalityProviders.QueryFinalityProvider:output_type -> proto.QueryFinalityProviderResponse - 12, // 19: proto.FinalityProviders.QueryFinalityProviderList:output_type -> proto.QueryFinalityProviderListResponse - 19, // 20: proto.FinalityProviders.SignMessageFromChainKey:output_type -> proto.SignMessageFromChainKeyResponse - 14, // [14:21] is the sub-list for method output_type - 7, // [7:14] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 1, // 6: proto.FinalityProviders.GetInfo:input_type -> proto.GetInfoRequest + 3, // 7: proto.FinalityProviders.CreateFinalityProvider:input_type -> proto.CreateFinalityProviderRequest + 5, // 8: proto.FinalityProviders.RegisterFinalityProvider:input_type -> proto.RegisterFinalityProviderRequest + 7, // 9: proto.FinalityProviders.AddFinalitySignature:input_type -> proto.AddFinalitySignatureRequest + 9, // 10: proto.FinalityProviders.QueryFinalityProvider:input_type -> proto.QueryFinalityProviderRequest + 11, // 11: proto.FinalityProviders.QueryFinalityProviderList:input_type -> proto.QueryFinalityProviderListRequest + 18, // 12: proto.FinalityProviders.SignMessageFromChainKey:input_type -> proto.SignMessageFromChainKeyRequest + 2, // 13: proto.FinalityProviders.GetInfo:output_type -> proto.GetInfoResponse + 4, // 14: proto.FinalityProviders.CreateFinalityProvider:output_type -> proto.CreateFinalityProviderResponse + 6, // 15: proto.FinalityProviders.RegisterFinalityProvider:output_type -> proto.RegisterFinalityProviderResponse + 8, // 16: proto.FinalityProviders.AddFinalitySignature:output_type -> proto.AddFinalitySignatureResponse + 10, // 17: proto.FinalityProviders.QueryFinalityProvider:output_type -> proto.QueryFinalityProviderResponse + 12, // 18: proto.FinalityProviders.QueryFinalityProviderList:output_type -> proto.QueryFinalityProviderListResponse + 19, // 19: proto.FinalityProviders.SignMessageFromChainKey:output_type -> proto.SignMessageFromChainKeyResponse + 13, // [13:20] is the sub-list for method output_type + 6, // [6:13] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_finality_providers_proto_init() } diff --git a/finality-provider/proto/finality_providers.proto b/finality-provider/proto/finality_providers.proto index ea587916..ffcab9b4 100644 --- a/finality-provider/proto/finality_providers.proto +++ b/finality-provider/proto/finality_providers.proto @@ -129,22 +129,17 @@ message FinalityProvider { ]; // pop is the proof of possession of chain_pk and btc_pk ProofOfPossession pop = 5; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 6; - // registered_epoch is the epoch number when the finality provider is registered on Babylon - uint64 registered_epoch = 7; // key_name is the identifier of the keyring - string key_name = 8; + string key_name = 6; // chain_id is the identifier of the consumer chain that the finality provider connected to - string chain_id = 9; + string chain_id = 7; // last_voted_height defines the height of the last voted chain block - uint64 last_voted_height = 10; + uint64 last_voted_height = 8; // last_processed_height defines the height of the last successfully processed block // even though the vote is not cast - uint64 last_processed_height = 11; + uint64 last_processed_height = 9; // status defines the current finality provider status - FinalityProviderStatus status = 12; + FinalityProviderStatus status = 10; } // FinalityProviderInfo is the basic information of a finality provider mainly for external usage @@ -160,19 +155,12 @@ message FinalityProviderInfo { (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", (gogoproto.nullable) = false ]; - // registered_epoch is the epoch number when the finality provider is registered on Babylon - uint64 registered_epoch = 5; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 6; // last_voted_height defines the height of the last voted chain block - uint64 last_voted_height = 7; + uint64 last_voted_height = 5; // status defines the current finality provider status - string status = 8; + string status = 6; // is_running shows whether the finality provider is running within the daemon - bool is_running = 9; - // pop is the proof of possession of chain_pk and btc_pk - ProofOfPossession pop = 10; + bool is_running = 7; } // Description defines description fields for a finality provider diff --git a/finality-provider/proto/finality_providers_grpc.pb.go b/finality-provider/proto/finality_providers_grpc.pb.go index e2d7bdca..6480c381 100644 --- a/finality-provider/proto/finality_providers_grpc.pb.go +++ b/finality-provider/proto/finality_providers_grpc.pb.go @@ -1,8 +1,4 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: finality_providers.proto package proto @@ -18,16 +14,6 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 -const ( - FinalityProviders_GetInfo_FullMethodName = "/proto.FinalityProviders/GetInfo" - FinalityProviders_CreateFinalityProvider_FullMethodName = "/proto.FinalityProviders/CreateFinalityProvider" - FinalityProviders_RegisterFinalityProvider_FullMethodName = "/proto.FinalityProviders/RegisterFinalityProvider" - FinalityProviders_AddFinalitySignature_FullMethodName = "/proto.FinalityProviders/AddFinalitySignature" - FinalityProviders_QueryFinalityProvider_FullMethodName = "/proto.FinalityProviders/QueryFinalityProvider" - FinalityProviders_QueryFinalityProviderList_FullMethodName = "/proto.FinalityProviders/QueryFinalityProviderList" - FinalityProviders_SignMessageFromChainKey_FullMethodName = "/proto.FinalityProviders/SignMessageFromChainKey" -) - // FinalityProvidersClient is the client API for FinalityProviders 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. @@ -60,7 +46,7 @@ func NewFinalityProvidersClient(cc grpc.ClientConnInterface) FinalityProvidersCl func (c *finalityProvidersClient) GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) { out := new(GetInfoResponse) - err := c.cc.Invoke(ctx, FinalityProviders_GetInfo_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/GetInfo", in, out, opts...) if err != nil { return nil, err } @@ -69,7 +55,7 @@ func (c *finalityProvidersClient) GetInfo(ctx context.Context, in *GetInfoReques func (c *finalityProvidersClient) CreateFinalityProvider(ctx context.Context, in *CreateFinalityProviderRequest, opts ...grpc.CallOption) (*CreateFinalityProviderResponse, error) { out := new(CreateFinalityProviderResponse) - err := c.cc.Invoke(ctx, FinalityProviders_CreateFinalityProvider_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/CreateFinalityProvider", in, out, opts...) if err != nil { return nil, err } @@ -78,7 +64,7 @@ func (c *finalityProvidersClient) CreateFinalityProvider(ctx context.Context, in func (c *finalityProvidersClient) RegisterFinalityProvider(ctx context.Context, in *RegisterFinalityProviderRequest, opts ...grpc.CallOption) (*RegisterFinalityProviderResponse, error) { out := new(RegisterFinalityProviderResponse) - err := c.cc.Invoke(ctx, FinalityProviders_RegisterFinalityProvider_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/RegisterFinalityProvider", in, out, opts...) if err != nil { return nil, err } @@ -87,7 +73,7 @@ func (c *finalityProvidersClient) RegisterFinalityProvider(ctx context.Context, func (c *finalityProvidersClient) AddFinalitySignature(ctx context.Context, in *AddFinalitySignatureRequest, opts ...grpc.CallOption) (*AddFinalitySignatureResponse, error) { out := new(AddFinalitySignatureResponse) - err := c.cc.Invoke(ctx, FinalityProviders_AddFinalitySignature_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/AddFinalitySignature", in, out, opts...) if err != nil { return nil, err } @@ -96,7 +82,7 @@ func (c *finalityProvidersClient) AddFinalitySignature(ctx context.Context, in * func (c *finalityProvidersClient) QueryFinalityProvider(ctx context.Context, in *QueryFinalityProviderRequest, opts ...grpc.CallOption) (*QueryFinalityProviderResponse, error) { out := new(QueryFinalityProviderResponse) - err := c.cc.Invoke(ctx, FinalityProviders_QueryFinalityProvider_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/QueryFinalityProvider", in, out, opts...) if err != nil { return nil, err } @@ -105,7 +91,7 @@ func (c *finalityProvidersClient) QueryFinalityProvider(ctx context.Context, in func (c *finalityProvidersClient) QueryFinalityProviderList(ctx context.Context, in *QueryFinalityProviderListRequest, opts ...grpc.CallOption) (*QueryFinalityProviderListResponse, error) { out := new(QueryFinalityProviderListResponse) - err := c.cc.Invoke(ctx, FinalityProviders_QueryFinalityProviderList_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/QueryFinalityProviderList", in, out, opts...) if err != nil { return nil, err } @@ -114,7 +100,7 @@ func (c *finalityProvidersClient) QueryFinalityProviderList(ctx context.Context, func (c *finalityProvidersClient) SignMessageFromChainKey(ctx context.Context, in *SignMessageFromChainKeyRequest, opts ...grpc.CallOption) (*SignMessageFromChainKeyResponse, error) { out := new(SignMessageFromChainKeyResponse) - err := c.cc.Invoke(ctx, FinalityProviders_SignMessageFromChainKey_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/proto.FinalityProviders/SignMessageFromChainKey", in, out, opts...) if err != nil { return nil, err } @@ -192,7 +178,7 @@ func _FinalityProviders_GetInfo_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_GetInfo_FullMethodName, + FullMethod: "/proto.FinalityProviders/GetInfo", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).GetInfo(ctx, req.(*GetInfoRequest)) @@ -210,7 +196,7 @@ func _FinalityProviders_CreateFinalityProvider_Handler(srv interface{}, ctx cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_CreateFinalityProvider_FullMethodName, + FullMethod: "/proto.FinalityProviders/CreateFinalityProvider", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).CreateFinalityProvider(ctx, req.(*CreateFinalityProviderRequest)) @@ -228,7 +214,7 @@ func _FinalityProviders_RegisterFinalityProvider_Handler(srv interface{}, ctx co } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_RegisterFinalityProvider_FullMethodName, + FullMethod: "/proto.FinalityProviders/RegisterFinalityProvider", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).RegisterFinalityProvider(ctx, req.(*RegisterFinalityProviderRequest)) @@ -246,7 +232,7 @@ func _FinalityProviders_AddFinalitySignature_Handler(srv interface{}, ctx contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_AddFinalitySignature_FullMethodName, + FullMethod: "/proto.FinalityProviders/AddFinalitySignature", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).AddFinalitySignature(ctx, req.(*AddFinalitySignatureRequest)) @@ -264,7 +250,7 @@ func _FinalityProviders_QueryFinalityProvider_Handler(srv interface{}, ctx conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_QueryFinalityProvider_FullMethodName, + FullMethod: "/proto.FinalityProviders/QueryFinalityProvider", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).QueryFinalityProvider(ctx, req.(*QueryFinalityProviderRequest)) @@ -282,7 +268,7 @@ func _FinalityProviders_QueryFinalityProviderList_Handler(srv interface{}, ctx c } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_QueryFinalityProviderList_FullMethodName, + FullMethod: "/proto.FinalityProviders/QueryFinalityProviderList", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).QueryFinalityProviderList(ctx, req.(*QueryFinalityProviderListRequest)) @@ -300,7 +286,7 @@ func _FinalityProviders_SignMessageFromChainKey_Handler(srv interface{}, ctx con } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FinalityProviders_SignMessageFromChainKey_FullMethodName, + FullMethod: "/proto.FinalityProviders/SignMessageFromChainKey", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).SignMessageFromChainKey(ctx, req.(*SignMessageFromChainKeyRequest)) diff --git a/finality-provider/service/app.go b/finality-provider/service/app.go index 65a2072d..c5c6a971 100644 --- a/finality-provider/service/app.go +++ b/finality-provider/service/app.go @@ -35,12 +35,13 @@ type FinalityProviderApp struct { wg sync.WaitGroup quit chan struct{} - cc clientcontroller.ClientController - kr keyring.Keyring - fps *store.FinalityProviderStore - config *fpcfg.Config - logger *zap.Logger - input *strings.Reader + cc clientcontroller.ClientController + kr keyring.Keyring + fps *store.FinalityProviderStore + pubRandStore *store.PubRandProofStore + config *fpcfg.Config + logger *zap.Logger + input *strings.Reader fpManager *FinalityProviderManager eotsManager eotsmanager.EOTSManager @@ -85,6 +86,10 @@ func NewFinalityProviderApp( if err != nil { return nil, fmt.Errorf("failed to initiate finality provider store: %w", err) } + pubRandStore, err := store.NewPubRandProofStore(db) + if err != nil { + return nil, fmt.Errorf("failed to initiate public randomness store: %w", err) + } input := strings.NewReader("") kr, err := fpkr.CreateKeyring( @@ -99,7 +104,7 @@ func NewFinalityProviderApp( fpMetrics := metrics.NewFpMetrics() - fpm, err := NewFinalityProviderManager(fpStore, config, cc, em, fpMetrics, logger) + fpm, err := NewFinalityProviderManager(fpStore, pubRandStore, config, cc, em, fpMetrics, logger) if err != nil { return nil, fmt.Errorf("failed to create finality-provider manager: %w", err) } @@ -107,6 +112,7 @@ func NewFinalityProviderApp( return &FinalityProviderApp{ cc: cc, fps: fpStore, + pubRandStore: pubRandStore, kr: kr, config: config, logger: logger, @@ -129,6 +135,10 @@ func (app *FinalityProviderApp) GetFinalityProviderStore() *store.FinalityProvid return app.fps } +func (app *FinalityProviderApp) GetPubRandProofStore() *store.PubRandProofStore { + return app.pubRandStore +} + func (app *FinalityProviderApp) GetKeyring() keyring.Keyring { return app.kr } @@ -186,7 +196,6 @@ func (app *FinalityProviderApp) RegisterFinalityProvider(fpPkStr string) (*Regis pop: pop, description: fp.Description, commission: fp.Commission, - masterPubRand: fp.MasterPubRand, errResponse: make(chan error, 1), successResponse: make(chan *RegisterFinalityProviderResponse, 1), } @@ -345,7 +354,54 @@ func (app *FinalityProviderApp) CreateFinalityProvider( } func (app *FinalityProviderApp) handleCreateFinalityProviderRequest(req *createFinalityProviderRequest) (*createFinalityProviderResponse, error) { - storedFp, err := app.StoreFinalityProvider(req.keyName, req.passPhrase, req.hdPath, req.chainID, req.description, req.commission) + // 1. check if the chain key exists + kr, err := fpkr.NewChainKeyringControllerWithKeyring(app.kr, req.keyName, app.input) + if err != nil { + return nil, err + } + chainSk, err := kr.GetChainPrivKey(req.passPhrase) + if err != nil { + // the chain key does not exist, should create the chain key first + keyInfo, err := kr.CreateChainKey(req.passPhrase, req.hdPath, "") + if err != nil { + return nil, fmt.Errorf("failed to create chain key %s: %w", req.keyName, err) + } + chainSk = &secp256k1.PrivKey{Key: keyInfo.PrivateKey.Serialize()} + } + chainPk := &secp256k1.PubKey{Key: chainSk.PubKey().Bytes()} + + // 2. create EOTS key + fpPkBytes, err := app.eotsManager.CreateKey(req.keyName, req.passPhrase, req.hdPath) + if err != nil { + return nil, err + } + fpPk, err := bbntypes.NewBIP340PubKey(fpPkBytes) + if err != nil { + return nil, err + } + fpRecord, err := app.eotsManager.KeyRecord(fpPk.MustMarshal(), req.passPhrase) + if err != nil { + return nil, fmt.Errorf("failed to get finality-provider record: %w", err) + } + + // 3. create proof-of-possession + pop, err := kr.CreatePop(fpRecord.PrivKey, req.passPhrase) + if err != nil { + return nil, fmt.Errorf("failed to create proof-of-possession of the finality-provider: %w", err) + } + + if err := app.fps.CreateFinalityProvider(chainPk, fpPk.MustToBTCPK(), req.description, req.commission, req.keyName, req.chainID, pop.BabylonSig, pop.BtcSig); err != nil { + return nil, fmt.Errorf("failed to save finality-provider: %w", err) + } + app.fpManager.metrics.RecordFpStatus(fpPk.MarshalHex(), proto.FinalityProviderStatus_CREATED) + + app.logger.Info("successfully created a finality-provider", + zap.String("btc_pk", fpPk.MarshalHex()), + zap.String("chain_pk", chainPk.String()), + zap.String("key_name", req.keyName), + ) + + storedFp, err := app.fps.GetFinalityProvider(fpPk.MustToBTCPK()) if err != nil { return nil, err } @@ -422,13 +478,7 @@ func (app *FinalityProviderApp) StoreFinalityProvider( return nil, fmt.Errorf("failed to create proof-of-possession of the finality provider: %w", err) } - // 4. Create derive master public randomness - _, mpr, err := fpkr.GenerateMasterRandPair(fpRecord.PrivKey.Serialize(), types.MarshalChainID(chainID)) - if err != nil { - return nil, fmt.Errorf("failed to get master public randomness of the finality provider: %w", err) - } - - if err := app.fps.CreateFinalityProvider(chainPk, fpPk.MustToBTCPK(), description, commission, mpr.MarshalBase58(), keyName, chainID, pop.BabylonSig, pop.BtcSig); err != nil { + if err := app.fps.CreateFinalityProvider(chainPk, fpPk.MustToBTCPK(), description, commission, keyName, chainID, pop.BabylonSig, pop.BtcSig); err != nil { return nil, fmt.Errorf("failed to save finality-provider: %w", err) } app.fpManager.metrics.RecordFpStatus(fpPk.MarshalHex(), proto.FinalityProviderStatus_CREATED) @@ -483,17 +533,10 @@ func (app *FinalityProviderApp) eventLoop() { req.successResponse <- &createFinalityProviderResponse{FpInfo: res.FpInfo} case ev := <-app.finalityProviderRegisteredEventChan: - btcPK := ev.btcPubKey.MustToBTCPK() - // set the finality provider's registered epoch - if err := app.fps.SetFpRegisteredEpoch(btcPK, ev.registeredEpoch); err != nil { - app.logger.Fatal("failed to set the finality provider's registered epoch", - zap.String("pk", ev.btcPubKey.MarshalHex()), - zap.Error(err), - ) - } // change the status of the finality-provider to registered - if err := app.fps.SetFpStatus(btcPK, proto.FinalityProviderStatus_REGISTERED); err != nil { - app.logger.Fatal("failed to set the finalityprovider's status to REGISTERED", + err := app.fps.SetFpStatus(ev.btcPubKey.MustToBTCPK(), proto.FinalityProviderStatus_REGISTERED) + if err != nil { + app.logger.Fatal("failed to set finality-provider status to REGISTERED", zap.String("pk", ev.btcPubKey.MarshalHex()), zap.Error(err), ) @@ -502,10 +545,9 @@ func (app *FinalityProviderApp) eventLoop() { // return to the caller ev.successResponse <- &RegisterFinalityProviderResponse{ - bbnPubKey: ev.bbnPubKey, - btcPubKey: ev.btcPubKey, - TxHash: ev.txHash, - RegisteredEpoch: ev.registeredEpoch, + bbnPubKey: ev.bbnPubKey, + btcPubKey: ev.btcPubKey, + TxHash: ev.txHash, } case <-app.quit: @@ -534,13 +576,12 @@ func (app *FinalityProviderApp) registrationLoop() { req.errResponse <- err continue } - res, registeredEpoch, err := app.cc.RegisterFinalityProvider( + res, err := app.cc.RegisterFinalityProvider( req.bbnPubKey.Key, req.btcPubKey.MustToBTCPK(), popBytes, req.commission, desBytes, - req.masterPubRand, ) if err != nil { @@ -561,10 +602,9 @@ func (app *FinalityProviderApp) registrationLoop() { ) app.finalityProviderRegisteredEventChan <- &finalityProviderRegisteredEvent{ - btcPubKey: req.btcPubKey, - bbnPubKey: req.bbnPubKey, - txHash: res.TxHash, - registeredEpoch: registeredEpoch, + btcPubKey: req.btcPubKey, + bbnPubKey: req.bbnPubKey, + txHash: res.TxHash, // pass the channel to the event so that we can send the response to the user which requested // the registration successResponse: req.successResponse, diff --git a/finality-provider/service/app_test.go b/finality-provider/service/app_test.go index 69ebd01c..5de3e800 100644 --- a/finality-provider/service/app_test.go +++ b/finality-provider/service/app_test.go @@ -52,7 +52,6 @@ func FuzzRegisterFinalityProvider(f *testing.F) { mockClientController.EXPECT().QueryLatestFinalizedBlocks(gomock.Any()).Return(nil, nil).AnyTimes() mockClientController.EXPECT().QueryFinalityProviderVotingPower(gomock.Any(), gomock.Any()).Return(uint64(0), nil).AnyTimes() - mockClientController.EXPECT().QueryLastFinalizedEpoch().Return(uint64(0), nil).AnyTimes() // Create randomized config fpHomeDir := filepath.Join(t.TempDir(), "fp-home") @@ -105,13 +104,13 @@ func FuzzRegisterFinalityProvider(f *testing.F) { popBytes, testutil.ZeroCommissionRate(), gomock.Any(), - fp.MasterPubRand, - ).Return(&types.TxResponse{TxHash: txHash}, uint64(0), nil).AnyTimes() + ).Return(&types.TxResponse{TxHash: txHash}, nil).AnyTimes() res, err := app.RegisterFinalityProvider(fp.GetBIP340BTCPK().MarshalHex()) require.NoError(t, err) require.Equal(t, txHash, res.TxHash) + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).AnyTimes() err = app.StartHandlingFinalityProvider(fp.GetBIP340BTCPK(), passphrase) require.NoError(t, err) diff --git a/finality-provider/service/eots_manager_adapter.go b/finality-provider/service/eots_manager_adapter.go new file mode 100644 index 00000000..c5eb9835 --- /dev/null +++ b/finality-provider/service/eots_manager_adapter.go @@ -0,0 +1,68 @@ +package service + +import ( + "fmt" + + bbntypes "github.com/babylonchain/babylon/types" + "github.com/babylonchain/finality-provider/types" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/cometbft/cometbft/crypto/tmhash" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (fp *FinalityProviderInstance) getPubRandList(startHeight uint64, numPubRand uint64) ([]*btcec.FieldVal, error) { + pubRandList, err := fp.em.CreateRandomnessPairList( + fp.btcPk.MustMarshal(), + fp.GetChainID(), + startHeight, + uint32(numPubRand), + fp.passphrase, + ) + if err != nil { + return nil, err + } + + return pubRandList, nil +} + +// TODO: have this function in Babylon side +func getHashToSignForCommitPubRand(startHeight uint64, numPubRand uint64, commitment []byte) ([]byte, error) { + hasher := tmhash.New() + if _, err := hasher.Write(sdk.Uint64ToBigEndian(startHeight)); err != nil { + return nil, err + } + if _, err := hasher.Write(sdk.Uint64ToBigEndian(numPubRand)); err != nil { + return nil, err + } + if _, err := hasher.Write(commitment); err != nil { + return nil, err + } + return hasher.Sum(nil), nil +} + +func (fp *FinalityProviderInstance) signPubRandCommit(startHeight uint64, numPubRand uint64, commitment []byte) (*schnorr.Signature, error) { + hash, err := getHashToSignForCommitPubRand(startHeight, numPubRand, commitment) + if err != nil { + return nil, fmt.Errorf("failed to sign the commit public randomness message: %w", err) + } + + // sign the message hash using the finality-provider's BTC private key + return fp.em.SignSchnorrSig(fp.btcPk.MustMarshal(), hash, fp.passphrase) +} + +// TODO: have this function in Babylon side +func getMsgToSignForVote(blockHeight uint64, blockHash []byte) []byte { + return append(sdk.Uint64ToBigEndian(blockHeight), blockHash...) +} + +func (fp *FinalityProviderInstance) signFinalitySig(b *types.BlockInfo) (*bbntypes.SchnorrEOTSSig, error) { + // build proper finality signature request + msgToSign := getMsgToSignForVote(b.Height, b.Hash) + sig, err := fp.em.SignEOTS(fp.btcPk.MustMarshal(), fp.GetChainID(), msgToSign, b.Height, fp.passphrase) + if err != nil { + return nil, fmt.Errorf("failed to sign EOTS: %w", err) + } + + return bbntypes.NewSchnorrEOTSSigFromModNScalar(sig), nil +} diff --git a/finality-provider/service/fastsync.go b/finality-provider/service/fastsync.go index 4a033378..f77cfe60 100644 --- a/finality-provider/service/fastsync.go +++ b/finality-provider/service/fastsync.go @@ -62,6 +62,14 @@ func (fp *FinalityProviderInstance) FastSync(startHeight, endHeight uint64) (*Fa fp.metrics.IncrementFpTotalBlocksWithoutVotingPower(fp.GetBtcPkHex()) continue } + // check whether the randomness has been committed + hasRand, err := fp.hasRandomness(b) + if err != nil { + return nil, err + } + if !hasRand { + break + } // all good, add the block for catching up catchUpBlocks = append(catchUpBlocks, b) } diff --git a/finality-provider/service/fastsync_test.go b/finality-provider/service/fastsync_test.go index 52c0ebbb..cf7e0164 100644 --- a/finality-provider/service/fastsync_test.go +++ b/finality-provider/service/fastsync_test.go @@ -4,6 +4,8 @@ import ( "math/rand" "testing" + "github.com/babylonchain/babylon/testutil/datagen" + ftypes "github.com/babylonchain/babylon/x/finality/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -11,28 +13,40 @@ import ( "github.com/babylonchain/finality-provider/types" ) -// FuzzFastSync tests a case where we have voting power when the finality -// provider enters fast-sync. -// It is expected that the finality provider could catch up to the current +// FuzzFastSync_SufficientRandomness tests a case where we have sufficient +// randomness and voting power when the finality provider enters fast-sync +// it is expected that the finality provider could catch up to the current // height through fast-sync -func FuzzFastSync(f *testing.F) { +func FuzzFastSync_SufficientRandomness(f *testing.F) { testutil.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - randomRegiteredEpoch := uint64(r.Int63n(10) + 1) randomStartingHeight := uint64(r.Int63n(100) + 1) finalizedHeight := randomStartingHeight + uint64(r.Int63n(10)+2) currentHeight := finalizedHeight + uint64(r.Int63n(10)+1) mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight) - // mock finalised BTC timestamped - mockClientController.EXPECT().QueryLastFinalizedEpoch().Return(randomRegiteredEpoch, nil).AnyTimes() - _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, randomStartingHeight, randomRegiteredEpoch) + mockClientController.EXPECT().QueryLatestFinalizedBlocks(uint64(1)).Return(nil, nil).AnyTimes() + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, randomStartingHeight) defer cleanUp() - // mock voting power + // commit pub rand + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).Times(1) + mockClientController.EXPECT().CommitPubRandList(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + _, err := fpIns.CommitPubRand(randomStartingHeight) + require.NoError(t, err) + mockClientController.EXPECT().QueryFinalityProviderVotingPower(fpIns.GetBtcPk(), gomock.Any()). Return(uint64(1), nil).AnyTimes() + // the last committed height is higher than the current height + // to make sure the randomness is sufficient + lastCommittedHeight := randomStartingHeight + testutil.TestPubRandNum + lastCommittedPubRandMap := make(map[uint64]*ftypes.PubRandCommitResponse) + lastCommittedPubRandMap[lastCommittedHeight] = &ftypes.PubRandCommitResponse{ + NumPubRand: 1000, + Commitment: datagen.GenRandomByteArray(r, 32), + } + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(lastCommittedPubRandMap, nil).AnyTimes() catchUpBlocks := testutil.GenBlocks(r, finalizedHeight+1, currentHeight) expectedTxHash := testutil.GenRandomHexStr(r, 32) @@ -40,7 +54,7 @@ func FuzzFastSync(f *testing.F) { mockClientController.EXPECT().QueryLatestFinalizedBlocks(uint64(1)).Return([]*types.BlockInfo{finalizedBlock}, nil).AnyTimes() mockClientController.EXPECT().QueryBlocks(finalizedHeight+1, currentHeight, uint64(10)). Return(catchUpBlocks, nil) - mockClientController.EXPECT().SubmitBatchFinalitySigs(fpIns.GetBtcPk(), catchUpBlocks, gomock.Any()). + mockClientController.EXPECT().SubmitBatchFinalitySigs(fpIns.GetBtcPk(), catchUpBlocks, gomock.Any(), gomock.Any(), gomock.Any()). Return(&types.TxResponse{TxHash: expectedTxHash}, nil).AnyTimes() result, err := fpIns.FastSync(finalizedHeight+1, currentHeight) require.NoError(t, err) @@ -50,3 +64,54 @@ func FuzzFastSync(f *testing.F) { require.Equal(t, currentHeight, fpIns.GetLastProcessedHeight()) }) } + +// FuzzFastSync_NoRandomness tests a case where we have insufficient +// randomness but with voting power when the finality provider enters fast-sync +// it is expected that the finality provider could catch up to the last +// committed height +func FuzzFastSync_NoRandomness(f *testing.F) { + testutil.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + randomStartingHeight := uint64(r.Int63n(100) + 100) + finalizedHeight := randomStartingHeight + uint64(r.Int63n(10)+2) + currentHeight := finalizedHeight + uint64(r.Int63n(10)+1) + mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight) + mockClientController.EXPECT().QueryLatestFinalizedBlocks(uint64(1)).Return(nil, nil).AnyTimes() + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, randomStartingHeight) + defer cleanUp() + + // commit pub rand + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).Times(1) + mockClientController.EXPECT().CommitPubRandList(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + _, err := fpIns.CommitPubRand(randomStartingHeight) + require.NoError(t, err) + + mockClientController.EXPECT().QueryFinalityProviderVotingPower(fpIns.GetBtcPk(), gomock.Any()). + Return(uint64(1), nil).AnyTimes() + // the last height with pub rand is a random value inside [finalizedHeight+1, currentHeight] + lastHeightWithPubRand := uint64(rand.Intn(int(currentHeight)-int(finalizedHeight))) + finalizedHeight + 1 + lastCommittedPubRandMap := make(map[uint64]*ftypes.PubRandCommitResponse) + lastCommittedPubRandMap[lastHeightWithPubRand-10] = &ftypes.PubRandCommitResponse{ + NumPubRand: 10 + 1, + Commitment: datagen.GenRandomByteArray(r, 32), + } + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(lastCommittedPubRandMap, nil).AnyTimes() + + catchUpBlocks := testutil.GenBlocks(r, finalizedHeight+1, currentHeight) + expectedTxHash := testutil.GenRandomHexStr(r, 32) + finalizedBlock := &types.BlockInfo{Height: finalizedHeight, Hash: testutil.GenRandomByteArray(r, 32)} + mockClientController.EXPECT().QueryLatestFinalizedBlocks(uint64(1)).Return([]*types.BlockInfo{finalizedBlock}, nil).AnyTimes() + mockClientController.EXPECT().QueryBlocks(finalizedHeight+1, currentHeight, uint64(10)). + Return(catchUpBlocks, nil) + mockClientController.EXPECT().SubmitBatchFinalitySigs(fpIns.GetBtcPk(), catchUpBlocks[:lastHeightWithPubRand-finalizedHeight], gomock.Any(), gomock.Any(), gomock.Any()). + Return(&types.TxResponse{TxHash: expectedTxHash}, nil).AnyTimes() + result, err := fpIns.FastSync(finalizedHeight+1, currentHeight) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, expectedTxHash, result.Responses[0].TxHash) + require.Equal(t, lastHeightWithPubRand, fpIns.GetLastVotedHeight()) + require.Equal(t, lastHeightWithPubRand, fpIns.GetLastProcessedHeight()) + }) +} diff --git a/finality-provider/service/fp_instance.go b/finality-provider/service/fp_instance.go index b5f80695..8bff0433 100644 --- a/finality-provider/service/fp_instance.go +++ b/finality-provider/service/fp_instance.go @@ -30,8 +30,9 @@ type FinalityProviderInstance struct { chainPk *secp256k1.PubKey btcPk *bbntypes.BIP340PubKey - state *fpState - cfg *fpcfg.Config + fpState *fpState + pubRandState *pubRandState + cfg *fpcfg.Config logger *zap.Logger em eotsmanager.EOTSManager @@ -59,6 +60,7 @@ func NewFinalityProviderInstance( fpPk *bbntypes.BIP340PubKey, cfg *fpcfg.Config, s *store.FinalityProviderStore, + prStore *store.PubRandProofStore, cc clientcontroller.ClientController, em eotsmanager.EOTSManager, metrics *metrics.FpMetrics, @@ -73,25 +75,14 @@ func NewFinalityProviderInstance( // ensure the finality-provider has been registered if sfp.Status < proto.FinalityProviderStatus_REGISTERED { - return nil, fmt.Errorf("the finality provider %s has not been registered", sfp.KeyName) - } - - registeredEpoch := sfp.RegisteredEpoch - lastFinalizedEpoch, err := cc.QueryLastFinalizedEpoch() - if err != nil { - return nil, fmt.Errorf("failed to get the last finalized epoch: %v", err) - } - if lastFinalizedEpoch < registeredEpoch { - return nil, fmt.Errorf("the registered epoch %d of the finality provider %s is not BTC timestamped yet (last finalized epoch: %d)", registeredEpoch, sfp.KeyName, lastFinalizedEpoch) + return nil, fmt.Errorf("the finality-provider %s has not been registered", sfp.KeyName) } return &FinalityProviderInstance{ - btcPk: bbntypes.NewBIP340PubKeyFromBTCPK(sfp.BtcPk), - chainPk: sfp.ChainPk, - state: &fpState{ - fp: sfp, - s: s, - }, + btcPk: bbntypes.NewBIP340PubKeyFromBTCPK(sfp.BtcPk), + chainPk: sfp.ChainPk, + fpState: NewFpState(sfp, s), + pubRandState: NewPubRandState(prStore), cfg: cfg, logger: logger, isStarted: atomic.NewBool(false), @@ -135,6 +126,8 @@ func (fp *FinalityProviderInstance) Start() error { fp.wg.Add(1) go fp.finalitySigSubmissionLoop() fp.wg.Add(1) + go fp.randomnessCommitmentLoop() + fp.wg.Add(1) go fp.checkLaggingLoop() return nil @@ -213,6 +206,13 @@ func (fp *FinalityProviderInstance) finalitySigSubmissionLoop() { fp.metrics.IncrementFpTotalBlocksWithoutVotingPower(fp.GetBtcPkHex()) continue } + // check whether the randomness has been committed + // we should stall here until we have randomness committed at this + // height, otherwise, we might miss blocks + if err := fp.retryCheckRandomnessUntilBlockFinalized(b); err != nil { + fp.reportCriticalErr(err) + break + } // use the copy of the block to avoid the impact to other receivers nextBlock := *b @@ -276,6 +276,42 @@ func (fp *FinalityProviderInstance) finalitySigSubmissionLoop() { } } +func (fp *FinalityProviderInstance) randomnessCommitmentLoop() { + defer fp.wg.Done() + + commitRandTicker := time.NewTicker(fp.cfg.RandomnessCommitInterval) + defer commitRandTicker.Stop() + + for { + select { + case <-commitRandTicker.C: + tipBlock, err := fp.getLatestBlockWithRetry() + if err != nil { + fp.reportCriticalErr(err) + continue + } + txRes, err := fp.retryCommitPubRandUntilBlockFinalized(tipBlock) + if err != nil { + fp.metrics.IncrementFpTotalFailedRandomness(fp.GetBtcPkHex()) + fp.reportCriticalErr(err) + continue + } + // txRes could be nil if no need to commit more randomness + if txRes != nil { + fp.logger.Info( + "successfully committed public randomness to the consumer chain", + zap.String("pk", fp.GetBtcPkHex()), + zap.String("tx_hash", txRes.TxHash), + ) + } + + case <-fp.quit: + fp.logger.Info("the randomness commitment loop is closing") + return + } + } +} + func (fp *FinalityProviderInstance) checkLaggingLoop() { defer fp.wg.Done() @@ -370,7 +406,6 @@ func (fp *FinalityProviderInstance) hasProcessed(b *types.BlockInfo) bool { return false } -// hasVotingPower checks whether the finality provider has voting power for the given block func (fp *FinalityProviderInstance) hasVotingPower(b *types.BlockInfo) (bool, error) { power, err := fp.GetVotingPowerWithRetry(b.Height) if err != nil { @@ -378,7 +413,7 @@ func (fp *FinalityProviderInstance) hasVotingPower(b *types.BlockInfo) (bool, er } if power == 0 { fp.logger.Debug( - "the finality provider does not have voting power", + "the finality-provider does not have voting power", zap.String("pk", fp.GetBtcPkHex()), zap.Uint64("block_height", b.Height), ) @@ -389,6 +424,24 @@ func (fp *FinalityProviderInstance) hasVotingPower(b *types.BlockInfo) (bool, er return true, nil } +func (fp *FinalityProviderInstance) hasRandomness(b *types.BlockInfo) (bool, error) { + lastCommittedHeight, err := fp.GetLastCommittedHeight() + if err != nil { + return false, err + } + if b.Height > lastCommittedHeight { + fp.logger.Debug( + "the finality provider has not committed public randomness for the height", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint64("block_height", b.Height), + zap.Uint64("last_committed_height", lastCommittedHeight), + ) + return false, nil + } + + return true, nil +} + func (fp *FinalityProviderInstance) reportCriticalErr(err error) { fp.criticalErrChan <- &CriticalError{ err: err, @@ -401,6 +454,65 @@ func (fp *FinalityProviderInstance) checkLagging(currentBlock *types.BlockInfo) return currentBlock.Height >= fp.GetLastProcessedHeight()+fp.cfg.FastSyncGap } +// retryQueryingRandomnessUntilBlockFinalized periodically checks whether +// the randomness has been committed to the target block until the block is +// finalized +// error will be returned if maximum retries have been reached or the query to +// the consumer chain fails +func (fp *FinalityProviderInstance) retryCheckRandomnessUntilBlockFinalized(targetBlock *types.BlockInfo) error { + var failedCycles uint32 + + // we break the for loop if the block is finalized or the randomness is successfully committed + // error will be returned if maximum retries have been reached or the query to the consumer chain fails + for { + fp.logger.Debug( + "checking randomness", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint64("target_block_height", targetBlock.Height), + ) + hasRand, err := fp.hasRandomness(targetBlock) + if err != nil { + fp.logger.Debug( + "failed to check last committed randomness", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint32("current_failures", failedCycles), + zap.Uint64("target_block_height", targetBlock.Height), + zap.Error(err), + ) + + failedCycles += 1 + if failedCycles > uint32(fp.cfg.MaxSubmissionRetries) { + return fmt.Errorf("reached max failed cycles with err: %w", err) + } + } else if hasRand { + // the randomness has been successfully committed + return nil + } + select { + case <-time.After(fp.cfg.SubmissionRetryInterval): + // periodically query the index block to be later checked whether it is Finalized + finalized, err := fp.checkBlockFinalization(targetBlock.Height) + if err != nil { + return fmt.Errorf("failed to query block finalization at height %v: %w", targetBlock.Height, err) + } + if finalized { + fp.logger.Debug( + "the block is already finalized, skip checking randomness", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint64("target_height", targetBlock.Height), + ) + // TODO: returning nil here is to safely break the loop + // the error still exists + return nil + } + + case <-fp.quit: + fp.logger.Debug("the finality-provider instance is closing", zap.String("pk", fp.GetBtcPkHex())) + return nil + } + } +} + // retrySubmitFinalitySignatureUntilBlockFinalized periodically tries to submit finality signature until success or the block is finalized // error will be returned if maximum retries have been reached or the query to the consumer chain fails func (fp *FinalityProviderInstance) retrySubmitFinalitySignatureUntilBlockFinalized(targetBlock *types.BlockInfo) (*types.TxResponse, error) { @@ -471,15 +583,153 @@ func (fp *FinalityProviderInstance) checkBlockFinalization(height uint64) (bool, return b.Finalized, nil } +// retryCommitPubRandUntilBlockFinalized periodically tries to commit public rand until success or the block is finalized +// error will be returned if maximum retries have been reached or the query to the consumer chain fails +func (fp *FinalityProviderInstance) retryCommitPubRandUntilBlockFinalized(targetBlock *types.BlockInfo) (*types.TxResponse, error) { + var failedCycles uint32 + + // we break the for loop if the block is finalized or the public rand is successfully committed + // error will be returned if maximum retries have been reached or the query to the consumer chain fails + for { + // error will be returned if max retries have been reached + // TODO: CommitPubRand also includes saving all inclusion proofs of public randomness + // this part should not be retried here. We need to separate the function into + // 1) determining the starting height to commit, 2) generating pub rand and inclusion + // proofs, and 3) committing public randomness. + // TODO: make 3) a part of `select` statement. The function terminates upon either the block + // is finalised or the pub rand is committed successfully + res, err := fp.CommitPubRand(targetBlock.Height) + if err != nil { + if clientcontroller.IsUnrecoverable(err) { + return nil, err + } + fp.logger.Debug( + "failed to commit public randomness to the consumer chain", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint32("current_failures", failedCycles), + zap.Uint64("target_block_height", targetBlock.Height), + zap.Error(err), + ) + + failedCycles += 1 + if failedCycles > uint32(fp.cfg.MaxSubmissionRetries) { + return nil, fmt.Errorf("reached max failed cycles with err: %w", err) + } + } else { + // the public randomness has been successfully submitted + return res, nil + } + select { + case <-time.After(fp.cfg.SubmissionRetryInterval): + // periodically query the index block to be later checked whether it is Finalized + finalized, err := fp.checkBlockFinalization(targetBlock.Height) + if err != nil { + return nil, fmt.Errorf("failed to query block finalization at height %v: %w", targetBlock.Height, err) + } + if finalized { + fp.logger.Debug( + "the block is already finalized, skip submission", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint64("target_height", targetBlock.Height), + ) + // TODO: returning nil here is to safely break the loop + // the error still exists + return nil, nil + } + + case <-fp.quit: + fp.logger.Debug("the finality-provider instance is closing", zap.String("pk", fp.GetBtcPkHex())) + return nil, nil + } + } +} + +// CommitPubRand generates a list of Schnorr rand pairs, +// commits the public randomness for the managed finality providers, +// and save the randomness pair to DB +func (fp *FinalityProviderInstance) CommitPubRand(tipHeight uint64) (*types.TxResponse, error) { + lastCommittedHeight, err := fp.GetLastCommittedHeight() + if err != nil { + return nil, err + } + + var startHeight uint64 + if lastCommittedHeight == uint64(0) { + // the finality-provider has never submitted public rand before + startHeight = tipHeight + 1 + } else if lastCommittedHeight < fp.cfg.MinRandHeightGap+tipHeight { + // (should not use subtraction because they are in the type of uint64) + // we are running out of the randomness + startHeight = lastCommittedHeight + 1 + } else { + fp.logger.Debug( + "the finality-provider has sufficient public randomness, skip committing more", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint64("block_height", tipHeight), + zap.Uint64("last_committed_height", lastCommittedHeight), + ) + return nil, nil + } + + // generate a list of Schnorr randomness pairs + // NOTE: currently, calling this will create and save a list of randomness + // in case of failure, randomness that has been created will be overwritten + // for safety reason as the same randomness must not be used twice + pubRandList, err := fp.getPubRandList(startHeight, fp.cfg.NumPubRand) + if err != nil { + return nil, fmt.Errorf("failed to generate randomness: %w", err) + } + numPubRand := uint64(len(pubRandList)) + + // generate commitment and proof for each public randomness + commitment, proofList := types.GetPubRandCommitAndProofs(pubRandList) + + // store them to database + if err := fp.pubRandState.AddPubRandProofList(pubRandList, proofList); err != nil { + return nil, fmt.Errorf("failed to save public randomness to DB: %w", err) + } + + // sign the commitment + schnorrSig, err := fp.signPubRandCommit(startHeight, numPubRand, commitment) + if err != nil { + return nil, fmt.Errorf("failed to sign the Schnorr signature: %w", err) + } + + res, err := fp.cc.CommitPubRandList(fp.GetBtcPk(), startHeight, numPubRand, commitment, schnorrSig) + if err != nil { + return nil, fmt.Errorf("failed to commit public randomness to the consumer chain: %w", err) + } + + // Update metrics + fp.metrics.RecordFpRandomnessTime(fp.GetBtcPkHex()) + fp.metrics.RecordFpLastCommittedRandomnessHeight(fp.GetBtcPkHex(), lastCommittedHeight) + fp.metrics.AddToFpTotalCommittedRandomness(fp.GetBtcPkHex(), float64(len(pubRandList))) + + return res, nil +} + // SubmitFinalitySignature builds and sends a finality signature over the given block to the consumer chain func (fp *FinalityProviderInstance) SubmitFinalitySignature(b *types.BlockInfo) (*types.TxResponse, error) { - eotsSig, err := fp.signEotsSig(b) + sig, err := fp.signFinalitySig(b) if err != nil { return nil, err } + // get public randomness at the height + prList, err := fp.getPubRandList(b.Height, 1) + if err != nil { + return nil, fmt.Errorf("failed to get public randomness list: %v", err) + } + pubRand := prList[0] + + // get inclusion proof + proofBytes, err := fp.pubRandState.GetPubRandProof(pubRand) + if err != nil { + return nil, fmt.Errorf("failed to get inclusion proof of public randomness: %v", err) + } + // send finality signature to the consumer chain - res, err := fp.cc.SubmitFinalitySig(fp.GetBtcPk(), b.Height, b.Hash, eotsSig.ToModNScalar()) + res, err := fp.cc.SubmitFinalitySig(fp.GetBtcPk(), b, pubRand, proofBytes, sig.ToModNScalar()) if err != nil { return nil, fmt.Errorf("failed to send finality signature to the consumer chain: %w", err) } @@ -501,17 +751,30 @@ func (fp *FinalityProviderInstance) SubmitBatchFinalitySignatures(blocks []*type return nil, fmt.Errorf("should not submit batch finality signature with zero block") } - sigs := make([]*btcec.ModNScalar, 0, len(blocks)) + // get public randomness list + prList, err := fp.getPubRandList(blocks[0].Height, uint64(len(blocks))) + if err != nil { + return nil, fmt.Errorf("failed to get public randomness list: %v", err) + } + // get proof list + // TODO: how to recover upon having an error in GetPubRandProofList? + proofBytesList, err := fp.pubRandState.GetPubRandProofList(prList) + if err != nil { + return nil, fmt.Errorf("failed to get public randomness inclusion proof list: %v", err) + } + + // sign blocks + sigList := make([]*btcec.ModNScalar, 0, len(blocks)) for _, b := range blocks { - eotsSig, err := fp.signEotsSig(b) + eotsSig, err := fp.signFinalitySig(b) if err != nil { return nil, err } - sigs = append(sigs, eotsSig.ToModNScalar()) + sigList = append(sigList, eotsSig.ToModNScalar()) } // send finality signature to the consumer chain - res, err := fp.cc.SubmitBatchFinalitySigs(fp.GetBtcPk(), blocks, sigs) + res, err := fp.cc.SubmitBatchFinalitySigs(fp.GetBtcPk(), blocks, prList, proofBytesList, sigList) if err != nil { return nil, fmt.Errorf("failed to send a batch of finality signatures to the consumer chain: %w", err) } @@ -523,33 +786,41 @@ func (fp *FinalityProviderInstance) SubmitBatchFinalitySignatures(blocks []*type return res, nil } -func (fp *FinalityProviderInstance) signEotsSig(b *types.BlockInfo) (*bbntypes.SchnorrEOTSSig, error) { - // build proper finality signature request - msg := &ftypes.MsgAddFinalitySig{ - FpBtcPk: fp.btcPk, - BlockHeight: b.Height, - BlockAppHash: b.Hash, +// TestSubmitFinalitySignatureAndExtractPrivKey is exposed for presentation/testing purpose to allow manual sending finality signature +// this API is the same as SubmitFinalitySignature except that we don't constraint the voting height and update status +// Note: this should not be used in the submission loop +func (fp *FinalityProviderInstance) TestSubmitFinalitySignatureAndExtractPrivKey(b *types.BlockInfo) (*types.TxResponse, *btcec.PrivateKey, error) { + // check last committed height + lastCommittedHeight, err := fp.GetLastCommittedHeight() + if err != nil { + return nil, nil, err } - msgToSign := msg.MsgToSign() - sig, err := fp.em.SignEOTS(fp.btcPk.MustMarshal(), fp.GetChainID(), msgToSign, b.Height, fp.passphrase) + if lastCommittedHeight < b.Height { + return nil, nil, fmt.Errorf("the finality-provider's last committed height %v is lower than the current block height %v", + lastCommittedHeight, b.Height) + } + + // get public randomness + prList, err := fp.getPubRandList(b.Height, 1) if err != nil { - return nil, fmt.Errorf("failed to sign EOTS: %w", err) + return nil, nil, fmt.Errorf("failed to get public randomness list: %v", err) } + pubRand := prList[0] - return bbntypes.NewSchnorrEOTSSigFromModNScalar(sig), nil -} + // get proof + proofBytes, err := fp.pubRandState.GetPubRandProof(pubRand) + if err != nil { + return nil, nil, fmt.Errorf("failed to get public randomness inclusion proof: %v", err) + } -// TestSubmitFinalitySignatureAndExtractPrivKey is exposed for presentation/testing purpose to allow manual sending finality signature -// this API is the same as SubmitFinalitySignature except that we don't constraint the voting height and update status -// Note: this should not be used in the submission loop -func (fp *FinalityProviderInstance) TestSubmitFinalitySignatureAndExtractPrivKey(b *types.BlockInfo) (*types.TxResponse, *btcec.PrivateKey, error) { - eotsSig, err := fp.signEotsSig(b) + // sign block + eotsSig, err := fp.signFinalitySig(b) if err != nil { return nil, nil, err } // send finality signature to the consumer chain - res, err := fp.cc.SubmitFinalitySig(fp.GetBtcPk(), b.Height, b.Hash, eotsSig.ToModNScalar()) + res, err := fp.cc.SubmitFinalitySig(fp.GetBtcPk(), b, pubRand, proofBytes, eotsSig.ToModNScalar()) if err != nil { return nil, nil, fmt.Errorf("failed to send finality signature to the consumer chain: %w", err) } @@ -607,6 +878,50 @@ func (fp *FinalityProviderInstance) getPollerStartingHeight() (uint64, error) { return initialBlockToGet, nil } +func (fp *FinalityProviderInstance) GetLastCommittedHeight() (uint64, error) { + pubRandCommitMap, err := fp.lastCommittedPublicRandWithRetry(1) + if err != nil { + return 0, err + } + + // no committed randomness yet + if len(pubRandCommitMap) == 0 { + return 0, nil + } + + if len(pubRandCommitMap) > 1 { + return 0, fmt.Errorf("got more than one last committed public randomness") + } + var lastCommittedHeight uint64 + for startHeight, resp := range pubRandCommitMap { + lastCommittedHeight = startHeight + resp.NumPubRand - 1 + } + + return lastCommittedHeight, nil +} + +func (fp *FinalityProviderInstance) lastCommittedPublicRandWithRetry(count uint64) (map[uint64]*ftypes.PubRandCommitResponse, error) { + var response map[uint64]*ftypes.PubRandCommitResponse + if err := retry.Do(func() error { + resp, err := fp.cc.QueryLastCommittedPublicRand(fp.GetBtcPk(), count) + if err != nil { + return err + } + response = resp + return nil + }, RtyAtt, RtyDel, RtyErr, retry.OnRetry(func(n uint, err error) { + fp.logger.Debug( + "failed to query babylon for the last committed public randomness", + zap.Uint("attempt", n+1), + zap.Uint("max_attempts", RtyAttNum), + zap.Error(err), + ) + })); err != nil { + return nil, err + } + return response, nil +} + func (fp *FinalityProviderInstance) latestFinalizedBlocksWithRetry(count uint64) ([]*types.BlockInfo, error) { var response []*types.BlockInfo if err := retry.Do(func() error { diff --git a/finality-provider/service/fp_instance_test.go b/finality-provider/service/fp_instance_test.go index 9cc2c696..99e4b1fa 100644 --- a/finality-provider/service/fp_instance_test.go +++ b/finality-provider/service/fp_instance_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap" + "github.com/babylonchain/babylon/testutil/datagen" + ftypes "github.com/babylonchain/babylon/x/finality/types" "github.com/babylonchain/finality-provider/clientcontroller" "github.com/babylonchain/finality-provider/eotsmanager" eotscfg "github.com/babylonchain/finality-provider/eotsmanager/config" @@ -21,23 +23,59 @@ import ( "github.com/babylonchain/finality-provider/types" ) +func FuzzCommitPubRandList(f *testing.F) { + testutil.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + randomStartingHeight := uint64(r.Int63n(100) + 1) + currentHeight := randomStartingHeight + uint64(r.Int63n(10)+2) + startingBlock := &types.BlockInfo{Height: randomStartingHeight, Hash: testutil.GenRandomByteArray(r, 32)} + mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight) + mockClientController.EXPECT().QueryFinalityProviderVotingPower(gomock.Any(), gomock.Any()). + Return(uint64(0), nil).AnyTimes() + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, randomStartingHeight) + defer cleanUp() + + expectedTxHash := testutil.GenRandomHexStr(r, 32) + mockClientController.EXPECT(). + CommitPubRandList(fpIns.GetBtcPk(), startingBlock.Height+1, gomock.Any(), gomock.Any(), gomock.Any()). + Return(&types.TxResponse{TxHash: expectedTxHash}, nil).AnyTimes() + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).AnyTimes() + res, err := fpIns.CommitPubRand(startingBlock.Height) + require.NoError(t, err) + require.Equal(t, expectedTxHash, res.TxHash) + }) +} + func FuzzSubmitFinalitySig(f *testing.F) { testutil.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - randomRegiteredEpoch := uint64(r.Int63n(10) + 1) randomStartingHeight := uint64(r.Int63n(100) + 1) currentHeight := randomStartingHeight + uint64(r.Int63n(10)+1) startingBlock := &types.BlockInfo{Height: randomStartingHeight, Hash: testutil.GenRandomByteArray(r, 32)} mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight) - // mock finalised BTC timestamped - mockClientController.EXPECT().QueryLastFinalizedEpoch().Return(randomRegiteredEpoch, nil).AnyTimes() - - _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, randomStartingHeight, randomRegiteredEpoch) + mockClientController.EXPECT().QueryLatestFinalizedBlocks(gomock.Any()).Return(nil, nil).AnyTimes() + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, randomStartingHeight) defer cleanUp() - // mock voting power + // commit pub rand + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).Times(1) + mockClientController.EXPECT().CommitPubRandList(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + _, err := fpIns.CommitPubRand(startingBlock.Height) + require.NoError(t, err) + + // mock committed pub rand + lastCommittedHeight := randomStartingHeight + 25 + lastCommittedPubRandMap := make(map[uint64]*ftypes.PubRandCommitResponse) + lastCommittedPubRandMap[lastCommittedHeight] = &ftypes.PubRandCommitResponse{ + NumPubRand: 1000, + Commitment: datagen.GenRandomByteArray(r, 32), + } + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(lastCommittedPubRandMap, nil).AnyTimes() + // mock voting power and commit pub rand mockClientController.EXPECT().QueryFinalityProviderVotingPower(fpIns.GetBtcPk(), gomock.Any()). Return(uint64(1), nil).AnyTimes() @@ -48,7 +86,7 @@ func FuzzSubmitFinalitySig(f *testing.F) { } expectedTxHash := testutil.GenRandomHexStr(r, 32) mockClientController.EXPECT(). - SubmitFinalitySig(fpIns.GetBtcPk(), nextBlock.Height, nextBlock.Hash, gomock.Any()). + SubmitFinalitySig(fpIns.GetBtcPk(), nextBlock, gomock.Any(), gomock.Any(), gomock.Any()). Return(&types.TxResponse{TxHash: expectedTxHash}, nil).AnyTimes() providerRes, err := fpIns.SubmitFinalitySignature(nextBlock) require.NoError(t, err) @@ -60,7 +98,7 @@ func FuzzSubmitFinalitySig(f *testing.F) { }) } -func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc clientcontroller.ClientController, startingHeight uint64, registeredEpoch uint64) (*service.FinalityProviderApp, *service.FinalityProviderInstance, func()) { +func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc clientcontroller.ClientController, startingHeight uint64) (*service.FinalityProviderApp, *service.FinalityProviderInstance, func()) { logger := zap.NewNop() // create an EOTS manager eotsHomeDir := filepath.Join(t.TempDir(), "eots-home") @@ -76,9 +114,9 @@ func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc cli fpCfg.NumPubRand = testutil.TestPubRandNum fpCfg.PollerConfig.AutoChainScanningMode = false fpCfg.PollerConfig.StaticChainScanningStartHeight = startingHeight - fpdb, err := fpCfg.DatabaseConfig.GetDbBackend() + db, err := fpCfg.DatabaseConfig.GetDbBackend() require.NoError(t, err) - app, err := service.NewFinalityProviderApp(&fpCfg, cc, em, fpdb, logger) + app, err := service.NewFinalityProviderApp(&fpCfg, cc, em, db, logger) require.NoError(t, err) err = app.Start() require.NoError(t, err) @@ -87,15 +125,13 @@ func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc cli // create registered finality-provider fp := testutil.GenStoredFinalityProvider(r, t, app, passphrase, hdPath) - err = app.GetFinalityProviderStore().SetFpStatus(fp.BtcPk, proto.FinalityProviderStatus_REGISTERED) + pubRandProofStore := app.GetPubRandProofStore() + fpStore := app.GetFinalityProviderStore() + err = fpStore.SetFpStatus(fp.BtcPk, proto.FinalityProviderStatus_REGISTERED) require.NoError(t, err) - - err = app.GetFinalityProviderStore().SetFpRegisteredEpoch(fp.BtcPk, registeredEpoch) - require.NoError(t, err) - // TODO: use mock metrics m := metrics.NewFpMetrics() - fpIns, err := service.NewFinalityProviderInstance(fp.GetBIP340BTCPK(), &fpCfg, app.GetFinalityProviderStore(), cc, em, m, passphrase, make(chan *service.CriticalError), logger) + fpIns, err := service.NewFinalityProviderInstance(fp.GetBIP340BTCPK(), &fpCfg, fpStore, pubRandProofStore, cc, em, m, passphrase, make(chan *service.CriticalError), logger) require.NoError(t, err) cleanUp := func() { @@ -103,7 +139,7 @@ func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc cli require.NoError(t, err) err = eotsdb.Close() require.NoError(t, err) - err = fpdb.Close() + err = db.Close() require.NoError(t, err) err = os.RemoveAll(eotsHomeDir) require.NoError(t, err) diff --git a/finality-provider/service/fp_manager.go b/finality-provider/service/fp_manager.go index 03fef45c..2625a029 100644 --- a/finality-provider/service/fp_manager.go +++ b/finality-provider/service/fp_manager.go @@ -42,11 +42,12 @@ type FinalityProviderManager struct { fpis map[string]*FinalityProviderInstance // needed for initiating finality-provider instances - fps *store.FinalityProviderStore - config *fpcfg.Config - cc clientcontroller.ClientController - em eotsmanager.EOTSManager - logger *zap.Logger + fps *store.FinalityProviderStore + pubRandStore *store.PubRandProofStore + config *fpcfg.Config + cc clientcontroller.ClientController + em eotsmanager.EOTSManager + logger *zap.Logger metrics *metrics.FpMetrics @@ -57,6 +58,7 @@ type FinalityProviderManager struct { func NewFinalityProviderManager( fps *store.FinalityProviderStore, + pubRandStore *store.PubRandProofStore, config *fpcfg.Config, cc clientcontroller.ClientController, em eotsmanager.EOTSManager, @@ -68,6 +70,7 @@ func NewFinalityProviderManager( criticalErrChan: make(chan *CriticalError), isStarted: atomic.NewBool(false), fps: fps, + pubRandStore: pubRandStore, config: config, cc: cc, em: em, @@ -389,7 +392,7 @@ func (fpm *FinalityProviderManager) addFinalityProviderInstance( return fmt.Errorf("finality-provider instance already exists") } - fpIns, err := NewFinalityProviderInstance(pk, fpm.config, fpm.fps, fpm.cc, fpm.em, fpm.metrics, passphrase, fpm.criticalErrChan, fpm.logger) + fpIns, err := NewFinalityProviderInstance(pk, fpm.config, fpm.fps, fpm.pubRandStore, fpm.cc, fpm.em, fpm.metrics, passphrase, fpm.criticalErrChan, fpm.logger) if err != nil { return fmt.Errorf("failed to create finality-provider %s instance: %w", pkHex, err) } diff --git a/finality-provider/service/fp_manager_test.go b/finality-provider/service/fp_manager_test.go index 486fcb73..f2641b8a 100644 --- a/finality-provider/service/fp_manager_test.go +++ b/finality-provider/service/fp_manager_test.go @@ -10,6 +10,11 @@ import ( "github.com/babylonchain/babylon/testutil/datagen" bbntypes "github.com/babylonchain/babylon/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "github.com/babylonchain/finality-provider/clientcontroller" "github.com/babylonchain/finality-provider/eotsmanager" eotscfg "github.com/babylonchain/finality-provider/eotsmanager/config" @@ -18,16 +23,11 @@ import ( "github.com/babylonchain/finality-provider/finality-provider/service" fpstore "github.com/babylonchain/finality-provider/finality-provider/store" "github.com/babylonchain/finality-provider/keyring" - fpkr "github.com/babylonchain/finality-provider/keyring" "github.com/babylonchain/finality-provider/metrics" "github.com/babylonchain/finality-provider/testutil" "github.com/babylonchain/finality-provider/testutil/mocks" "github.com/babylonchain/finality-provider/types" "github.com/babylonchain/finality-provider/util" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" - "go.uber.org/zap" ) var ( @@ -57,11 +57,11 @@ func FuzzStatusUpdate(f *testing.F) { mockClientController.EXPECT().QueryBestBlock().Return(currentBlockRes, nil).AnyTimes() mockClientController.EXPECT().QueryActivatedHeight().Return(uint64(1), nil).AnyTimes() mockClientController.EXPECT().QueryBlock(gomock.Any()).Return(currentBlockRes, nil).AnyTimes() - mockClientController.EXPECT().QueryLastFinalizedEpoch().Return(uint64(0), nil).AnyTimes() + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).AnyTimes() votingPower := uint64(r.Intn(2)) mockClientController.EXPECT().QueryFinalityProviderVotingPower(gomock.Any(), currentHeight).Return(votingPower, nil).AnyTimes() - mockClientController.EXPECT().SubmitFinalitySig(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.TxResponse{TxHash: ""}, nil).AnyTimes() + mockClientController.EXPECT().SubmitFinalitySig(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.TxResponse{TxHash: ""}, nil).AnyTimes() var slashedHeight uint64 if votingPower == 0 { mockClientController.EXPECT().QueryFinalityProviderSlashed(gomock.Any()).Return(true, nil).AnyTimes() @@ -117,13 +117,15 @@ func newFinalityProviderManagerWithRegisteredFp(t *testing.T, r *rand.Rand, cc c require.NoError(t, err) err = util.MakeDirectory(fpcfg.DataDir(fpHomeDir)) require.NoError(t, err) - fpdb, err := fpCfg.DatabaseConfig.GetDbBackend() + db, err := fpCfg.DatabaseConfig.GetDbBackend() + require.NoError(t, err) + fpStore, err := fpstore.NewFinalityProviderStore(db) require.NoError(t, err) - fpStore, err := fpstore.NewFinalityProviderStore(fpdb) + pubRandStore, err := fpstore.NewPubRandProofStore(db) require.NoError(t, err) metricsCollectors := metrics.NewFpMetrics() - vm, err := service.NewFinalityProviderManager(fpStore, &fpCfg, cc, em, metricsCollectors, logger) + vm, err := service.NewFinalityProviderManager(fpStore, pubRandStore, &fpCfg, cc, em, metricsCollectors, logger) require.NoError(t, err) // create registered finality-provider @@ -143,34 +145,26 @@ func newFinalityProviderManagerWithRegisteredFp(t *testing.T, r *rand.Rand, cc c pop, err := kc.CreatePop(fpRecord.PrivKey, passphrase) require.NoError(t, err) - _, mpr, err := fpkr.GenerateMasterRandPair(fpRecord.PrivKey.Serialize(), types.MarshalChainID(chainID)) - require.NoError(t, err) - err = fpStore.CreateFinalityProvider( bbnPk, btcPk.MustToBTCPK(), testutil.RandomDescription(r), testutil.ZeroCommissionRate(), - mpr.MarshalBase58(), keyName, chainID, pop.BabylonSig, pop.BtcSig, ) require.NoError(t, err) - err = fpStore.SetFpStatus(btcPk.MustToBTCPK(), proto.FinalityProviderStatus_REGISTERED) require.NoError(t, err) - err = fpStore.SetFpRegisteredEpoch(btcPk.MustToBTCPK(), 0) - require.NoError(t, err) - cleanUp := func() { err = vm.Stop() require.NoError(t, err) err = eotsdb.Close() require.NoError(t, err) - err = fpdb.Close() + err = db.Close() require.NoError(t, err) err = os.RemoveAll(eotsHomeDir) require.NoError(t, err) diff --git a/finality-provider/service/types.go b/finality-provider/service/fp_store_adapter.go similarity index 77% rename from finality-provider/service/types.go rename to finality-provider/service/fp_store_adapter.go index 389de729..b370b7b8 100644 --- a/finality-provider/service/types.go +++ b/finality-provider/service/fp_store_adapter.go @@ -13,7 +13,6 @@ import ( "github.com/babylonchain/finality-provider/finality-provider/proto" "github.com/babylonchain/finality-provider/finality-provider/store" - "github.com/babylonchain/finality-provider/types" ) type createFinalityProviderResponse struct { @@ -38,7 +37,6 @@ type registerFinalityProviderRequest struct { pop *btcstakingtypes.ProofOfPossession description *stakingtypes.Description commission *sdkmath.LegacyDec - masterPubRand string errResponse chan error successResponse chan *RegisterFinalityProviderResponse } @@ -47,15 +45,13 @@ type finalityProviderRegisteredEvent struct { bbnPubKey *secp256k1.PubKey btcPubKey *bbntypes.BIP340PubKey txHash string - registeredEpoch uint64 successResponse chan *RegisterFinalityProviderResponse } type RegisterFinalityProviderResponse struct { - bbnPubKey *secp256k1.PubKey - btcPubKey *bbntypes.BIP340PubKey - TxHash string - RegisteredEpoch uint64 + bbnPubKey *secp256k1.PubKey + btcPubKey *bbntypes.BIP340PubKey + TxHash string } type CreateFinalityProviderResult struct { @@ -68,6 +64,16 @@ type fpState struct { s *store.FinalityProviderStore } +func NewFpState( + fp *store.StoredFinalityProvider, + s *store.FinalityProviderStore, +) *fpState { + return &fpState{ + fp: fp, + s: s, + } +} + func (fps *fpState) getStoreFinalityProvider() *store.StoredFinalityProvider { fps.mu.Lock() defer fps.mu.Unlock() @@ -97,15 +103,15 @@ func (fps *fpState) setLastProcessedAndVotedHeight(height uint64) error { } func (fp *FinalityProviderInstance) GetStoreFinalityProvider() *store.StoredFinalityProvider { - return fp.state.getStoreFinalityProvider() + return fp.fpState.getStoreFinalityProvider() } func (fp *FinalityProviderInstance) GetBtcPkBIP340() *bbntypes.BIP340PubKey { - return fp.state.getStoreFinalityProvider().GetBIP340BTCPK() + return fp.fpState.getStoreFinalityProvider().GetBIP340BTCPK() } func (fp *FinalityProviderInstance) GetBtcPk() *btcec.PublicKey { - return fp.state.getStoreFinalityProvider().BtcPk + return fp.fpState.getStoreFinalityProvider().BtcPk } func (fp *FinalityProviderInstance) GetBtcPkHex() string { @@ -113,23 +119,23 @@ func (fp *FinalityProviderInstance) GetBtcPkHex() string { } func (fp *FinalityProviderInstance) GetStatus() proto.FinalityProviderStatus { - return fp.state.getStoreFinalityProvider().Status + return fp.fpState.getStoreFinalityProvider().Status } func (fp *FinalityProviderInstance) GetLastVotedHeight() uint64 { - return fp.state.getStoreFinalityProvider().LastVotedHeight + return fp.fpState.getStoreFinalityProvider().LastVotedHeight } func (fp *FinalityProviderInstance) GetLastProcessedHeight() uint64 { - return fp.state.getStoreFinalityProvider().LastProcessedHeight + return fp.fpState.getStoreFinalityProvider().LastProcessedHeight } func (fp *FinalityProviderInstance) GetChainID() []byte { - return types.MarshalChainID(fp.state.getStoreFinalityProvider().ChainID) + return []byte(fp.fpState.getStoreFinalityProvider().ChainID) } func (fp *FinalityProviderInstance) SetStatus(s proto.FinalityProviderStatus) error { - return fp.state.setStatus(s) + return fp.fpState.setStatus(s) } func (fp *FinalityProviderInstance) MustSetStatus(s proto.FinalityProviderStatus) { @@ -140,7 +146,7 @@ func (fp *FinalityProviderInstance) MustSetStatus(s proto.FinalityProviderStatus } func (fp *FinalityProviderInstance) SetLastProcessedHeight(height uint64) error { - return fp.state.setLastProcessedHeight(height) + return fp.fpState.setLastProcessedHeight(height) } func (fp *FinalityProviderInstance) MustSetLastProcessedHeight(height uint64) { @@ -152,7 +158,7 @@ func (fp *FinalityProviderInstance) MustSetLastProcessedHeight(height uint64) { } func (fp *FinalityProviderInstance) updateStateAfterFinalitySigSubmission(height uint64) error { - return fp.state.setLastProcessedAndVotedHeight(height) + return fp.fpState.setLastProcessedAndVotedHeight(height) } func (fp *FinalityProviderInstance) MustUpdateStateAfterFinalitySigSubmission(height uint64) { @@ -163,22 +169,3 @@ func (fp *FinalityProviderInstance) MustUpdateStateAfterFinalitySigSubmission(he fp.metrics.RecordFpLastVotedHeight(fp.GetBtcPkHex(), height) fp.metrics.RecordFpLastProcessedHeight(fp.GetBtcPkHex(), height) } - -func (fp *FinalityProviderInstance) getEOTSPrivKey() (*btcec.PrivateKey, error) { - record, err := fp.em.KeyRecord(fp.btcPk.MustMarshal(), fp.passphrase) - if err != nil { - return nil, err - } - - return record.PrivKey, nil -} - -// only used for testing purposes -func (fp *FinalityProviderInstance) BtcPrivKey() (*btcec.PrivateKey, error) { - return fp.getEOTSPrivKey() -} - -// only used for testing purposes -func (fp *FinalityProviderInstance) RegisteredEpoch() uint64 { - return fp.state.fp.RegisteredEpoch -} diff --git a/finality-provider/service/pub_rand_store_adapter.go b/finality-provider/service/pub_rand_store_adapter.go new file mode 100644 index 00000000..65e11697 --- /dev/null +++ b/finality-provider/service/pub_rand_store_adapter.go @@ -0,0 +1,30 @@ +package service + +import ( + "github.com/babylonchain/finality-provider/finality-provider/store" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/cometbft/cometbft/crypto/merkle" +) + +type pubRandState struct { + s *store.PubRandProofStore +} + +func NewPubRandState(s *store.PubRandProofStore) *pubRandState { + return &pubRandState{s: s} +} + +func (st *pubRandState) AddPubRandProofList( + pubRandList []*btcec.FieldVal, + proofList []*merkle.Proof, +) error { + return st.s.AddPubRandProofList(pubRandList, proofList) +} + +func (st *pubRandState) GetPubRandProof(pubRand *btcec.FieldVal) ([]byte, error) { + return st.s.GetPubRandProof(pubRand) +} + +func (st *pubRandState) GetPubRandProofList(pubRandList []*btcec.FieldVal) ([][]byte, error) { + return st.s.GetPubRandProofList(pubRandList) +} diff --git a/finality-provider/store/errors.go b/finality-provider/store/errors.go index 982369ab..ad31420d 100644 --- a/finality-provider/store/errors.go +++ b/finality-provider/store/errors.go @@ -11,4 +11,10 @@ var ( // ErrDuplicateFinalityProvider The finality provider we try to add already exists in db ErrDuplicateFinalityProvider = errors.New("finality provider already exists") + + // ErrCorruptedPubRandProofDb For some reason, db on disk representation have changed + ErrCorruptedPubRandProofDb = errors.New("public randomness proof db is corrupted") + + // ErrPubRandProofNotFound The finality provider we try update is not found in db + ErrPubRandProofNotFound = errors.New("public randomness proof not found") ) diff --git a/finality-provider/store/fpstore.go b/finality-provider/store/fpstore.go index df916fd5..ea0d7cca 100644 --- a/finality-provider/store/fpstore.go +++ b/finality-provider/store/fpstore.go @@ -2,7 +2,6 @@ package store import ( "fmt" - "math" sdkmath "cosmossdk.io/math" "github.com/btcsuite/btcd/btcec/v2" @@ -47,7 +46,6 @@ func (s *FinalityProviderStore) CreateFinalityProvider( btcPk *btcec.PublicKey, description *stakingtypes.Description, commission *sdkmath.LegacyDec, - masterPubRand string, keyName, chainId string, chainSig, btcSig []byte, ) error { @@ -64,11 +62,9 @@ func (s *FinalityProviderStore) CreateFinalityProvider( ChainSig: chainSig, BtcSig: btcSig, }, - RegisteredEpoch: math.MaxUint64, - MasterPubRand: masterPubRand, - KeyName: keyName, - ChainId: chainId, - Status: proto.FinalityProviderStatus_CREATED, + KeyName: keyName, + ChainId: chainId, + Status: proto.FinalityProviderStatus_CREATED, } return s.createFinalityProviderInternal(fp) @@ -117,15 +113,6 @@ func (s *FinalityProviderStore) SetFpStatus(btcPk *btcec.PublicKey, status proto return s.setFinalityProviderState(btcPk, setFpStatus) } -func (s *FinalityProviderStore) SetFpRegisteredEpoch(btcPk *btcec.PublicKey, registeredEpoch uint64) error { - setFpStatus := func(fp *proto.FinalityProvider) error { - fp.RegisteredEpoch = registeredEpoch - return nil - } - - return s.setFinalityProviderState(btcPk, setFpStatus) -} - // SetFpLastVotedHeight sets the last voted height to the stored last voted height and last processed height // only if it is larger than the stored one. This is to ensure the stored state to increase monotonically func (s *FinalityProviderStore) SetFpLastVotedHeight(btcPk *btcec.PublicKey, lastVotedHeight uint64) error { diff --git a/finality-provider/store/fpstore_test.go b/finality-provider/store/fpstore_test.go index a0935d81..ada6feb1 100644 --- a/finality-provider/store/fpstore_test.go +++ b/finality-provider/store/fpstore_test.go @@ -41,7 +41,6 @@ func FuzzFinalityProvidersStore(f *testing.F) { fp.BtcPk, fp.Description, fp.Commission, - fp.MasterPubRand, fp.KeyName, fp.ChainID, fp.Pop.ChainSig, @@ -57,7 +56,6 @@ func FuzzFinalityProvidersStore(f *testing.F) { fp.Description, fp.Commission, fp.KeyName, - fp.MasterPubRand, fp.ChainID, fp.Pop.ChainSig, fp.Pop.BtcSig, diff --git a/finality-provider/store/pub_rand.go b/finality-provider/store/pub_rand.go new file mode 100644 index 00000000..678c8f53 --- /dev/null +++ b/finality-provider/store/pub_rand.go @@ -0,0 +1,136 @@ +package store + +import ( + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/cometbft/cometbft/crypto/merkle" + "github.com/lightningnetwork/lnd/kvdb" +) + +var ( + // mapping: pub_rand -> proof + pubRandProofBucketName = []byte("pub_rand_proof") +) + +type PubRandProofStore struct { + db kvdb.Backend +} + +// NewPubRandProofStore returns a new store backed by db +func NewPubRandProofStore(db kvdb.Backend) (*PubRandProofStore, error) { + store := &PubRandProofStore{db} + if err := store.initBuckets(); err != nil { + return nil, err + } + + return store, nil +} + +func (s *PubRandProofStore) initBuckets() error { + return kvdb.Batch(s.db, func(tx kvdb.RwTx) error { + _, err := tx.CreateTopLevelBucket(pubRandProofBucketName) + return err + }) +} + +func (s *PubRandProofStore) AddPubRandProofList( + pubRandList []*btcec.FieldVal, + proofList []*merkle.Proof, +) error { + if len(pubRandList) != len(proofList) { + return fmt.Errorf("the number of public randomness is not same as the number of proofs") + } + + pubRandBytesList := [][]byte{} + proofBytesList := [][]byte{} + for i := range pubRandList { + pubRandBytes := *pubRandList[i].Bytes() + pubRandBytesList = append(pubRandBytesList, pubRandBytes[:]) + proofBytes, err := proofList[i].ToProto().Marshal() + if err != nil { + return fmt.Errorf("invalid proof: %w", err) + } + proofBytesList = append(proofBytesList, proofBytes) + } + + return kvdb.Batch(s.db, func(tx kvdb.RwTx) error { + bucket := tx.ReadWriteBucket(pubRandProofBucketName) + if bucket == nil { + return ErrCorruptedPubRandProofDb + } + + for i := range pubRandBytesList { + // skip if already committed + if bucket.Get(pubRandBytesList[i]) != nil { + continue + } + // set to DB + if err := bucket.Put(pubRandBytesList[i], proofBytesList[i]); err != nil { + return err + } + } + + return nil + }) +} + +func (s *PubRandProofStore) GetPubRandProof(pubRand *btcec.FieldVal) ([]byte, error) { + pubRandBytes := *pubRand.Bytes() + var proofBytes []byte + + err := s.db.View(func(tx kvdb.RTx) error { + bucket := tx.ReadBucket(pubRandProofBucketName) + if bucket == nil { + return ErrCorruptedPubRandProofDb + } + + proofBytes = bucket.Get(pubRandBytes[:]) + if proofBytes == nil { + return ErrPubRandProofNotFound + } + + return nil + }, func() {}) + + if err != nil { + return nil, err + } + + return proofBytes, nil +} + +func (s *PubRandProofStore) GetPubRandProofList(pubRandList []*btcec.FieldVal) ([][]byte, error) { + pubRandBytesList := [][]byte{} + for i := range pubRandList { + pubRandBytes := *pubRandList[i].Bytes() + pubRandBytesList = append(pubRandBytesList, pubRandBytes[:]) + } + + proofBytesList := [][]byte{} + + err := s.db.View(func(tx kvdb.RTx) error { + bucket := tx.ReadBucket(pubRandProofBucketName) + if bucket == nil { + return ErrCorruptedPubRandProofDb + } + + for i := range pubRandBytesList { + proofBytes := bucket.Get(pubRandBytesList[i]) + if proofBytes == nil { + return ErrPubRandProofNotFound + } + proofBytesList = append(proofBytesList, proofBytes) + } + + return nil + }, func() {}) + + if err != nil { + return nil, err + } + + return proofBytesList, nil +} + +// TODO: delete function? diff --git a/finality-provider/store/storedfp.go b/finality-provider/store/storedfp.go index 1bed2abd..2239c392 100644 --- a/finality-provider/store/storedfp.go +++ b/finality-provider/store/storedfp.go @@ -20,8 +20,6 @@ type StoredFinalityProvider struct { Description *stakingtypes.Description Commission *sdkmath.LegacyDec Pop *proto.ProofOfPossession - RegisteredEpoch uint64 - MasterPubRand string KeyName string ChainID string LastVotedHeight uint64 @@ -55,8 +53,6 @@ func protoFpToStoredFinalityProvider(fp *proto.FinalityProvider) (*StoredFinalit ChainSig: fp.Pop.ChainSig, BtcSig: fp.Pop.BtcSig, }, - RegisteredEpoch: fp.RegisteredEpoch, - MasterPubRand: fp.MasterPubRand, KeyName: fp.KeyName, ChainID: fp.ChainId, LastVotedHeight: fp.LastVotedHeight, @@ -84,9 +80,6 @@ func (sfp *StoredFinalityProvider) ToFinalityProviderInfo() *proto.FinalityProvi SecurityContact: sfp.Description.SecurityContact, Details: sfp.Description.Details, }, - Pop: sfp.Pop, - RegisteredEpoch: sfp.RegisteredEpoch, - MasterPubRand: sfp.MasterPubRand, Commission: sfp.Commission.String(), LastVotedHeight: sfp.LastVotedHeight, Status: sfp.Status.String(), diff --git a/go.mod b/go.mod index c32914f6..0227e173 100644 --- a/go.mod +++ b/go.mod @@ -8,28 +8,30 @@ require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 github.com/avast/retry-go/v4 v4.5.1 - github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b + github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 github.com/btcsuite/btcd v0.24.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcwallet/walletdb v1.4.0 - github.com/cosmos/cosmos-proto v1.0.0-beta.4 - github.com/cosmos/cosmos-sdk v0.50.5 + github.com/cometbft/cometbft v0.38.6 + github.com/cosmos/cosmos-proto v1.0.0-beta.5 + github.com/cosmos/cosmos-sdk v0.50.6 github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/gogoproto v1.4.11 + github.com/cosmos/gogoproto v1.4.12 github.com/cosmos/relayer/v2 v2.5.2 + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/jessevdk/go-flags v1.5.0 github.com/jsternberg/zap-logfmt v1.3.0 github.com/lightningnetwork/lnd v0.16.4-beta.rc1 github.com/lightningnetwork/lnd/kvdb v1.4.1 - github.com/prometheus/client_golang v1.18.0 + github.com/prometheus/client_golang v1.19.0 github.com/stretchr/testify v1.9.0 github.com/urfave/cli v1.22.14 go.uber.org/atomic v1.10.0 go.uber.org/zap v1.26.0 - google.golang.org/grpc v1.62.0 + google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.33.0 ) @@ -39,24 +41,24 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.36.0 // indirect - cosmossdk.io/api v0.7.3 // indirect + cosmossdk.io/api v0.7.4 // indirect cosmossdk.io/client/v2 v2.0.0-beta.1 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core v0.11.0 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/log v1.3.1 // indirect - cosmossdk.io/store v1.0.2 // indirect + cosmossdk.io/store v1.1.0 // indirect cosmossdk.io/x/circuit v0.1.0 // indirect cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect cosmossdk.io/x/nft v0.1.0 // indirect - cosmossdk.io/x/tx v0.13.1 // indirect - cosmossdk.io/x/upgrade v0.1.0 // indirect + cosmossdk.io/x/tx v0.13.3 // indirect + cosmossdk.io/x/upgrade v0.1.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect - github.com/CosmWasm/wasmd v0.50.0 // indirect - github.com/CosmWasm/wasmvm v1.5.2 // indirect + github.com/CosmWasm/wasmd v0.51.0 // indirect + 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/aead/siphash v1.0.1 // indirect @@ -71,7 +73,7 @@ require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect @@ -79,7 +81,6 @@ require ( github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.5 // indirect 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 @@ -89,7 +90,7 @@ require ( github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.2 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/iavl v1.0.1 // indirect + github.com/cosmos/iavl v1.1.2 // indirect github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect @@ -99,7 +100,6 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // 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 github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect @@ -148,7 +148,7 @@ require ( github.com/hashicorp/go-getter v1.7.4 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-metrics v0.5.1 // indirect + github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect @@ -186,7 +186,7 @@ require ( github.com/lightningnetwork/lnd/healthcheck v1.2.2 // indirect github.com/lightningnetwork/lnd/ticker v1.1.0 // indirect github.com/lightningnetwork/lnd/tor v1.1.0 // indirect - github.com/linxGnu/grocksdb v1.8.12 // indirect + github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -206,15 +206,16 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect + github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pierrec/lz4/v4 v4.1.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.2 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.32.0 // indirect @@ -262,22 +263,22 @@ require ( go.opentelemetry.io/otel/trace v1.22.0 // indirect go.opentelemetry.io/proto/otlp v0.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.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.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + 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.18.0 // indirect + golang.org/x/tools v0.20.0 // indirect google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index f79f38ca..c0bcd9a5 100644 --- a/go.sum +++ b/go.sum @@ -184,8 +184,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= -cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= +cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= @@ -200,8 +200,8 @@ cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= -cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= +cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= +cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= @@ -210,10 +210,10 @@ cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= cosmossdk.io/x/nft v0.1.0 h1:VhcsFiEK33ODN27kxKLa0r/CeFd8laBfbDBwYqCyYCM= cosmossdk.io/x/nft v0.1.0/go.mod h1:ec4j4QAO4mJZ+45jeYRnW7awLHby1JZANqe1hNZ4S3g= -cosmossdk.io/x/tx v0.13.1 h1:Mg+EMp67Pz+NukbJqYxuo8uRp7N/a9uR+oVS9pONtj8= -cosmossdk.io/x/tx v0.13.1/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= -cosmossdk.io/x/upgrade v0.1.0 h1:z1ZZG4UL9ICTNbJDYZ6jOnF9GdEK9wyoEFi4BUScHXE= -cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= +cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= +cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -225,10 +225,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CosmWasm/wasmd v0.50.0 h1:NVaGqCSTRfb9UTDHJwT6nQIWcb6VjlQl88iI+u1+qjE= -github.com/CosmWasm/wasmd v0.50.0/go.mod h1:UjmShW4l9YxaMytwJZ7IB7MWzHiynSZP3DdWrG0FRtk= -github.com/CosmWasm/wasmvm v1.5.2 h1:+pKB1Mz9GZVt1vadxB+EDdD1FOz3dMNjIKq/58/lrag= -github.com/CosmWasm/wasmvm v1.5.2/go.mod h1:Q0bSEtlktzh7W2hhEaifrFp1Erx11ckQZmjq8FLCyys= +github.com/CosmWasm/wasmd v0.51.0 h1:3A2o20RrdF7P1D3Xb+R7A/pHbbHWsYCDXrHLa7S0SC8= +github.com/CosmWasm/wasmd v0.51.0/go.mod h1:7TSaj5HoolghujuVWeExqmcUKgpcYWEySGLSODbnnwY= +github.com/CosmWasm/wasmvm/v2 v2.0.0 h1:IqNCI2G0mvs7K6ej17/I28805rVqnu+Y1cWDqIdwb08= +github.com/CosmWasm/wasmvm/v2 v2.0.0/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= @@ -281,8 +281,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b h1:HfjAGZiebrcInFAq8Lk8MXbKbtTYxRoO65vfLPOCXzw= -github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b/go.mod h1:lfeASLNJgcUsX7LEns3HRUv0k+MjzcB2q2AMasfz38M= +github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 h1:3lXL5eQylIUzcZNxCni2lskwLT0Ix6sTyb5a7iBA/eg= +github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020/go.mod h1:YFALTW+Kp/b5jSDoA7Z70RggJjAedlmQTrpdeU8c3hY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -339,8 +339,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -384,8 +384,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= -github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= +github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk= +github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -410,19 +410,19 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= -github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= -github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA= -github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.50.6 h1:efR3MsvMHX5sxS3be+hOobGk87IzlZbSpsI2x/Vw3hk= +github.com/cosmos/cosmos-sdk v0.50.6/go.mod h1:lVkRY6cdMJ0fG3gp8y4hFrsKZqF4z7y0M2UXFb9Yt40= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= -github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= +github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= +github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= +github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE= @@ -759,8 +759,8 @@ github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVH github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-metrics v0.5.1 h1:rfPwUqFU6uZXNvGl4hzjY8LEBsqFVU4si1H9/Hqck/U= -github.com/hashicorp/go-metrics v0.5.1/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= +github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= +github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= @@ -956,8 +956,8 @@ github.com/lightningnetwork/lnd/tor v1.1.0 h1:iXO7fSzjxTI+p88KmtpbuyuRJeNfgtpl9Q github.com/lightningnetwork/lnd/tor v1.1.0/go.mod h1:RDtaAdwfAm+ONuPYwUhNIH1RAvKPv+75lHPOegUcz64= 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.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= -github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= +github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -1086,8 +1086,8 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= @@ -1111,32 +1111,32 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= +github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1144,8 +1144,8 @@ github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5 github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1387,8 +1387,8 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1400,8 +1400,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1428,8 +1428,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1492,8 +1492,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1519,8 +1519,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1535,8 +1535,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1640,14 +1640,14 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1659,8 +1659,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1729,8 +1729,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1910,12 +1910,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 h1:x9PwdEgd11LgK+orcck69WVRo7DezSO4VUMPI4xpc8A= -google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1958,8 +1958,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= -google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/itest/babylon_node_handler.go b/itest/babylon_node_handler.go index eb53b360..f5e63e20 100644 --- a/itest/babylon_node_handler.go +++ b/itest/babylon_node_handler.go @@ -130,7 +130,6 @@ func NewBabylonNodeHandler(t *testing.T, covenantQuorum int, covenantPks []*type "--keyring-backend=test", "--chain-id=chain-test", "--additional-sender-account", - fmt.Sprintf("--epoch-interval=%d", 5), fmt.Sprintf("--slashing-address=%s", slashingAddr), fmt.Sprintf("--covenant-quorum=%d", covenantQuorum), fmt.Sprintf("--covenant-pks=%s", strings.Join(covenantPksStr, ",")), diff --git a/itest/e2e_test.go b/itest/e2e_test.go index 44cde78b..89635e10 100644 --- a/itest/e2e_test.go +++ b/itest/e2e_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/require" "github.com/babylonchain/finality-provider/finality-provider/proto" + "github.com/babylonchain/finality-provider/finality-provider/service" "github.com/babylonchain/finality-provider/types" ) @@ -26,11 +27,14 @@ var ( // activation with BTC delegation and Covenant sig -> // vote submission -> block finalization func TestFinalityProviderLifeCycle(t *testing.T) { - tm, fpInsList, _ := StartManagerWithFinalityProvider(t, 1) + tm, fpInsList := StartManagerWithFinalityProvider(t, 1) defer tm.Stop(t) fpIns := fpInsList[0] + // check the public randomness is committed + tm.WaitForFpPubRandCommitted(t, fpIns) + // send a BTC delegation _ = tm.InsertBTCDelegation(t, []*btcec.PublicKey{fpIns.GetBtcPk()}, stakingTime, stakingAmount) @@ -55,11 +59,14 @@ func TestFinalityProviderLifeCycle(t *testing.T) { // sends a finality vote over a conflicting block // in this case, the BTC private key should be extracted by Babylon func TestDoubleSigning(t *testing.T) { - tm, fpInsList, _ := StartManagerWithFinalityProvider(t, 1) + tm, fpInsList := StartManagerWithFinalityProvider(t, 1) defer tm.Stop(t) fpIns := fpInsList[0] + // check the public randomness is committed + tm.WaitForFpPubRandCommitted(t, fpIns) + // send a BTC delegation _ = tm.InsertBTCDelegation(t, []*btcec.PublicKey{fpIns.GetBtcPk()}, stakingTime, stakingAmount) @@ -111,13 +118,19 @@ func TestDoubleSigning(t *testing.T) { // TestMultipleFinalityProviders tests starting with multiple finality providers func TestMultipleFinalityProviders(t *testing.T) { n := 3 - tm, fpInstances, _ := StartManagerWithFinalityProvider(t, n) + tm, fpInstances := StartManagerWithFinalityProvider(t, n) defer tm.Stop(t) // submit BTC delegations for each finality-provider for _, fpIns := range fpInstances { - // send a BTC delegation - _ = tm.InsertBTCDelegation(t, []*btcec.PublicKey{fpIns.GetBtcPk()}, stakingTime, stakingAmount) + tm.Wg.Add(1) + go func(fpi *service.FinalityProviderInstance) { + defer tm.Wg.Done() + // check the public randomness is committed + tm.WaitForFpPubRandCommitted(t, fpi) + // send a BTC delegation + _ = tm.InsertBTCDelegation(t, []*btcec.PublicKey{fpi.GetBtcPk()}, stakingTime, stakingAmount) + }(fpIns) } tm.Wg.Wait() @@ -142,11 +155,14 @@ func TestMultipleFinalityProviders(t *testing.T) { // TestFastSync tests the fast sync process where the finality-provider is terminated and restarted with fast sync func TestFastSync(t *testing.T) { - tm, fpInsList, _ := StartManagerWithFinalityProvider(t, 1) + tm, fpInsList := StartManagerWithFinalityProvider(t, 1) defer tm.Stop(t) fpIns := fpInsList[0] + // check the public randomness is committed + tm.WaitForFpPubRandCommitted(t, fpIns) + // send a BTC delegation _ = tm.InsertBTCDelegation(t, []*btcec.PublicKey{fpIns.GetBtcPk()}, stakingTime, stakingAmount) diff --git a/itest/test_manager.go b/itest/test_manager.go index 63af3876..b1583de1 100644 --- a/itest/test_manager.go +++ b/itest/test_manager.go @@ -13,21 +13,18 @@ import ( sdkmath "cosmossdk.io/math" "github.com/babylonchain/babylon/btcstaking" - txformat "github.com/babylonchain/babylon/btctxformatter" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" "github.com/babylonchain/babylon/testutil/datagen" bbntypes "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "go.uber.org/zap" @@ -151,13 +148,10 @@ func (tm *TestManager) WaitForServicesStart(t *testing.T) { t.Logf("Babylon node is started") } -func StartManagerWithFinalityProvider(t *testing.T, n int) (*TestManager, []*service.FinalityProviderInstance, uint64) { +func StartManagerWithFinalityProvider(t *testing.T, n int) (*TestManager, []*service.FinalityProviderInstance) { tm := StartManager(t) app := tm.Fpa - // register all finality providers - registeredEpoch := uint64(0) - fpPKs := make([]*bbntypes.BIP340PubKey, 0, n) for i := 0; i < n; i++ { fpName := fpNamePrefix + strconv.Itoa(i) moniker := monikerPrefix + strconv.Itoa(i) @@ -170,55 +164,46 @@ func StartManagerWithFinalityProvider(t *testing.T, n int) (*TestManager, []*ser require.NoError(t, err) fpPk, err := bbntypes.NewBIP340PubKeyFromHex(res.FpInfo.BtcPkHex) require.NoError(t, err) - fpPKs = append(fpPKs, fpPk) - resp, err := app.RegisterFinalityProvider(fpPk.MarshalHex()) + _, err = app.RegisterFinalityProvider(fpPk.MarshalHex()) require.NoError(t, err) - registeredEpoch = resp.RegisteredEpoch // last registered epoch - } - - // wait until the last registered epoch is finalised - tm.FinalizeUntilEpoch(t, registeredEpoch) - - for i := 0; i < n; i++ { - // start - err := app.StartHandlingFinalityProvider(fpPKs[i], passphrase) + err = app.StartHandlingFinalityProvider(fpPk, passphrase) require.NoError(t, err) - fpIns, err := app.GetFinalityProviderInstance(fpPKs[i]) + fpIns, err := app.GetFinalityProviderInstance(fpPk) require.NoError(t, err) require.True(t, fpIns.IsRunning()) require.NoError(t, err) - } - - // check finality providers on Babylon side - require.Eventually(t, func() bool { - fps, err := tm.BBNClient.QueryFinalityProviders() - if err != nil { - t.Logf("failed to query finality providers from Babylon %s", err.Error()) - return false - } - if len(fps) != n { - return false - } - - for _, fp := range fps { - if !strings.Contains(fp.Description.Moniker, monikerPrefix) { + // check finality providers on Babylon side + require.Eventually(t, func() bool { + fps, err := tm.BBNClient.QueryFinalityProviders() + if err != nil { + t.Logf("failed to query finality providers from Babylon %s", err.Error()) return false } - if !fp.Commission.Equal(sdkmath.LegacyZeroDec()) { + + if len(fps) != i+1 { return false } - } - return true - }, eventuallyWaitTimeOut, eventuallyPollTime) + for _, fp := range fps { + if !strings.Contains(fp.Description.Moniker, monikerPrefix) { + return false + } + if !fp.Commission.Equal(sdkmath.LegacyZeroDec()) { + return false + } + } + + return true + }, eventuallyWaitTimeOut, eventuallyPollTime) + } fpInsList := app.ListFinalityProviderInstances() require.Equal(t, n, len(fpInsList)) t.Logf("the test manager is running with %v finality-provider(s)", len(fpInsList)) - return tm, fpInsList, registeredEpoch + return tm, fpInsList } func (tm *TestManager) Stop(t *testing.T) { @@ -243,6 +228,18 @@ func (tm *TestManager) WaitForFpRegistered(t *testing.T, bbnPk *secp256k1.PubKey t.Logf("the finality-provider is successfully registered") } +func (tm *TestManager) WaitForFpPubRandCommitted(t *testing.T, fpIns *service.FinalityProviderInstance) { + require.Eventually(t, func() bool { + lastCommittedHeight, err := fpIns.GetLastCommittedHeight() + if err != nil { + return false + } + return lastCommittedHeight > 0 + }, eventuallyWaitTimeOut, eventuallyPollTime) + + t.Logf("public randomness is successfully committed") +} + func (tm *TestManager) WaitForNPendingDels(t *testing.T, n int) []*bstypes.BTCDelegationResponse { var ( dels []*bstypes.BTCDelegationResponse @@ -767,112 +764,3 @@ func ParseRespBTCDelToBTCDel(resp *bstypes.BTCDelegationResponse) (btcDel *bstyp return btcDel, nil } - -func (tm *TestManager) InsertWBTCHeaders(t *testing.T, r *rand.Rand) { - params, err := tm.BBNClient.QueryStakingParams() - require.NoError(t, err) - btcTipResp, err := tm.BBNClient.QueryBtcLightClientTip() - require.NoError(t, err) - tipHeader, err := bbntypes.NewBTCHeaderBytesFromHex(btcTipResp.HeaderHex) - require.NoError(t, err) - kHeaders := datagen.NewBTCHeaderChainFromParentInfo(r, &btclctypes.BTCHeaderInfo{ - Header: &tipHeader, - Hash: tipHeader.Hash(), - Height: btcTipResp.Height, - Work: &btcTipResp.Work, - }, uint32(params.FinalizationTimeoutBlocks)) - _, err = tm.BBNClient.InsertBtcBlockHeaders(kHeaders.ChainToBytes()) - require.NoError(t, err) -} - -func (tm *TestManager) FinalizeUntilEpoch(t *testing.T, epoch uint64) { - bbnClient := tm.BBNClient.GetBBNClient() - - // wait until the checkpoint of this epoch is sealed - require.Eventually(t, func() bool { - lastSealedCkpt, err := bbnClient.LatestEpochFromStatus(ckpttypes.Sealed) - if err != nil { - return false - } - return epoch <= lastSealedCkpt.RawCheckpoint.EpochNum - }, eventuallyWaitTimeOut, 1*time.Second) - - t.Logf("start finalizing epochs till %d", epoch) - // Random source for the generation of BTC data - r := rand.New(rand.NewSource(time.Now().Unix())) - - // get all checkpoints of these epochs - pagination := &sdkquerytypes.PageRequest{ - Key: ckpttypes.CkptsObjectKey(1), - Limit: epoch, - } - resp, err := bbnClient.RawCheckpoints(pagination) - require.NoError(t, err) - require.Equal(t, int(epoch), len(resp.RawCheckpoints)) - - submitter := tm.BBNClient.GetKeyAddress() - - for _, checkpoint := range resp.RawCheckpoints { - currentBtcTipResp, err := tm.BBNClient.QueryBtcLightClientTip() - require.NoError(t, err) - tipHeader, err := bbntypes.NewBTCHeaderBytesFromHex(currentBtcTipResp.HeaderHex) - require.NoError(t, err) - - rawCheckpoint, err := checkpoint.Ckpt.ToRawCheckpoint() - require.NoError(t, err) - - btcCheckpoint, err := ckpttypes.FromRawCkptToBTCCkpt(rawCheckpoint, submitter) - require.NoError(t, err) - - babylonTagBytes, err := hex.DecodeString("01020304") - require.NoError(t, err) - - p1, p2, err := txformat.EncodeCheckpointData( - babylonTagBytes, - txformat.CurrentVersion, - btcCheckpoint, - ) - require.NoError(t, err) - - tx1 := datagen.CreatOpReturnTransaction(r, p1) - - opReturn1 := datagen.CreateBlockWithTransaction(r, tipHeader.ToBlockHeader(), tx1) - tx2 := datagen.CreatOpReturnTransaction(r, p2) - opReturn2 := datagen.CreateBlockWithTransaction(r, opReturn1.HeaderBytes.ToBlockHeader(), tx2) - - // insert headers and proofs - _, err = tm.BBNClient.InsertBtcBlockHeaders([]bbntypes.BTCHeaderBytes{ - opReturn1.HeaderBytes, - opReturn2.HeaderBytes, - }) - require.NoError(t, err) - - _, err = tm.BBNClient.InsertSpvProofs(submitter.String(), []*btcctypes.BTCSpvProof{ - opReturn1.SpvProof, - opReturn2.SpvProof, - }) - require.NoError(t, err) - - // wait until this checkpoint is submitted - require.Eventually(t, func() bool { - ckpt, err := bbnClient.RawCheckpoint(checkpoint.Ckpt.EpochNum) - require.NoError(t, err) - return ckpt.RawCheckpoint.Status == ckpttypes.Submitted - }, eventuallyWaitTimeOut, eventuallyPollTime) - } - - // insert w BTC headers - tm.InsertWBTCHeaders(t, r) - - // wait until the checkpoint of this epoch is finalised - require.Eventually(t, func() bool { - lastFinalizedCkpt, err := bbnClient.LatestEpochFromStatus(ckpttypes.Finalized) - if err != nil { - t.Logf("failed to get last finalized epoch: %v", err) - return false - } - return epoch <= lastFinalizedCkpt.RawCheckpoint.EpochNum - }, eventuallyWaitTimeOut, 1*time.Second) - - t.Logf("epoch %d is finalised", epoch) -} diff --git a/keyring/randgenerator.go b/keyring/randgenerator.go deleted file mode 100644 index 6183365d..00000000 --- a/keyring/randgenerator.go +++ /dev/null @@ -1,24 +0,0 @@ -package keyring - -import ( - "crypto/hmac" - "crypto/sha256" - - "github.com/babylonchain/babylon/crypto/eots" -) - -// GenerateMasterRandPair generates pair of master secret/public randomness -// The result is deterministic with each given input -func GenerateMasterRandPair(key []byte, chainID []byte) (*eots.MasterSecretRand, *eots.MasterPublicRand, error) { - // calculate the random hash of the key concatenated with chainID and height - hasher := hmac.New(sha256.New, key) - hasher.Write(chainID) - seedSlice := hasher.Sum(nil) - - // convert to 32-byte seed - var seed [32]byte - copy(seed[:], seedSlice[:32]) - - // convert the hash into private random - return eots.NewMasterRandPairFromSeed(seed) -} diff --git a/metrics/eots_collectors.go b/metrics/eots_collectors.go index f0221de4..be337444 100644 --- a/metrics/eots_collectors.go +++ b/metrics/eots_collectors.go @@ -7,10 +7,12 @@ import ( ) type EotsMetrics struct { - EotsCreatedKeysCounter prometheus.Counter - EotsFpTotalEotsSignCounter *prometheus.CounterVec - EotsFpLastEotsSignHeight *prometheus.GaugeVec - EotsFpTotalSchnorrSignCounter *prometheus.CounterVec + EotsCreatedKeysCounter prometheus.Counter + EotsFpTotalGeneratedRandomnessCounter *prometheus.CounterVec + EotsFpLastGeneratedRandomnessHeight *prometheus.GaugeVec + EotsFpTotalEotsSignCounter *prometheus.CounterVec + EotsFpLastEotsSignHeight *prometheus.GaugeVec + EotsFpTotalSchnorrSignCounter *prometheus.CounterVec } var eotsMetricsRegisterOnce sync.Once @@ -24,6 +26,20 @@ func NewEotsMetrics() *EotsMetrics { Name: "eots_created_keys_counter", Help: "Total number of EOTS keys created", }), + EotsFpTotalGeneratedRandomnessCounter: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "eots_fp_total_generated_randomness_counter", + Help: "Total number of generated randomness pairs by EOTS", + }, + []string{"fp_btc_pk_hex"}, + ), + EotsFpLastGeneratedRandomnessHeight: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "eots_fp_last_generated_randomness_height", + Help: "Height of the last generated randomness pair by EOTS", + }, + []string{"fp_btc_pk_hex"}, + ), EotsFpTotalEotsSignCounter: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "eots_fp_total_eots_sign_counter", @@ -49,6 +65,8 @@ func NewEotsMetrics() *EotsMetrics { // Register the EOTS metrics with Prometheus prometheus.MustRegister(eotsMetricsInstance.EotsCreatedKeysCounter) + prometheus.MustRegister(eotsMetricsInstance.EotsFpTotalGeneratedRandomnessCounter) + prometheus.MustRegister(eotsMetricsInstance.EotsFpLastGeneratedRandomnessHeight) prometheus.MustRegister(eotsMetricsInstance.EotsFpTotalEotsSignCounter) prometheus.MustRegister(eotsMetricsInstance.EotsFpLastEotsSignHeight) prometheus.MustRegister(eotsMetricsInstance.EotsFpTotalSchnorrSignCounter) @@ -62,6 +80,16 @@ func (em *EotsMetrics) IncrementEotsCreatedKeysCounter() { em.EotsCreatedKeysCounter.Inc() } +// IncrementEotsFpTotalGeneratedRandomnessCounter increments the EOTS signature counter +func (em *EotsMetrics) IncrementEotsFpTotalGeneratedRandomnessCounter(fpBtcPkHex string) { + em.EotsFpTotalGeneratedRandomnessCounter.WithLabelValues(fpBtcPkHex).Inc() +} + +// SetEotsFpLastGeneratedRandomnessHeight sets the height of the last generated randomness pair by EOTS +func (em *EotsMetrics) SetEotsFpLastGeneratedRandomnessHeight(fpBtcPkHex string, height float64) { + em.EotsFpLastGeneratedRandomnessHeight.WithLabelValues(fpBtcPkHex).Set(height) +} + // IncrementEotsFpTotalEotsSignCounter increments the EOTS signature counter func (em *EotsMetrics) IncrementEotsFpTotalEotsSignCounter(fpBtcPkHex string) { em.EotsFpTotalEotsSignCounter.WithLabelValues(fpBtcPkHex).Inc() diff --git a/testutil/datagen.go b/testutil/datagen.go index 6afc9fe4..6c3982c6 100644 --- a/testutil/datagen.go +++ b/testutil/datagen.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/babylonchain/babylon/crypto/eots" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -13,7 +14,6 @@ import ( "github.com/babylonchain/finality-provider/finality-provider/store" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" @@ -52,6 +52,12 @@ func AddRandomSeedsToFuzzer(f *testing.F, num uint) { } } +func GenPublicRand(r *rand.Rand, t *testing.T) *bbn.SchnorrPubRand { + _, eotsPR, err := eots.RandGen(r) + require.NoError(t, err) + return bbn.NewSchnorrPubRandFromFieldVal(eotsPR) +} + func GenRandomFinalityProvider(r *rand.Rand, t *testing.T) *store.StoredFinalityProvider { // generate BTC key pair btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) @@ -68,17 +74,13 @@ func GenRandomFinalityProvider(r *rand.Rand, t *testing.T) *store.StoredFinality err = pop.Verify(chainPk, bip340PK, &chaincfg.SimNetParams) require.NoError(t, err) - _, mpr, err := eots.NewMasterRandPair(r) - require.NoError(t, err) - return &store.StoredFinalityProvider{ - KeyName: GenRandomHexStr(r, 4), - ChainID: "chain-test", - ChainPk: &secp256k1.PubKey{Key: chainPk.Bytes()}, - BtcPk: bip340PK.MustToBTCPK(), - Description: RandomDescription(r), - Commission: ZeroCommissionRate(), - MasterPubRand: mpr.MarshalBase58(), + KeyName: GenRandomHexStr(r, 4), + ChainID: "chain-test", + ChainPk: &secp256k1.PubKey{Key: chainPk.Bytes()}, + BtcPk: bip340PK.MustToBTCPK(), + Description: RandomDescription(r), + Commission: ZeroCommissionRate(), Pop: &proto.ProofOfPossession{ ChainSig: pop.BabylonSig, BtcSig: pop.BtcSig, diff --git a/testutil/mocks/babylon.go b/testutil/mocks/babylon.go index bf9cc8bb..9bec5685 100644 --- a/testutil/mocks/babylon.go +++ b/testutil/mocks/babylon.go @@ -8,8 +8,10 @@ import ( reflect "reflect" math "cosmossdk.io/math" - types "github.com/babylonchain/finality-provider/types" + types "github.com/babylonchain/babylon/x/finality/types" + types0 "github.com/babylonchain/finality-provider/types" btcec "github.com/btcsuite/btcd/btcec/v2" + schnorr "github.com/btcsuite/btcd/btcec/v2/schnorr" gomock "github.com/golang/mock/gomock" ) @@ -50,6 +52,21 @@ func (mr *MockClientControllerMockRecorder) Close() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockClientController)(nil).Close)) } +// CommitPubRandList mocks base method. +func (m *MockClientController) CommitPubRandList(fpPk *btcec.PublicKey, startHeight, numPubRand uint64, commitment []byte, sig *schnorr.Signature) (*types0.TxResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CommitPubRandList", fpPk, startHeight, numPubRand, commitment, sig) + ret0, _ := ret[0].(*types0.TxResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CommitPubRandList indicates an expected call of CommitPubRandList. +func (mr *MockClientControllerMockRecorder) CommitPubRandList(fpPk, startHeight, numPubRand, commitment, sig interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitPubRandList", reflect.TypeOf((*MockClientController)(nil).CommitPubRandList), fpPk, startHeight, numPubRand, commitment, sig) +} + // QueryActivatedHeight mocks base method. func (m *MockClientController) QueryActivatedHeight() (uint64, error) { m.ctrl.T.Helper() @@ -66,10 +83,10 @@ func (mr *MockClientControllerMockRecorder) QueryActivatedHeight() *gomock.Call } // QueryBestBlock mocks base method. -func (m *MockClientController) QueryBestBlock() (*types.BlockInfo, error) { +func (m *MockClientController) QueryBestBlock() (*types0.BlockInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryBestBlock") - ret0, _ := ret[0].(*types.BlockInfo) + ret0, _ := ret[0].(*types0.BlockInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -81,10 +98,10 @@ func (mr *MockClientControllerMockRecorder) QueryBestBlock() *gomock.Call { } // QueryBlock mocks base method. -func (m *MockClientController) QueryBlock(height uint64) (*types.BlockInfo, error) { +func (m *MockClientController) QueryBlock(height uint64) (*types0.BlockInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryBlock", height) - ret0, _ := ret[0].(*types.BlockInfo) + ret0, _ := ret[0].(*types0.BlockInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -96,10 +113,10 @@ func (mr *MockClientControllerMockRecorder) QueryBlock(height interface{}) *gomo } // QueryBlocks mocks base method. -func (m *MockClientController) QueryBlocks(startHeight, endHeight, limit uint64) ([]*types.BlockInfo, error) { +func (m *MockClientController) QueryBlocks(startHeight, endHeight, limit uint64) ([]*types0.BlockInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryBlocks", startHeight, endHeight, limit) - ret0, _ := ret[0].([]*types.BlockInfo) + ret0, _ := ret[0].([]*types0.BlockInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -140,26 +157,26 @@ func (mr *MockClientControllerMockRecorder) QueryFinalityProviderVotingPower(fpP return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFinalityProviderVotingPower", reflect.TypeOf((*MockClientController)(nil).QueryFinalityProviderVotingPower), fpPk, blockHeight) } -// QueryLastFinalizedEpoch mocks base method. -func (m *MockClientController) QueryLastFinalizedEpoch() (uint64, error) { +// QueryLastCommittedPublicRand mocks base method. +func (m *MockClientController) QueryLastCommittedPublicRand(fpPk *btcec.PublicKey, count uint64) (map[uint64]*types.PubRandCommitResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryLastFinalizedEpoch") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "QueryLastCommittedPublicRand", fpPk, count) + ret0, _ := ret[0].(map[uint64]*types.PubRandCommitResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// QueryLastFinalizedEpoch indicates an expected call of QueryLastFinalizedEpoch. -func (mr *MockClientControllerMockRecorder) QueryLastFinalizedEpoch() *gomock.Call { +// QueryLastCommittedPublicRand indicates an expected call of QueryLastCommittedPublicRand. +func (mr *MockClientControllerMockRecorder) QueryLastCommittedPublicRand(fpPk, count interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryLastFinalizedEpoch", reflect.TypeOf((*MockClientController)(nil).QueryLastFinalizedEpoch)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryLastCommittedPublicRand", reflect.TypeOf((*MockClientController)(nil).QueryLastCommittedPublicRand), fpPk, count) } // QueryLatestFinalizedBlocks mocks base method. -func (m *MockClientController) QueryLatestFinalizedBlocks(count uint64) ([]*types.BlockInfo, error) { +func (m *MockClientController) QueryLatestFinalizedBlocks(count uint64) ([]*types0.BlockInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryLatestFinalizedBlocks", count) - ret0, _ := ret[0].([]*types.BlockInfo) + ret0, _ := ret[0].([]*types0.BlockInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -171,47 +188,46 @@ func (mr *MockClientControllerMockRecorder) QueryLatestFinalizedBlocks(count int } // RegisterFinalityProvider mocks base method. -func (m *MockClientController) RegisterFinalityProvider(chainPk []byte, fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, description []byte, masterPubRand string) (*types.TxResponse, uint64, error) { +func (m *MockClientController) RegisterFinalityProvider(chainPk []byte, fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, description []byte) (*types0.TxResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterFinalityProvider", chainPk, fpPk, pop, commission, description, masterPubRand) - ret0, _ := ret[0].(*types.TxResponse) - ret1, _ := ret[1].(uint64) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + ret := m.ctrl.Call(m, "RegisterFinalityProvider", chainPk, fpPk, pop, commission, description) + ret0, _ := ret[0].(*types0.TxResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 } // RegisterFinalityProvider indicates an expected call of RegisterFinalityProvider. -func (mr *MockClientControllerMockRecorder) RegisterFinalityProvider(chainPk, fpPk, pop, commission, description, masterPubRand interface{}) *gomock.Call { +func (mr *MockClientControllerMockRecorder) RegisterFinalityProvider(chainPk, fpPk, pop, commission, description interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterFinalityProvider", reflect.TypeOf((*MockClientController)(nil).RegisterFinalityProvider), chainPk, fpPk, pop, commission, description, masterPubRand) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterFinalityProvider", reflect.TypeOf((*MockClientController)(nil).RegisterFinalityProvider), chainPk, fpPk, pop, commission, description) } // SubmitBatchFinalitySigs mocks base method. -func (m *MockClientController) SubmitBatchFinalitySigs(fpPk *btcec.PublicKey, blocks []*types.BlockInfo, sigs []*btcec.ModNScalar) (*types.TxResponse, error) { +func (m *MockClientController) SubmitBatchFinalitySigs(fpPk *btcec.PublicKey, blocks []*types0.BlockInfo, pubRandList []*btcec.FieldVal, proofList [][]byte, sigs []*btcec.ModNScalar) (*types0.TxResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubmitBatchFinalitySigs", fpPk, blocks, sigs) - ret0, _ := ret[0].(*types.TxResponse) + ret := m.ctrl.Call(m, "SubmitBatchFinalitySigs", fpPk, blocks, pubRandList, proofList, sigs) + ret0, _ := ret[0].(*types0.TxResponse) ret1, _ := ret[1].(error) return ret0, ret1 } // SubmitBatchFinalitySigs indicates an expected call of SubmitBatchFinalitySigs. -func (mr *MockClientControllerMockRecorder) SubmitBatchFinalitySigs(fpPk, blocks, sigs interface{}) *gomock.Call { +func (mr *MockClientControllerMockRecorder) SubmitBatchFinalitySigs(fpPk, blocks, pubRandList, proofList, sigs interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitBatchFinalitySigs", reflect.TypeOf((*MockClientController)(nil).SubmitBatchFinalitySigs), fpPk, blocks, sigs) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitBatchFinalitySigs", reflect.TypeOf((*MockClientController)(nil).SubmitBatchFinalitySigs), fpPk, blocks, pubRandList, proofList, sigs) } // SubmitFinalitySig mocks base method. -func (m *MockClientController) SubmitFinalitySig(fpPk *btcec.PublicKey, blockHeight uint64, blockHash []byte, sig *btcec.ModNScalar) (*types.TxResponse, error) { +func (m *MockClientController) SubmitFinalitySig(fpPk *btcec.PublicKey, block *types0.BlockInfo, pubRand *btcec.FieldVal, proof []byte, sig *btcec.ModNScalar) (*types0.TxResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubmitFinalitySig", fpPk, blockHeight, blockHash, sig) - ret0, _ := ret[0].(*types.TxResponse) + ret := m.ctrl.Call(m, "SubmitFinalitySig", fpPk, block, pubRand, proof, sig) + ret0, _ := ret[0].(*types0.TxResponse) ret1, _ := ret[1].(error) return ret0, ret1 } // SubmitFinalitySig indicates an expected call of SubmitFinalitySig. -func (mr *MockClientControllerMockRecorder) SubmitFinalitySig(fpPk, blockHeight, blockHash, sig interface{}) *gomock.Call { +func (mr *MockClientControllerMockRecorder) SubmitFinalitySig(fpPk, block, pubRand, proof, sig interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitFinalitySig", reflect.TypeOf((*MockClientController)(nil).SubmitFinalitySig), fpPk, blockHeight, blockHash, sig) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitFinalitySig", reflect.TypeOf((*MockClientController)(nil).SubmitFinalitySig), fpPk, block, pubRand, proof, sig) } diff --git a/tools/go.mod b/tools/go.mod index ed0155fe..e6d232ad 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -4,7 +4,7 @@ go 1.21 toolchain go1.21.4 -require github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b +require github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 require ( cloud.google.com/go v0.112.0 // indirect @@ -12,7 +12,7 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.36.0 // indirect - cosmossdk.io/api v0.7.3 // indirect + cosmossdk.io/api v0.7.4 // indirect cosmossdk.io/client/v2 v2.0.0-beta.1 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core v0.11.0 // indirect @@ -20,19 +20,19 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/math v1.3.0 // indirect - cosmossdk.io/store v1.0.2 // indirect - cosmossdk.io/tools/confix v0.1.0 // indirect + cosmossdk.io/store v1.1.0 // indirect + cosmossdk.io/tools/confix v0.1.1 // indirect cosmossdk.io/x/circuit v0.1.0 // indirect cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect cosmossdk.io/x/nft v0.1.0 // indirect - cosmossdk.io/x/tx v0.13.1 // indirect - cosmossdk.io/x/upgrade v0.1.0 // indirect + cosmossdk.io/x/tx v0.13.3 // indirect + cosmossdk.io/x/upgrade v0.1.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect - github.com/CosmWasm/wasmd v0.50.0 // indirect - github.com/CosmWasm/wasmvm v1.5.2 // indirect + github.com/CosmWasm/wasmd v0.51.0 // indirect + 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/aead/siphash v1.0.1 // indirect @@ -49,7 +49,7 @@ require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect @@ -57,16 +57,16 @@ require ( github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.5 // indirect + github.com/cometbft/cometbft v0.38.6 // indirect github.com/cometbft/cometbft-db v0.9.1 // 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.4 // indirect - github.com/cosmos/cosmos-sdk v0.50.5 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/cosmos-sdk v0.50.6 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v1.0.1 // indirect + github.com/cosmos/gogoproto v1.4.12 // indirect + github.com/cosmos/iavl v1.1.2 // indirect github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect @@ -118,10 +118,10 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.4 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-metrics v0.5.1 // indirect + github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.8.12 // indirect + github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -156,13 +156,13 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect + github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.2 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.8.3 // indirect @@ -194,21 +194,21 @@ require ( go.opentelemetry.io/otel/metric v1.22.0 // indirect go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect - google.golang.org/grpc v1.62.0 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index 5b909011..cc5875d2 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -184,8 +184,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= -cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= +cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= @@ -200,10 +200,10 @@ cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= -cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= -cosmossdk.io/tools/confix v0.1.0 h1:2OOZTtQsDT5e7P3FM5xqM0bPfluAxZlAwxqaDmYBE+E= -cosmossdk.io/tools/confix v0.1.0/go.mod h1:TdXKVYs4gEayav5wM+JHT+kTU2J7fozFNqoVaN+8CdY= +cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= +cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= +cosmossdk.io/tools/confix v0.1.1 h1:aexyRv9+y15veH3Qw16lxQwo+ki7r2I+g0yNTEFEQM8= +cosmossdk.io/tools/confix v0.1.1/go.mod h1:nQVvP1tHsGXS83PonPVWJtSbddIqyjEw99L4M3rPJyQ= cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= @@ -212,10 +212,10 @@ cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= cosmossdk.io/x/nft v0.1.0 h1:VhcsFiEK33ODN27kxKLa0r/CeFd8laBfbDBwYqCyYCM= cosmossdk.io/x/nft v0.1.0/go.mod h1:ec4j4QAO4mJZ+45jeYRnW7awLHby1JZANqe1hNZ4S3g= -cosmossdk.io/x/tx v0.13.1 h1:Mg+EMp67Pz+NukbJqYxuo8uRp7N/a9uR+oVS9pONtj8= -cosmossdk.io/x/tx v0.13.1/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= -cosmossdk.io/x/upgrade v0.1.0 h1:z1ZZG4UL9ICTNbJDYZ6jOnF9GdEK9wyoEFi4BUScHXE= -cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= +cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= +cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -225,10 +225,10 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CosmWasm/wasmd v0.50.0 h1:NVaGqCSTRfb9UTDHJwT6nQIWcb6VjlQl88iI+u1+qjE= -github.com/CosmWasm/wasmd v0.50.0/go.mod h1:UjmShW4l9YxaMytwJZ7IB7MWzHiynSZP3DdWrG0FRtk= -github.com/CosmWasm/wasmvm v1.5.2 h1:+pKB1Mz9GZVt1vadxB+EDdD1FOz3dMNjIKq/58/lrag= -github.com/CosmWasm/wasmvm v1.5.2/go.mod h1:Q0bSEtlktzh7W2hhEaifrFp1Erx11ckQZmjq8FLCyys= +github.com/CosmWasm/wasmd v0.51.0 h1:3A2o20RrdF7P1D3Xb+R7A/pHbbHWsYCDXrHLa7S0SC8= +github.com/CosmWasm/wasmd v0.51.0/go.mod h1:7TSaj5HoolghujuVWeExqmcUKgpcYWEySGLSODbnnwY= +github.com/CosmWasm/wasmvm/v2 v2.0.0 h1:IqNCI2G0mvs7K6ej17/I28805rVqnu+Y1cWDqIdwb08= +github.com/CosmWasm/wasmvm/v2 v2.0.0/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= @@ -268,8 +268,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b h1:HfjAGZiebrcInFAq8Lk8MXbKbtTYxRoO65vfLPOCXzw= -github.com/babylonchain/babylon v0.8.6-0.20240416015120-ffeb9c5b930b/go.mod h1:lfeASLNJgcUsX7LEns3HRUv0k+MjzcB2q2AMasfz38M= +github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 h1:3lXL5eQylIUzcZNxCni2lskwLT0Ix6sTyb5a7iBA/eg= +github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020/go.mod h1:YFALTW+Kp/b5jSDoA7Z70RggJjAedlmQTrpdeU8c3hY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -323,8 +323,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -366,8 +366,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= -github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= +github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk= +github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -382,19 +382,19 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= -github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= -github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA= -github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.50.6 h1:efR3MsvMHX5sxS3be+hOobGk87IzlZbSpsI2x/Vw3hk= +github.com/cosmos/cosmos-sdk v0.50.6/go.mod h1:lVkRY6cdMJ0fG3gp8y4hFrsKZqF4z7y0M2UXFb9Yt40= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= -github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= +github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= +github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= +github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE= @@ -701,15 +701,15 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.4 h1:3yQjWuxICvSpYwqSayAdKRFcvBl1y/vogCxczWSmix0= -github.com/hashicorp/go-getter v1.7.4/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-metrics v0.5.1 h1:rfPwUqFU6uZXNvGl4hzjY8LEBsqFVU4si1H9/Hqck/U= -github.com/hashicorp/go-metrics v0.5.1/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= +github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= +github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= @@ -817,8 +817,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= 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.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= -github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= +github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -927,8 +927,8 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -949,32 +949,32 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= +github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1149,8 +1149,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1162,8 +1162,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1190,8 +1190,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1252,8 +1252,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1279,8 +1279,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1295,8 +1295,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1395,13 +1395,13 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1413,8 +1413,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1483,8 +1483,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1661,12 +1661,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 h1:x9PwdEgd11LgK+orcck69WVRo7DezSO4VUMPI4xpc8A= -google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1708,8 +1708,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= -google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/types/chainkey.go b/types/chainkey.go index 56f88ced..6d5df870 100644 --- a/types/chainkey.go +++ b/types/chainkey.go @@ -12,7 +12,3 @@ type ChainKeyInfo struct { PublicKey *btcec.PublicKey PrivateKey *btcec.PrivateKey } - -func MarshalChainID(chainID string) []byte { - return []byte(chainID) -} diff --git a/types/pub_rand_commit.go b/types/pub_rand_commit.go new file mode 100644 index 00000000..972cd458 --- /dev/null +++ b/types/pub_rand_commit.go @@ -0,0 +1,17 @@ +package types + +import ( + bbn "github.com/babylonchain/babylon/types" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/cometbft/cometbft/crypto/merkle" +) + +// GetPubRandCommitAndProofs commits a list of public randomness and returns +// the commitment (i.e., Merkle root) and all Merkle proofs +func GetPubRandCommitAndProofs(pubRandList []*btcec.FieldVal) ([]byte, []*merkle.Proof) { + prBytesList := make([][]byte, 0, len(pubRandList)) + for _, pr := range pubRandList { + prBytesList = append(prBytesList, bbn.NewSchnorrPubRandFromFieldVal(pr).MustMarshal()) + } + return merkle.ProofsFromByteSlices(prBytesList) +} From 15eeb42debf62e140fcbf34d41938038b48b5d3d Mon Sep 17 00:00:00 2001 From: iwantanode <87604944+tudorpintea999@users.noreply.github.com> Date: Mon, 10 Jun 2024 08:02:55 +0300 Subject: [PATCH 08/21] Update eots.md (#370) Hello I fixed a minor typo, Hope it helps. Br, Tudor --- docs/eots.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/eots.md b/docs/eots.md index 925d3cb6..fd945f28 100644 --- a/docs/eots.md +++ b/docs/eots.md @@ -68,7 +68,7 @@ Handles the keys for EOTS. The binary `eotsd` has the option to add a new key to the keyring for later usage with signing EOTS and Schnorr signatures. Keep in mind that new keys can be created on demand by the GRPC call from `fpd`. -But, if you would like to add a new EOTS keys manually, run `eotsd keys add`. +But, if you would like to add a new EOTS key manually, run `eotsd keys add`. This command has several flag options: From 9fe04d260b0aceb37c0176356851e53971b08932 Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Thu, 13 Jun 2024 11:02:20 +0800 Subject: [PATCH 09/21] chore: Fix issues in retry loops (#373) --- finality-provider/service/errors.go | 7 +++ finality-provider/service/fp_instance.go | 56 +++++++++++++++++------- log/log.go | 2 +- 3 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 finality-provider/service/errors.go diff --git a/finality-provider/service/errors.go b/finality-provider/service/errors.go new file mode 100644 index 00000000..c499215e --- /dev/null +++ b/finality-provider/service/errors.go @@ -0,0 +1,7 @@ +package service + +import "errors" + +var ( + ErrFinalityProviderShutDown = errors.New("the finality provider instance is shutting down") +) diff --git a/finality-provider/service/fp_instance.go b/finality-provider/service/fp_instance.go index 8bff0433..d08bc146 100644 --- a/finality-provider/service/fp_instance.go +++ b/finality-provider/service/fp_instance.go @@ -207,19 +207,29 @@ func (fp *FinalityProviderInstance) finalitySigSubmissionLoop() { continue } // check whether the randomness has been committed - // we should stall here until we have randomness committed at this - // height, otherwise, we might miss blocks - if err := fp.retryCheckRandomnessUntilBlockFinalized(b); err != nil { - fp.reportCriticalErr(err) + // the retry will end if max retry times is reached + // or the target block is finalized + isFinalized, err := fp.retryCheckRandomnessUntilBlockFinalized(b) + if err != nil { + if !errors.Is(err, ErrFinalityProviderShutDown) { + fp.reportCriticalErr(err) + } break } + // the block is finalized, no need to submit finality signature + if isFinalized { + fp.MustSetLastProcessedHeight(b.Height) + continue + } // use the copy of the block to avoid the impact to other receivers nextBlock := *b res, err := fp.retrySubmitFinalitySignatureUntilBlockFinalized(&nextBlock) if err != nil { fp.metrics.IncrementFpTotalFailedVotes(fp.GetBtcPkHex()) - fp.reportCriticalErr(err) + if !errors.Is(err, ErrFinalityProviderShutDown) { + fp.reportCriticalErr(err) + } continue } if res == nil { @@ -459,8 +469,8 @@ func (fp *FinalityProviderInstance) checkLagging(currentBlock *types.BlockInfo) // finalized // error will be returned if maximum retries have been reached or the query to // the consumer chain fails -func (fp *FinalityProviderInstance) retryCheckRandomnessUntilBlockFinalized(targetBlock *types.BlockInfo) error { - var failedCycles uint32 +func (fp *FinalityProviderInstance) retryCheckRandomnessUntilBlockFinalized(targetBlock *types.BlockInfo) (bool, error) { + var numRetries uint32 // we break the for loop if the block is finalized or the randomness is successfully committed // error will be returned if maximum retries have been reached or the query to the consumer chain fails @@ -475,25 +485,37 @@ func (fp *FinalityProviderInstance) retryCheckRandomnessUntilBlockFinalized(targ fp.logger.Debug( "failed to check last committed randomness", zap.String("pk", fp.GetBtcPkHex()), - zap.Uint32("current_failures", failedCycles), + zap.Uint32("current_failures", numRetries), zap.Uint64("target_block_height", targetBlock.Height), zap.Error(err), ) - failedCycles += 1 - if failedCycles > uint32(fp.cfg.MaxSubmissionRetries) { - return fmt.Errorf("reached max failed cycles with err: %w", err) + numRetries += 1 + if numRetries > uint32(fp.cfg.MaxSubmissionRetries) { + return false, fmt.Errorf("reached max failed cycles with err: %w", err) } - } else if hasRand { + } else if !hasRand { + fp.logger.Debug( + "randomness does not exist", + zap.String("pk", fp.GetBtcPkHex()), + zap.Uint32("current_retries", numRetries), + zap.Uint64("target_block_height", targetBlock.Height), + ) + + numRetries += 1 + if numRetries > uint32(fp.cfg.MaxSubmissionRetries) { + return false, fmt.Errorf("reached max retries but randomness still not existed") + } + } else { // the randomness has been successfully committed - return nil + return false, nil } select { case <-time.After(fp.cfg.SubmissionRetryInterval): // periodically query the index block to be later checked whether it is Finalized finalized, err := fp.checkBlockFinalization(targetBlock.Height) if err != nil { - return fmt.Errorf("failed to query block finalization at height %v: %w", targetBlock.Height, err) + return false, fmt.Errorf("failed to query block finalization at height %v: %w", targetBlock.Height, err) } if finalized { fp.logger.Debug( @@ -503,12 +525,12 @@ func (fp *FinalityProviderInstance) retryCheckRandomnessUntilBlockFinalized(targ ) // TODO: returning nil here is to safely break the loop // the error still exists - return nil + return true, nil } case <-fp.quit: fp.logger.Debug("the finality-provider instance is closing", zap.String("pk", fp.GetBtcPkHex())) - return nil + return false, ErrFinalityProviderShutDown } } } @@ -569,7 +591,7 @@ func (fp *FinalityProviderInstance) retrySubmitFinalitySignatureUntilBlockFinali case <-fp.quit: fp.logger.Debug("the finality-provider instance is closing", zap.String("pk", fp.GetBtcPkHex())) - return nil, nil + return nil, ErrFinalityProviderShutDown } } } diff --git a/log/log.go b/log/log.go index 791179c1..4b05ed39 100644 --- a/log/log.go +++ b/log/log.go @@ -63,7 +63,7 @@ func NewRootLoggerWithFile(logFile string, level string) (*zap.Logger, error) { if err := util.MakeDirectory(filepath.Dir(logFile)); err != nil { return nil, err } - f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660) if err != nil { return nil, err } From fb5f89486131310f5daa03dbb4acbca4ca9d3dfc Mon Sep 17 00:00:00 2001 From: Elias Rad <146735585+nnsW3@users.noreply.github.com> Date: Mon, 17 Jun 2024 03:41:27 +0300 Subject: [PATCH 10/21] Fix typos (#375) This PR addresses several typographical errors across various files in the project. The changes improve readability and maintain the professional standard of the documentation and code comments. Hope it helps Best regards, Elias. --- clientcontroller/babylon.go | 2 +- clientcontroller/retry_utils.go | 2 +- docs/eots.md | 2 +- docs/finality-provider.md | 2 +- eotsmanager/eotsmanager.go | 2 +- eotsmanager/localmanager.go | 2 +- itest/e2e_test.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clientcontroller/babylon.go b/clientcontroller/babylon.go index d5ba0f25..a8847d32 100644 --- a/clientcontroller/babylon.go +++ b/clientcontroller/babylon.go @@ -76,7 +76,7 @@ func (bc *BabylonController) mustGetTxSigner() string { func (bc *BabylonController) GetKeyAddress() sdk.AccAddress { // get key address, retrieves address based on key name which is configured in - // cfg *stakercfg.BBNConfig. If this fails, it means we have misconfiguration problem + // cfg *stakercfg.BBNConfig. If this fails, it means we have a misconfiguration problem // and we should panic. // This is checked at the start of BabylonController, so if it fails something is really wrong diff --git a/clientcontroller/retry_utils.go b/clientcontroller/retry_utils.go index fb64590b..39748ff7 100644 --- a/clientcontroller/retry_utils.go +++ b/clientcontroller/retry_utils.go @@ -9,7 +9,7 @@ import ( finalitytypes "github.com/babylonchain/babylon/x/finality/types" ) -// these errors are considered unrecoverable because these indicate +// these errors are considered unrecoverable because they indicate // something critical in the finality provider program or the consumer chain var unrecoverableErrors = []*sdkErr.Error{ finalitytypes.ErrBlockNotFound, diff --git a/docs/eots.md b/docs/eots.md index fd945f28..b09b77a7 100644 --- a/docs/eots.md +++ b/docs/eots.md @@ -9,7 +9,7 @@ using them to produce EOTS signatures. in the [Babylon BTC Staking Litepaper](https://docs.babylonchain.io/assets/files/btc_staking_litepaper-32bfea0c243773f0bfac63e148387aef.pdf). In short, the EOTS manager produces EOTS public/private randomness pairs. The -finality provider commits the public part of this pairs to Babylon for every future +finality provider commits the public part of these pairs to Babylon for every future block height that they intend to provide a finality signature for. If the finality provider votes for two different blocks on the same height, they will have to reuse the same private randomness which will lead to their underlying private key being diff --git a/docs/finality-provider.md b/docs/finality-provider.md index b2c6c410..e25b6f65 100644 --- a/docs/finality-provider.md +++ b/docs/finality-provider.md @@ -51,7 +51,7 @@ For different operating systems, those are: Below are some important parameters of the `fpd.conf` file. **Note**: -The configuration below requires to point to the path where this keyring is +The configuration below requires pointing to the path where this keyring is stored `KeyDirectory`. This `Key` field stores the key name used for interacting with the consumer chain and will be specified along with the `KeyringBackend` field in the next [step](#3-add-key-for-the-consumer-chain). So we diff --git a/eotsmanager/eotsmanager.go b/eotsmanager/eotsmanager.go index 2e8e1619..263a1d87 100644 --- a/eotsmanager/eotsmanager.go +++ b/eotsmanager/eotsmanager.go @@ -26,7 +26,7 @@ type EOTSManager interface { KeyRecord(uid []byte, passphrase string) (*types.KeyRecord, error) // SignEOTS signs an EOTS using the private key of the finality provider and the corresponding - // secret randomness of the give chain at the given height + // secret randomness of the given chain at the given height // It fails if the finality provider does not exist or there's no randomness committed to the given height // or passPhrase is incorrect SignEOTS(uid []byte, chainID []byte, msg []byte, height uint64, passphrase string) (*btcec.ModNScalar, error) diff --git a/eotsmanager/localmanager.go b/eotsmanager/localmanager.go index 8e7aa2ee..fe235c84 100644 --- a/eotsmanager/localmanager.go +++ b/eotsmanager/localmanager.go @@ -164,7 +164,7 @@ func loadBIP340PubKeyFromKeyringRecord(record *keyring.Record) (*bbntypes.BIP340 // TODO the current implementation is a PoC, which does not contain any anti-slasher mechanism // // a simple anti-slasher mechanism could be that the manager remembers the tuple (fpPk, chainID, height) or -// the hash of each generated randomness and return error if the same randomness is requested tweice +// the hash of each generated randomness and return error if the same randomness is requested twice func (lm *LocalEOTSManager) CreateRandomnessPairList(fpPk []byte, chainID []byte, startHeight uint64, num uint32, passphrase string) ([]*btcec.FieldVal, error) { prList := make([]*btcec.FieldVal, 0, num) diff --git a/itest/e2e_test.go b/itest/e2e_test.go index 89635e10..5dcccd88 100644 --- a/itest/e2e_test.go +++ b/itest/e2e_test.go @@ -149,7 +149,7 @@ func TestMultipleFinalityProviders(t *testing.T) { // check the BTC delegations are active _ = tm.WaitForNActiveDels(t, n) - // check there's a block finalized + // check if there's a block finalized _ = tm.WaitForNFinalizedBlocks(t, 1) } From 521878347cb90706df0a768861d5526303e26552 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 1 Jul 2024 11:04:06 -0300 Subject: [PATCH 11/21] chore: update BBN version to FP addr is the signer (#435) - The key for Babylon in the config needs to be the FP key to be the signer - E2E testing now if the FP needs to sign something it needs to update the ClientController to be able to sign msgs with the corresponding key Related: https://github.com/babylonchain/babylon/pull/678 --- clientcontroller/babylon.go | 16 +- clientcontroller/interface.go | 6 +- docs/finality-provider.md | 36 +- eotsmanager/proto/eotsmanager.pb.go | 2 +- eotsmanager/proto/eotsmanager_grpc.pb.go | 37 ++- finality-provider/cmd/fpcli/daemon/export.go | 12 +- finality-provider/proto/finality_providers.go | 16 +- .../proto/finality_providers.pb.go | 311 +++++++++--------- .../proto/finality_providers.proto | 15 +- .../proto/finality_providers_grpc.pb.go | 42 ++- finality-provider/service/app.go | 59 ++-- finality-provider/service/app_test.go | 4 +- finality-provider/service/fp_instance.go | 5 +- finality-provider/service/fp_manager_test.go | 8 +- finality-provider/service/fp_store_adapter.go | 17 +- finality-provider/service/rpcserver.go | 3 +- finality-provider/store/fpstore.go | 11 +- finality-provider/store/fpstore_test.go | 10 +- finality-provider/store/storedfp.go | 18 +- go.mod | 5 +- go.sum | 8 +- itest/babylon_node_handler.go | 73 ++-- itest/test_manager.go | 90 ++--- keyring/keyringcontroller.go | 15 +- keyring/keyringcontroller_test.go | 8 +- testutil/datagen.go | 14 +- testutil/mocks/babylon.go | 8 +- tools/go.mod | 5 +- tools/go.sum | 8 +- 29 files changed, 446 insertions(+), 416 deletions(-) diff --git a/clientcontroller/babylon.go b/clientcontroller/babylon.go index a8847d32..a058df57 100644 --- a/clientcontroller/babylon.go +++ b/clientcontroller/babylon.go @@ -18,7 +18,6 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" sttypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -81,13 +80,11 @@ func (bc *BabylonController) GetKeyAddress() sdk.AccAddress { // This is checked at the start of BabylonController, so if it fails something is really wrong keyRec, err := bc.bbnClient.GetKeyring().Key(bc.cfg.Key) - if err != nil { panic(fmt.Sprintf("Failed to get key address: %s", err)) } addr, err := keyRec.GetAddress() - if err != nil { panic(fmt.Sprintf("Failed to get key address: %s", err)) } @@ -111,13 +108,12 @@ func (bc *BabylonController) reliablySendMsgs(msgs []sdk.Msg, expectedErrs []*sd // RegisterFinalityProvider registers a finality provider via a MsgCreateFinalityProvider to Babylon // it returns tx hash and error func (bc *BabylonController) RegisterFinalityProvider( - chainPk []byte, fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, description []byte, ) (*types.TxResponse, error) { - var bbnPop btcstakingtypes.ProofOfPossession + var bbnPop btcstakingtypes.ProofOfPossessionBTC if err := bbnPop.Unmarshal(pop); err != nil { return nil, fmt.Errorf("invalid proof-of-possession: %w", err) } @@ -127,9 +123,9 @@ func (bc *BabylonController) RegisterFinalityProvider( return nil, fmt.Errorf("invalid description: %w", err) } + fpAddr := bc.mustGetTxSigner() msg := &btcstakingtypes.MsgCreateFinalityProvider{ - Signer: bc.mustGetTxSigner(), - BabylonPk: &secp256k1.PubKey{Key: chainPk}, + Addr: fpAddr, BtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk), Pop: &bbnPop, Commission: commission, @@ -409,10 +405,9 @@ func (bc *BabylonController) Close() error { */ func (bc *BabylonController) CreateBTCDelegation( - delBabylonPk *secp256k1.PubKey, delBtcPk *bbntypes.BIP340PubKey, fpPks []*btcec.PublicKey, - pop *btcstakingtypes.ProofOfPossession, + pop *btcstakingtypes.ProofOfPossessionBTC, stakingTime uint32, stakingValue int64, stakingTxInfo *btcctypes.TransactionInfo, @@ -429,8 +424,7 @@ func (bc *BabylonController) CreateBTCDelegation( fpBtcPks = append(fpBtcPks, *bbntypes.NewBIP340PubKeyFromBTCPK(v)) } msg := &btcstakingtypes.MsgCreateBTCDelegation{ - Signer: bc.mustGetTxSigner(), - BabylonPk: delBabylonPk, + StakerAddr: bc.mustGetTxSigner(), Pop: pop, BtcPk: delBtcPk, FpBtcPkList: fpBtcPks, diff --git a/clientcontroller/interface.go b/clientcontroller/interface.go index 6590e005..cb682f60 100644 --- a/clientcontroller/interface.go +++ b/clientcontroller/interface.go @@ -19,11 +19,10 @@ const ( ) type ClientController interface { - // RegisterFinalityProvider registers a finality provider to the consumer chain - // it returns tx hash and error + // it returns tx hash and error. The address of the finality provider will be + // the signer of the msg. RegisterFinalityProvider( - chainPk []byte, fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, @@ -75,6 +74,7 @@ func NewClientController(chainName string, bbnConfig *fpcfg.BBNConfig, netParams cc ClientController err error ) + switch chainName { case babylonConsumerChainName: cc, err = NewBabylonController(bbnConfig, netParams, logger) diff --git a/docs/finality-provider.md b/docs/finality-provider.md index e25b6f65..2b471832 100644 --- a/docs/finality-provider.md +++ b/docs/finality-provider.md @@ -52,10 +52,12 @@ Below are some important parameters of the `fpd.conf` file. **Note**: The configuration below requires pointing to the path where this keyring is -stored `KeyDirectory`. This `Key` field stores the key name used for interacting with -the consumer chain and will be specified along with the -`KeyringBackend` field in the next [step](#3-add-key-for-the-consumer-chain). So we -can ignore the setting of the two fields in this step. +stored `KeyDirectory`. This `Key` field stores the key name of the finality +provider wallet that is going to be used for interacting with the consumer +chain and to sign the messages of your finality provider. It will be specified +along with the `KeyringBackend` field in the next +[step](#3-add-key-for-the-consumer-chain). So we can ignore the setting of the +two fields in this step. ```bash [Application Options] @@ -66,8 +68,8 @@ EOTSManagerAddress = 127.0.0.1:12582 RpcListener = 127.0.0.1:12581 [babylon] -# Name of the key to sign transactions with -Key = +# Name of the key of the finality provider to sign transactions with +Key = # Chain id of the chain to connect to # Please verify the `ChainID` from the Babylon RPC node https://rpc.testnet3.babylonchain.io/status @@ -98,7 +100,8 @@ GasPrices = 0.002ubbn ## 3. Add key for the consumer chain The finality provider daemon requires the existence of a keyring that contains an -account with Babylon token funds to pay for transactions. This key will be also used +account for the finality provider with Babylon token funds to pay and sign +transactions. This key identifies the finality provider and will be also used to pay for fees of transactions to the consumer chain. Use the following command to add the key: @@ -160,12 +163,12 @@ in [step](#3-add-key-for-the-consumer-chain) will be used. fpcli create-finality-provider --key-name my-finality-provider \ --chain-id bbn-test-3 --moniker my-name { - "babylon_pk_hex": "02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077", - "btc_pk_hex": "d0fc4db48643fbb4339dc4bbf15f272411716b0d60f18bdfeb3861544bf5ef63", - "description": { - "moniker": "my-name" - }, - "status": "CREATED" + "fp_addr": "bbn19khdh5vf8zv9x49f84cfuxx5t45m7klwq827mp", + "btc_pk_hex": "d0fc4db48643fbb4339dc4bbf15f272411716b0d60f18bdfeb3861544bf5ef63", + "description": { + "moniker": "my-name" + }, + "status": "CREATED" } ``` @@ -204,7 +207,7 @@ fpcli list-finality-providers "finality-providers": [ ... { - "babylon_pk_hex": "02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077", + "fp_addr": "bbn19khdh5vf8zv9x49f84cfuxx5t45m7klwq827mp", "btc_pk_hex": "d0fc4db48643fbb4339dc4bbf15f272411716b0d60f18bdfeb3861544bf5ef63", "description": { "moniker": "my-name" @@ -251,12 +254,9 @@ The expected result is a JSON object corresponding to the finality provider info "details": "other overall info" }, "commission": "0.050000000000000000", - "babylon_pk": { - "key": "AtPEagBqVQUL6og0qH+H44pFf9p3WcHAva+zC2+74X8p" - }, + "fp_addr": "bbn19khdh5vf8zv9x49f84cfuxx5t45m7klwq827mp", "btc_pk": "02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077", "pop": { - "babylon_sig": "sAg34vImQTFVlZYsziw9PCCKDuRyZv38V2MX8Ij9fQhyOdpxCUZ1VEgpSlwV/dbnpDs1UOez8Ni9EcbADkmnBA==", "btc_sig": "sHLpEHVTyTp9K55oeHxnPlkV4unc/r1obqzKn5S1gq95oXA3AgL1jyCzd/mGb23RfKbEyABjYUdcIBtZ02l5jg==" }, "master_pub_rand": "xpub661MyMwAqRbcFLhUq9uPM7GncSytVZvoNg4w7LLx1Y74GeeAZerkpV1amvGBTcw4ECmrwFsTNMNf1LFBKkA2pmd8aJ5Jmp8uKD5xgVSezBq", diff --git a/eotsmanager/proto/eotsmanager.pb.go b/eotsmanager/proto/eotsmanager.pb.go index be042366..ea5ae2b6 100644 --- a/eotsmanager/proto/eotsmanager.pb.go +++ b/eotsmanager/proto/eotsmanager.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc (unknown) // source: eotsmanager.proto diff --git a/eotsmanager/proto/eotsmanager_grpc.pb.go b/eotsmanager/proto/eotsmanager_grpc.pb.go index 75b1e5cf..0a8814ad 100644 --- a/eotsmanager/proto/eotsmanager_grpc.pb.go +++ b/eotsmanager/proto/eotsmanager_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: eotsmanager.proto package proto @@ -14,6 +18,15 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + EOTSManager_Ping_FullMethodName = "/proto.EOTSManager/Ping" + EOTSManager_CreateKey_FullMethodName = "/proto.EOTSManager/CreateKey" + EOTSManager_CreateRandomnessPairList_FullMethodName = "/proto.EOTSManager/CreateRandomnessPairList" + EOTSManager_KeyRecord_FullMethodName = "/proto.EOTSManager/KeyRecord" + EOTSManager_SignEOTS_FullMethodName = "/proto.EOTSManager/SignEOTS" + EOTSManager_SignSchnorrSig_FullMethodName = "/proto.EOTSManager/SignSchnorrSig" +) + // EOTSManagerClient is the client API for EOTSManager 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. @@ -41,7 +54,7 @@ func NewEOTSManagerClient(cc grpc.ClientConnInterface) EOTSManagerClient { func (c *eOTSManagerClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { out := new(PingResponse) - err := c.cc.Invoke(ctx, "/proto.EOTSManager/Ping", in, out, opts...) + err := c.cc.Invoke(ctx, EOTSManager_Ping_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -50,7 +63,7 @@ func (c *eOTSManagerClient) Ping(ctx context.Context, in *PingRequest, opts ...g func (c *eOTSManagerClient) CreateKey(ctx context.Context, in *CreateKeyRequest, opts ...grpc.CallOption) (*CreateKeyResponse, error) { out := new(CreateKeyResponse) - err := c.cc.Invoke(ctx, "/proto.EOTSManager/CreateKey", in, out, opts...) + err := c.cc.Invoke(ctx, EOTSManager_CreateKey_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -59,7 +72,7 @@ func (c *eOTSManagerClient) CreateKey(ctx context.Context, in *CreateKeyRequest, func (c *eOTSManagerClient) CreateRandomnessPairList(ctx context.Context, in *CreateRandomnessPairListRequest, opts ...grpc.CallOption) (*CreateRandomnessPairListResponse, error) { out := new(CreateRandomnessPairListResponse) - err := c.cc.Invoke(ctx, "/proto.EOTSManager/CreateRandomnessPairList", in, out, opts...) + err := c.cc.Invoke(ctx, EOTSManager_CreateRandomnessPairList_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -68,7 +81,7 @@ func (c *eOTSManagerClient) CreateRandomnessPairList(ctx context.Context, in *Cr func (c *eOTSManagerClient) KeyRecord(ctx context.Context, in *KeyRecordRequest, opts ...grpc.CallOption) (*KeyRecordResponse, error) { out := new(KeyRecordResponse) - err := c.cc.Invoke(ctx, "/proto.EOTSManager/KeyRecord", in, out, opts...) + err := c.cc.Invoke(ctx, EOTSManager_KeyRecord_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -77,7 +90,7 @@ func (c *eOTSManagerClient) KeyRecord(ctx context.Context, in *KeyRecordRequest, func (c *eOTSManagerClient) SignEOTS(ctx context.Context, in *SignEOTSRequest, opts ...grpc.CallOption) (*SignEOTSResponse, error) { out := new(SignEOTSResponse) - err := c.cc.Invoke(ctx, "/proto.EOTSManager/SignEOTS", in, out, opts...) + err := c.cc.Invoke(ctx, EOTSManager_SignEOTS_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -86,7 +99,7 @@ func (c *eOTSManagerClient) SignEOTS(ctx context.Context, in *SignEOTSRequest, o func (c *eOTSManagerClient) SignSchnorrSig(ctx context.Context, in *SignSchnorrSigRequest, opts ...grpc.CallOption) (*SignSchnorrSigResponse, error) { out := new(SignSchnorrSigResponse) - err := c.cc.Invoke(ctx, "/proto.EOTSManager/SignSchnorrSig", in, out, opts...) + err := c.cc.Invoke(ctx, EOTSManager_SignSchnorrSig_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -156,7 +169,7 @@ func _EOTSManager_Ping_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.EOTSManager/Ping", + FullMethod: EOTSManager_Ping_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).Ping(ctx, req.(*PingRequest)) @@ -174,7 +187,7 @@ func _EOTSManager_CreateKey_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.EOTSManager/CreateKey", + FullMethod: EOTSManager_CreateKey_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).CreateKey(ctx, req.(*CreateKeyRequest)) @@ -192,7 +205,7 @@ func _EOTSManager_CreateRandomnessPairList_Handler(srv interface{}, ctx context. } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.EOTSManager/CreateRandomnessPairList", + FullMethod: EOTSManager_CreateRandomnessPairList_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).CreateRandomnessPairList(ctx, req.(*CreateRandomnessPairListRequest)) @@ -210,7 +223,7 @@ func _EOTSManager_KeyRecord_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.EOTSManager/KeyRecord", + FullMethod: EOTSManager_KeyRecord_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).KeyRecord(ctx, req.(*KeyRecordRequest)) @@ -228,7 +241,7 @@ func _EOTSManager_SignEOTS_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.EOTSManager/SignEOTS", + FullMethod: EOTSManager_SignEOTS_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).SignEOTS(ctx, req.(*SignEOTSRequest)) @@ -246,7 +259,7 @@ func _EOTSManager_SignSchnorrSig_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.EOTSManager/SignSchnorrSig", + FullMethod: EOTSManager_SignSchnorrSig_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(EOTSManagerServer).SignSchnorrSig(ctx, req.(*SignSchnorrSigRequest)) diff --git a/finality-provider/cmd/fpcli/daemon/export.go b/finality-provider/cmd/fpcli/daemon/export.go index a1cb6bf1..dffd3fab 100644 --- a/finality-provider/cmd/fpcli/daemon/export.go +++ b/finality-provider/cmd/fpcli/daemon/export.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/math" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" dc "github.com/babylonchain/finality-provider/finality-provider/service/client" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/x/staking/types" bbn "github.com/babylonchain/babylon/types" @@ -97,17 +96,9 @@ func exportFp(ctx *cli.Context) error { return fmt.Errorf("failed to parse fp commission %s: %w", fpInfo.Commission, err) } - cosmosRawPubKey, err := hex.DecodeString(fpInfo.ChainPkHex) - if err != nil { - return fmt.Errorf("failed to decode chain pk hex %s: %w", fpInfo.ChainPkHex, err) - } - - cosmosPubKey := &secp256k1.PubKey{ - Key: cosmosRawPubKey, - } - desc := fpInfo.Description fp := btcstktypes.FinalityProvider{ + Addr: fpInfo.FpAddr, Description: &types.Description{ Moniker: desc.Moniker, Identity: desc.Identity, @@ -117,7 +108,6 @@ func exportFp(ctx *cli.Context) error { }, Commission: &comm, BtcPk: fpPk, - BabylonPk: cosmosPubKey, Pop: nil, // TODO: fill PoP? } diff --git a/finality-provider/proto/finality_providers.go b/finality-provider/proto/finality_providers.go index 6762ecb4..2b573a88 100644 --- a/finality-provider/proto/finality_providers.go +++ b/finality-provider/proto/finality_providers.go @@ -1,26 +1,14 @@ package proto import ( - "encoding/hex" "fmt" bbn "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func (sfp *FinalityProvider) GetChainPK() *secp256k1.PubKey { - return &secp256k1.PubKey{ - Key: sfp.ChainPk, - } -} - -func (sfp *FinalityProvider) GetChainPkHexString() string { - return hex.EncodeToString(sfp.ChainPk) -} - func (sfp *FinalityProvider) MustGetBTCPK() *btcec.PublicKey { btcPubKey, err := schnorr.ParsePubKey(sfp.BtcPk) if err != nil { @@ -40,8 +28,8 @@ func NewFinalityProviderInfo(sfp *FinalityProvider) (*FinalityProviderInfo, erro return nil, err } return &FinalityProviderInfo{ - ChainPkHex: sfp.GetChainPkHexString(), - BtcPkHex: sfp.MustGetBIP340BTCPK().MarshalHex(), + FpAddr: sfp.FpAddr, + BtcPkHex: sfp.MustGetBIP340BTCPK().MarshalHex(), Description: &Description{ Moniker: des.Moniker, Identity: des.Identity, diff --git a/finality-provider/proto/finality_providers.pb.go b/finality-provider/proto/finality_providers.pb.go index 3446847f..9ec5dd2c 100644 --- a/finality-provider/proto/finality_providers.pb.go +++ b/finality-provider/proto/finality_providers.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc (unknown) // source: finality_providers.proto @@ -741,13 +741,14 @@ func (x *QueryFinalityProviderListResponse) GetFinalityProviders() []*FinalityPr return nil } +// FinalityProvider defines current state of finality provider. type FinalityProvider struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // chain_pk is the chain secp256k1 PK of this finality provider - ChainPk []byte `protobuf:"bytes,1,opt,name=chain_pk,json=chainPk,proto3" json:"chain_pk,omitempty"` + // fp_addr is the bech32 chain address identifier of the finality provider. + FpAddr string `protobuf:"bytes,1,opt,name=fp_addr,json=fpAddr,proto3" json:"fp_addr,omitempty"` // btc_pk is the BTC secp256k1 PK of the finality provider encoded in BIP-340 spec BtcPk []byte `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3" json:"btc_pk,omitempty"` // description defines the description terms for the finality provider @@ -801,11 +802,11 @@ func (*FinalityProvider) Descriptor() ([]byte, []int) { return file_finality_providers_proto_rawDescGZIP(), []int{12} } -func (x *FinalityProvider) GetChainPk() []byte { +func (x *FinalityProvider) GetFpAddr() string { if x != nil { - return x.ChainPk + return x.FpAddr } - return nil + return "" } func (x *FinalityProvider) GetBtcPk() []byte { @@ -877,8 +878,8 @@ type FinalityProviderInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // chain_pk_hex is the hex string of the chain secp256k1 PK of this finality provider - ChainPkHex string `protobuf:"bytes,1,opt,name=chain_pk_hex,json=chainPkHex,proto3" json:"chain_pk_hex,omitempty"` + // fp_addr is the bech32 chain address identifier of the finality provider. + FpAddr string `protobuf:"bytes,1,opt,name=fp_addr,json=fpAddr,proto3" json:"fp_addr,omitempty"` // btc_pk_hex is the hex string of the BTC secp256k1 PK of the finality provider encoded in BIP-340 spec BtcPkHex string `protobuf:"bytes,2,opt,name=btc_pk_hex,json=btcPkHex,proto3" json:"btc_pk_hex,omitempty"` // description defines the description terms for the finality provider @@ -925,9 +926,9 @@ func (*FinalityProviderInfo) Descriptor() ([]byte, []int) { return file_finality_providers_proto_rawDescGZIP(), []int{13} } -func (x *FinalityProviderInfo) GetChainPkHex() string { +func (x *FinalityProviderInfo) GetFpAddr() string { if x != nil { - return x.ChainPkHex + return x.FpAddr } return "" } @@ -1062,11 +1063,9 @@ type ProofOfPossession struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // chain_sig is the signature generated via sign(sk_chain, pk_btc) - ChainSig []byte `protobuf:"bytes,1,opt,name=chain_sig,json=chainSig,proto3" json:"chain_sig,omitempty"` - // btc_sig is the signature generated via sign(sk_btc, chain_sig) + // btc_sig is the signature generated via sign(sk_btc, fp_addr) // the signature follows encoding in BIP-340 spec - BtcSig []byte `protobuf:"bytes,2,opt,name=btc_sig,json=btcSig,proto3" json:"btc_sig,omitempty"` + BtcSig []byte `protobuf:"bytes,1,opt,name=btc_sig,json=btcSig,proto3" json:"btc_sig,omitempty"` } func (x *ProofOfPossession) Reset() { @@ -1101,13 +1100,6 @@ func (*ProofOfPossession) Descriptor() ([]byte, []int) { return file_finality_providers_proto_rawDescGZIP(), []int{15} } -func (x *ProofOfPossession) GetChainSig() []byte { - if x != nil { - return x.ChainSig - } - return nil -} - func (x *ProofOfPossession) GetBtcSig() []byte { if x != nil { return x.BtcSig @@ -1373,145 +1365,146 @@ var file_finality_providers_proto_rawDesc = []byte{ 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xa4, 0x03, 0x0a, 0x10, 0x46, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x6b, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x74, 0x63, 0x5f, - 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x74, 0x63, 0x50, 0x6b, 0x12, - 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x43, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, - 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x03, 0x70, 0x6f, 0x70, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, - 0x6f, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, - 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, - 0xb4, 0x02, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x0a, 0x62, 0x74, - 0x63, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x62, 0x74, 0x63, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, - 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x23, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, - 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, - 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, - 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, - 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x52, - 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0xa2, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, - 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, - 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, - 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x49, 0x0a, 0x11, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x12, 0x17, 0x0a, - 0x07, 0x62, 0x74, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x62, 0x74, 0x63, 0x53, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, - 0x72, 0x52, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x62, - 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, - 0x52, 0x61, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x22, - 0x94, 0x01, 0x0a, 0x1e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, - 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x6d, 0x73, 0x67, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x69, 0x67, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x54, 0x6f, 0x53, 0x69, - 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, - 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x17, 0x0a, - 0x07, 0x68, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x68, 0x64, 0x50, 0x61, 0x74, 0x68, 0x22, 0x3f, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2a, 0xa6, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x1a, - 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x12, 0x1e, 0x0a, 0x0a, - 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0e, 0x8a, 0x9d, - 0x20, 0x0a, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x12, 0x16, 0x0a, 0x06, - 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x41, 0x43, - 0x54, 0x49, 0x56, 0x45, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, - 0x10, 0x03, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, - 0x12, 0x18, 0x0a, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x04, 0x1a, 0x0b, 0x8a, - 0x9d, 0x20, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, - 0x32, 0xc0, 0x05, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x65, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, - 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xbc, 0x03, 0x0a, 0x10, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x31, 0x0a, + 0x07, 0x66, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, + 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x66, 0x70, 0x41, 0x64, 0x64, 0x72, + 0x12, 0x15, 0x0a, 0x06, 0x62, 0x74, 0x63, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x62, 0x74, 0x63, 0x50, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xc8, + 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, + 0x65, 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, + 0x0a, 0x03, 0x70, 0x6f, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, 0x6f, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, + 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x35, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xc5, 0x02, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x31, 0x0a, 0x07, 0x66, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x66, 0x70, 0x41, + 0x64, 0x64, 0x72, 0x12, 0x1c, 0x0a, 0x0a, 0x62, 0x74, 0x63, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x74, 0x63, 0x50, 0x6b, 0x48, 0x65, + 0x78, 0x12, 0x34, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xc8, 0xde, 0x1f, + 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, + 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, + 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, + 0xa2, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, + 0x29, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2c, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, + 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x74, 0x63, + 0x5f, 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x74, 0x63, 0x53, + 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x52, 0x61, 0x6e, + 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x62, 0x5f, 0x72, 0x61, 0x6e, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, + 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x22, 0x94, 0x01, 0x0a, 0x1e, + 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, + 0x0a, 0x0b, 0x6d, 0x73, 0x67, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x54, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x19, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, + 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x64, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x64, 0x50, 0x61, + 0x74, 0x68, 0x22, 0x3f, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x2a, 0xa6, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, + 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x45, 0x47, 0x49, + 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0e, 0x8a, 0x9d, 0x20, 0x0a, 0x52, 0x45, + 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x10, 0x02, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x1a, 0x0c, + 0x8a, 0x9d, 0x20, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x12, 0x18, 0x0a, 0x07, + 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x04, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x53, + 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x32, 0xc0, 0x05, 0x0a, + 0x11, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, + 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x23, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x19, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x17, 0x53, 0x69, 0x67, - 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, - 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, - 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x66, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x62, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, + 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x17, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, + 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, + 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/finality-provider/proto/finality_providers.proto b/finality-provider/proto/finality_providers.proto index ffcab9b4..0b37e545 100644 --- a/finality-provider/proto/finality_providers.proto +++ b/finality-provider/proto/finality_providers.proto @@ -115,9 +115,10 @@ message QueryFinalityProviderListResponse { // TODO add pagination in case the list gets large } +// FinalityProvider defines current state of finality provider. message FinalityProvider { - // chain_pk is the chain secp256k1 PK of this finality provider - bytes chain_pk = 1; + // fp_addr is the bech32 chain address identifier of the finality provider. + string fp_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the BTC secp256k1 PK of the finality provider encoded in BIP-340 spec bytes btc_pk = 2; // description defines the description terms for the finality provider @@ -144,8 +145,8 @@ message FinalityProvider { // FinalityProviderInfo is the basic information of a finality provider mainly for external usage message FinalityProviderInfo { - // chain_pk_hex is the hex string of the chain secp256k1 PK of this finality provider - string chain_pk_hex = 1; + // fp_addr is the bech32 chain address identifier of the finality provider. + string fp_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk_hex is the hex string of the BTC secp256k1 PK of the finality provider encoded in BIP-340 spec string btc_pk_hex = 2; // description defines the description terms for the finality provider @@ -176,11 +177,9 @@ message Description { // secret key and a Bitcoin secp256k1 secret key are held by the same // person message ProofOfPossession { - // chain_sig is the signature generated via sign(sk_chain, pk_btc) - bytes chain_sig = 1; - // btc_sig is the signature generated via sign(sk_btc, chain_sig) + // btc_sig is the signature generated via sign(sk_btc, fp_addr) // the signature follows encoding in BIP-340 spec - bytes btc_sig = 2; + bytes btc_sig = 1; } message SchnorrRandPair { diff --git a/finality-provider/proto/finality_providers_grpc.pb.go b/finality-provider/proto/finality_providers_grpc.pb.go index 6480c381..e2d7bdca 100644 --- a/finality-provider/proto/finality_providers_grpc.pb.go +++ b/finality-provider/proto/finality_providers_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: finality_providers.proto package proto @@ -14,6 +18,16 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + FinalityProviders_GetInfo_FullMethodName = "/proto.FinalityProviders/GetInfo" + FinalityProviders_CreateFinalityProvider_FullMethodName = "/proto.FinalityProviders/CreateFinalityProvider" + FinalityProviders_RegisterFinalityProvider_FullMethodName = "/proto.FinalityProviders/RegisterFinalityProvider" + FinalityProviders_AddFinalitySignature_FullMethodName = "/proto.FinalityProviders/AddFinalitySignature" + FinalityProviders_QueryFinalityProvider_FullMethodName = "/proto.FinalityProviders/QueryFinalityProvider" + FinalityProviders_QueryFinalityProviderList_FullMethodName = "/proto.FinalityProviders/QueryFinalityProviderList" + FinalityProviders_SignMessageFromChainKey_FullMethodName = "/proto.FinalityProviders/SignMessageFromChainKey" +) + // FinalityProvidersClient is the client API for FinalityProviders 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. @@ -46,7 +60,7 @@ func NewFinalityProvidersClient(cc grpc.ClientConnInterface) FinalityProvidersCl func (c *finalityProvidersClient) GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) { out := new(GetInfoResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/GetInfo", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_GetInfo_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -55,7 +69,7 @@ func (c *finalityProvidersClient) GetInfo(ctx context.Context, in *GetInfoReques func (c *finalityProvidersClient) CreateFinalityProvider(ctx context.Context, in *CreateFinalityProviderRequest, opts ...grpc.CallOption) (*CreateFinalityProviderResponse, error) { out := new(CreateFinalityProviderResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/CreateFinalityProvider", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_CreateFinalityProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -64,7 +78,7 @@ func (c *finalityProvidersClient) CreateFinalityProvider(ctx context.Context, in func (c *finalityProvidersClient) RegisterFinalityProvider(ctx context.Context, in *RegisterFinalityProviderRequest, opts ...grpc.CallOption) (*RegisterFinalityProviderResponse, error) { out := new(RegisterFinalityProviderResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/RegisterFinalityProvider", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_RegisterFinalityProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -73,7 +87,7 @@ func (c *finalityProvidersClient) RegisterFinalityProvider(ctx context.Context, func (c *finalityProvidersClient) AddFinalitySignature(ctx context.Context, in *AddFinalitySignatureRequest, opts ...grpc.CallOption) (*AddFinalitySignatureResponse, error) { out := new(AddFinalitySignatureResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/AddFinalitySignature", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_AddFinalitySignature_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -82,7 +96,7 @@ func (c *finalityProvidersClient) AddFinalitySignature(ctx context.Context, in * func (c *finalityProvidersClient) QueryFinalityProvider(ctx context.Context, in *QueryFinalityProviderRequest, opts ...grpc.CallOption) (*QueryFinalityProviderResponse, error) { out := new(QueryFinalityProviderResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/QueryFinalityProvider", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_QueryFinalityProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -91,7 +105,7 @@ func (c *finalityProvidersClient) QueryFinalityProvider(ctx context.Context, in func (c *finalityProvidersClient) QueryFinalityProviderList(ctx context.Context, in *QueryFinalityProviderListRequest, opts ...grpc.CallOption) (*QueryFinalityProviderListResponse, error) { out := new(QueryFinalityProviderListResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/QueryFinalityProviderList", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_QueryFinalityProviderList_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -100,7 +114,7 @@ func (c *finalityProvidersClient) QueryFinalityProviderList(ctx context.Context, func (c *finalityProvidersClient) SignMessageFromChainKey(ctx context.Context, in *SignMessageFromChainKeyRequest, opts ...grpc.CallOption) (*SignMessageFromChainKeyResponse, error) { out := new(SignMessageFromChainKeyResponse) - err := c.cc.Invoke(ctx, "/proto.FinalityProviders/SignMessageFromChainKey", in, out, opts...) + err := c.cc.Invoke(ctx, FinalityProviders_SignMessageFromChainKey_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -178,7 +192,7 @@ func _FinalityProviders_GetInfo_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/GetInfo", + FullMethod: FinalityProviders_GetInfo_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).GetInfo(ctx, req.(*GetInfoRequest)) @@ -196,7 +210,7 @@ func _FinalityProviders_CreateFinalityProvider_Handler(srv interface{}, ctx cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/CreateFinalityProvider", + FullMethod: FinalityProviders_CreateFinalityProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).CreateFinalityProvider(ctx, req.(*CreateFinalityProviderRequest)) @@ -214,7 +228,7 @@ func _FinalityProviders_RegisterFinalityProvider_Handler(srv interface{}, ctx co } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/RegisterFinalityProvider", + FullMethod: FinalityProviders_RegisterFinalityProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).RegisterFinalityProvider(ctx, req.(*RegisterFinalityProviderRequest)) @@ -232,7 +246,7 @@ func _FinalityProviders_AddFinalitySignature_Handler(srv interface{}, ctx contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/AddFinalitySignature", + FullMethod: FinalityProviders_AddFinalitySignature_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).AddFinalitySignature(ctx, req.(*AddFinalitySignatureRequest)) @@ -250,7 +264,7 @@ func _FinalityProviders_QueryFinalityProvider_Handler(srv interface{}, ctx conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/QueryFinalityProvider", + FullMethod: FinalityProviders_QueryFinalityProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).QueryFinalityProvider(ctx, req.(*QueryFinalityProviderRequest)) @@ -268,7 +282,7 @@ func _FinalityProviders_QueryFinalityProviderList_Handler(srv interface{}, ctx c } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/QueryFinalityProviderList", + FullMethod: FinalityProviders_QueryFinalityProviderList_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).QueryFinalityProviderList(ctx, req.(*QueryFinalityProviderListRequest)) @@ -286,7 +300,7 @@ func _FinalityProviders_SignMessageFromChainKey_Handler(srv interface{}, ctx con } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.FinalityProviders/SignMessageFromChainKey", + FullMethod: FinalityProviders_SignMessageFromChainKey_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(FinalityProvidersServer).SignMessageFromChainKey(ctx, req.(*SignMessageFromChainKeyRequest)) diff --git a/finality-provider/service/app.go b/finality-provider/service/app.go index c5c6a971..d0d29093 100644 --- a/finality-provider/service/app.go +++ b/finality-provider/service/app.go @@ -1,7 +1,6 @@ package service import ( - "encoding/hex" "fmt" "strings" "sync" @@ -13,6 +12,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/lightningnetwork/lnd/kvdb" "go.uber.org/zap" @@ -184,14 +184,18 @@ func (app *FinalityProviderApp) RegisterFinalityProvider(fpPkStr string) (*Regis return nil, err } - pop := &bstypes.ProofOfPossession{ - BabylonSig: fp.Pop.ChainSig, + pop := &bstypes.ProofOfPossessionBTC{ BtcSig: btcSig.MustMarshal(), BtcSigType: bstypes.BTCSigType_BIP340, } + fpAddr, err := sdk.AccAddressFromBech32(fp.FPAddr) + if err != nil { + return nil, err + } + request := ®isterFinalityProviderRequest{ - bbnPubKey: fp.ChainPk, + fpAddr: fpAddr, btcPubKey: bbntypes.NewBIP340PubKeyFromBTCPK(fp.BtcPk), pop: pop, description: fp.Description, @@ -359,16 +363,16 @@ func (app *FinalityProviderApp) handleCreateFinalityProviderRequest(req *createF if err != nil { return nil, err } - chainSk, err := kr.GetChainPrivKey(req.passPhrase) + + fpAddr, err := kr.Address(req.passPhrase) if err != nil { // the chain key does not exist, should create the chain key first keyInfo, err := kr.CreateChainKey(req.passPhrase, req.hdPath, "") if err != nil { return nil, fmt.Errorf("failed to create chain key %s: %w", req.keyName, err) } - chainSk = &secp256k1.PrivKey{Key: keyInfo.PrivateKey.Serialize()} + fpAddr = keyInfo.AccAddress } - chainPk := &secp256k1.PubKey{Key: chainSk.PubKey().Bytes()} // 2. create EOTS key fpPkBytes, err := app.eotsManager.CreateKey(req.keyName, req.passPhrase, req.hdPath) @@ -385,19 +389,19 @@ func (app *FinalityProviderApp) handleCreateFinalityProviderRequest(req *createF } // 3. create proof-of-possession - pop, err := kr.CreatePop(fpRecord.PrivKey, req.passPhrase) + pop, err := kr.CreatePop(fpAddr, fpRecord.PrivKey) if err != nil { return nil, fmt.Errorf("failed to create proof-of-possession of the finality-provider: %w", err) } - if err := app.fps.CreateFinalityProvider(chainPk, fpPk.MustToBTCPK(), req.description, req.commission, req.keyName, req.chainID, pop.BabylonSig, pop.BtcSig); err != nil { + if err := app.fps.CreateFinalityProvider(fpAddr, fpPk.MustToBTCPK(), req.description, req.commission, req.keyName, req.chainID, pop.BtcSig); err != nil { return nil, fmt.Errorf("failed to save finality-provider: %w", err) } app.fpManager.metrics.RecordFpStatus(fpPk.MarshalHex(), proto.FinalityProviderStatus_CREATED) app.logger.Info("successfully created a finality-provider", zap.String("btc_pk", fpPk.MarshalHex()), - zap.String("chain_pk", chainPk.String()), + zap.String("addr", fpAddr.String()), zap.String("key_name", req.keyName), ) @@ -445,6 +449,13 @@ func (app *FinalityProviderApp) loadChainKeyring( return kr, chainSk, nil } +// UpdateClientController sets a new client controoller in the App. +// Usefull for testing with multiples PKs with different keys, it needs +// to update who is the signer +func (app *FinalityProviderApp) UpdateClientController(cc clientcontroller.ClientController) { + app.cc = cc +} + // StoreFinalityProvider stores a new finality provider in the fp store. func (app *FinalityProviderApp) StoreFinalityProvider( keyName, passPhrase, hdPath, chainID string, @@ -452,11 +463,14 @@ func (app *FinalityProviderApp) StoreFinalityProvider( commission *sdkmath.LegacyDec, ) (*store.StoredFinalityProvider, error) { // 1. check if the chain key exists - kr, chainSk, err := app.loadChainKeyring(keyName, passPhrase, hdPath) + kr, _, err := app.loadChainKeyring(keyName, passPhrase, hdPath) + if err != nil { + return nil, err + } + fpAddr, err := kr.Address(passPhrase) if err != nil { return nil, err } - chainPk := &secp256k1.PubKey{Key: chainSk.PubKey().Bytes()} // 2. create EOTS key fpPkBytes, err := app.eotsManager.CreateKey(keyName, passPhrase, hdPath) @@ -473,19 +487,19 @@ func (app *FinalityProviderApp) StoreFinalityProvider( } // 3. create proof-of-possession - pop, err := kr.CreatePop(fpRecord.PrivKey, passPhrase) + pop, err := kr.CreatePop(fpAddr, fpRecord.PrivKey) if err != nil { return nil, fmt.Errorf("failed to create proof-of-possession of the finality provider: %w", err) } - if err := app.fps.CreateFinalityProvider(chainPk, fpPk.MustToBTCPK(), description, commission, keyName, chainID, pop.BabylonSig, pop.BtcSig); err != nil { + if err := app.fps.CreateFinalityProvider(fpAddr, fpPk.MustToBTCPK(), description, commission, keyName, chainID, pop.BtcSig); err != nil { return nil, fmt.Errorf("failed to save finality-provider: %w", err) } app.fpManager.metrics.RecordFpStatus(fpPk.MarshalHex(), proto.FinalityProviderStatus_CREATED) app.logger.Info("successfully created a finality-provider", zap.String("btc_pk", fpPk.MarshalHex()), - zap.String("chain_pk", chainPk.String()), + zap.String("fp_addr", fpAddr.String()), zap.String("key_name", keyName), ) @@ -545,9 +559,9 @@ func (app *FinalityProviderApp) eventLoop() { // return to the caller ev.successResponse <- &RegisterFinalityProviderResponse{ - bbnPubKey: ev.bbnPubKey, - btcPubKey: ev.btcPubKey, - TxHash: ev.txHash, + bbnAddress: ev.bbnAddress, + btcPubKey: ev.btcPubKey, + TxHash: ev.txHash, } case <-app.quit: @@ -577,7 +591,6 @@ func (app *FinalityProviderApp) registrationLoop() { continue } res, err := app.cc.RegisterFinalityProvider( - req.bbnPubKey.Key, req.btcPubKey.MustToBTCPK(), popBytes, req.commission, @@ -597,14 +610,14 @@ func (app *FinalityProviderApp) registrationLoop() { app.logger.Info( "successfully registered finality-provider on babylon", zap.String("btc_pk", req.btcPubKey.MarshalHex()), - zap.String("babylon_pk", hex.EncodeToString(req.bbnPubKey.Key)), + zap.String("fp_addr", req.fpAddr.String()), zap.String("txHash", res.TxHash), ) app.finalityProviderRegisteredEventChan <- &finalityProviderRegisteredEvent{ - btcPubKey: req.btcPubKey, - bbnPubKey: req.bbnPubKey, - txHash: res.TxHash, + btcPubKey: req.btcPubKey, + bbnAddress: req.fpAddr, + txHash: res.TxHash, // pass the channel to the event so that we can send the response to the user which requested // the registration successResponse: req.successResponse, diff --git a/finality-provider/service/app_test.go b/finality-provider/service/app_test.go index 5de3e800..a9a3c048 100644 --- a/finality-provider/service/app_test.go +++ b/finality-provider/service/app_test.go @@ -81,8 +81,7 @@ func FuzzRegisterFinalityProvider(f *testing.F) { btcSig := new(bbntypes.BIP340Signature) err = btcSig.Unmarshal(fp.Pop.BtcSig) require.NoError(t, err) - pop := &bstypes.ProofOfPossession{ - BabylonSig: fp.Pop.ChainSig, + pop := &bstypes.ProofOfPossessionBTC{ BtcSig: btcSig.MustMarshal(), BtcSigType: bstypes.BTCSigType_BIP340, } @@ -99,7 +98,6 @@ func FuzzRegisterFinalityProvider(f *testing.F) { txHash := testutil.GenRandomHexStr(r, 32) mockClientController.EXPECT(). RegisterFinalityProvider( - fp.ChainPk.Key, fp.BtcPk, popBytes, testutil.ZeroCommissionRate(), diff --git a/finality-provider/service/fp_instance.go b/finality-provider/service/fp_instance.go index d08bc146..c3eb52ab 100644 --- a/finality-provider/service/fp_instance.go +++ b/finality-provider/service/fp_instance.go @@ -12,7 +12,6 @@ import ( bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ftypes "github.com/babylonchain/babylon/x/finality/types" "github.com/btcsuite/btcd/btcec/v2" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/gogo/protobuf/jsonpb" "go.uber.org/atomic" "go.uber.org/zap" @@ -27,8 +26,7 @@ import ( ) type FinalityProviderInstance struct { - chainPk *secp256k1.PubKey - btcPk *bbntypes.BIP340PubKey + btcPk *bbntypes.BIP340PubKey fpState *fpState pubRandState *pubRandState @@ -80,7 +78,6 @@ func NewFinalityProviderInstance( return &FinalityProviderInstance{ btcPk: bbntypes.NewBIP340PubKeyFromBTCPK(sfp.BtcPk), - chainPk: sfp.ChainPk, fpState: NewFpState(sfp, s), pubRandState: NewPubRandState(prStore), cfg: cfg, diff --git a/finality-provider/service/fp_manager_test.go b/finality-provider/service/fp_manager_test.go index f2641b8a..21015952 100644 --- a/finality-provider/service/fp_manager_test.go +++ b/finality-provider/service/fp_manager_test.go @@ -10,7 +10,6 @@ import ( "github.com/babylonchain/babylon/testutil/datagen" bbntypes "github.com/babylonchain/babylon/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "go.uber.org/zap" @@ -139,20 +138,19 @@ func newFinalityProviderManagerWithRegisteredFp(t *testing.T, r *rand.Rand, cc c require.NoError(t, err) keyInfo, err := kc.CreateChainKey(passphrase, hdPath, "") require.NoError(t, err) - bbnPk := &secp256k1.PubKey{Key: keyInfo.PublicKey.SerializeCompressed()} + fpAddr := keyInfo.AccAddress fpRecord, err := em.KeyRecord(btcPk.MustMarshal(), passphrase) require.NoError(t, err) - pop, err := kc.CreatePop(fpRecord.PrivKey, passphrase) + pop, err := kc.CreatePop(fpAddr, fpRecord.PrivKey) require.NoError(t, err) err = fpStore.CreateFinalityProvider( - bbnPk, + fpAddr, btcPk.MustToBTCPK(), testutil.RandomDescription(r), testutil.ZeroCommissionRate(), keyName, chainID, - pop.BabylonSig, pop.BtcSig, ) require.NoError(t, err) diff --git a/finality-provider/service/fp_store_adapter.go b/finality-provider/service/fp_store_adapter.go index b370b7b8..7016ac75 100644 --- a/finality-provider/service/fp_store_adapter.go +++ b/finality-provider/service/fp_store_adapter.go @@ -7,7 +7,7 @@ import ( bbntypes "github.com/babylonchain/babylon/types" btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "go.uber.org/zap" @@ -31,10 +31,9 @@ type createFinalityProviderRequest struct { } type registerFinalityProviderRequest struct { - bbnPubKey *secp256k1.PubKey - btcPubKey *bbntypes.BIP340PubKey - // TODO we should have our own representation of PoP - pop *btcstakingtypes.ProofOfPossession + fpAddr sdk.AccAddress + btcPubKey *bbntypes.BIP340PubKey + pop *btcstakingtypes.ProofOfPossessionBTC description *stakingtypes.Description commission *sdkmath.LegacyDec errResponse chan error @@ -42,16 +41,16 @@ type registerFinalityProviderRequest struct { } type finalityProviderRegisteredEvent struct { - bbnPubKey *secp256k1.PubKey + bbnAddress sdk.AccAddress btcPubKey *bbntypes.BIP340PubKey txHash string successResponse chan *RegisterFinalityProviderResponse } type RegisterFinalityProviderResponse struct { - bbnPubKey *secp256k1.PubKey - btcPubKey *bbntypes.BIP340PubKey - TxHash string + bbnAddress sdk.AccAddress + btcPubKey *bbntypes.BIP340PubKey + TxHash string } type CreateFinalityProviderResult struct { diff --git a/finality-provider/service/rpcserver.go b/finality-provider/service/rpcserver.go index 877a9dd2..7c97a5d5 100644 --- a/finality-provider/service/rpcserver.go +++ b/finality-provider/service/rpcserver.go @@ -2,7 +2,6 @@ package service import ( "context" - "encoding/hex" "fmt" "sync" "sync/atomic" @@ -125,7 +124,7 @@ func (r *rpcServer) RegisterFinalityProvider(ctx context.Context, req *proto.Reg // the finality-provider instance should be started right after registration if err := r.app.StartHandlingFinalityProvider(txRes.btcPubKey, req.Passphrase); err != nil { - return nil, fmt.Errorf("failed to start the registered finality-provider %s: %w", hex.EncodeToString(txRes.bbnPubKey.Key), err) + return nil, fmt.Errorf("failed to start the registered finality-provider %s: %w", txRes.bbnAddress.String(), err) } return &proto.RegisterFinalityProviderResponse{TxHash: txRes.TxHash}, nil diff --git a/finality-provider/store/fpstore.go b/finality-provider/store/fpstore.go index ea0d7cca..6277a3db 100644 --- a/finality-provider/store/fpstore.go +++ b/finality-provider/store/fpstore.go @@ -7,7 +7,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcwallet/walletdb" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/lightningnetwork/lnd/kvdb" pm "google.golang.org/protobuf/proto" @@ -42,25 +42,24 @@ func (s *FinalityProviderStore) initBuckets() error { } func (s *FinalityProviderStore) CreateFinalityProvider( - chainPk *secp256k1.PubKey, + fpAddr sdk.AccAddress, btcPk *btcec.PublicKey, description *stakingtypes.Description, commission *sdkmath.LegacyDec, keyName, chainId string, - chainSig, btcSig []byte, + btcSig []byte, ) error { desBytes, err := description.Marshal() if err != nil { return fmt.Errorf("invalid description: %w", err) } fp := &proto.FinalityProvider{ - ChainPk: chainPk.Key, + FpAddr: fpAddr.String(), BtcPk: schnorr.SerializePubKey(btcPk), Description: desBytes, Commission: commission.String(), Pop: &proto.ProofOfPossession{ - ChainSig: chainSig, - BtcSig: btcSig, + BtcSig: btcSig, }, KeyName: keyName, ChainId: chainId, diff --git a/finality-provider/store/fpstore_test.go b/finality-provider/store/fpstore_test.go index ada6feb1..1766e356 100644 --- a/finality-provider/store/fpstore_test.go +++ b/finality-provider/store/fpstore_test.go @@ -11,6 +11,7 @@ import ( "github.com/babylonchain/finality-provider/finality-provider/config" fpstore "github.com/babylonchain/finality-provider/finality-provider/store" "github.com/babylonchain/finality-provider/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" ) // FuzzFinalityProvidersStore tests save and list finality providers properly @@ -35,15 +36,17 @@ func FuzzFinalityProvidersStore(f *testing.F) { }() fp := testutil.GenRandomFinalityProvider(r, t) + fpAddr, err := sdk.AccAddressFromBech32(fp.FPAddr) + require.NoError(t, err) + // create the fp for the first time err = vs.CreateFinalityProvider( - fp.ChainPk, + fpAddr, fp.BtcPk, fp.Description, fp.Commission, fp.KeyName, fp.ChainID, - fp.Pop.ChainSig, fp.Pop.BtcSig, ) require.NoError(t, err) @@ -51,13 +54,12 @@ func FuzzFinalityProvidersStore(f *testing.F) { // create same finality provider again // and expect duplicate error err = vs.CreateFinalityProvider( - fp.ChainPk, + fpAddr, fp.BtcPk, fp.Description, fp.Commission, fp.KeyName, fp.ChainID, - fp.Pop.ChainSig, fp.Pop.BtcSig, ) require.ErrorIs(t, err, fpstore.ErrDuplicateFinalityProvider) diff --git a/finality-provider/store/storedfp.go b/finality-provider/store/storedfp.go index 2239c392..9923c353 100644 --- a/finality-provider/store/storedfp.go +++ b/finality-provider/store/storedfp.go @@ -1,21 +1,19 @@ package store import ( - "encoding/hex" "fmt" sdkmath "cosmossdk.io/math" bbn "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/babylonchain/finality-provider/finality-provider/proto" ) type StoredFinalityProvider struct { - ChainPk *secp256k1.PubKey + FPAddr string BtcPk *btcec.PublicKey Description *stakingtypes.Description Commission *sdkmath.LegacyDec @@ -28,7 +26,6 @@ type StoredFinalityProvider struct { } func protoFpToStoredFinalityProvider(fp *proto.FinalityProvider) (*StoredFinalityProvider, error) { - chainPk := &secp256k1.PubKey{Key: fp.ChainPk} btcPk, err := schnorr.ParsePubKey(fp.BtcPk) if err != nil { return nil, fmt.Errorf("invalid BTC public key: %w", err) @@ -45,13 +42,12 @@ func protoFpToStoredFinalityProvider(fp *proto.FinalityProvider) (*StoredFinalit } return &StoredFinalityProvider{ - ChainPk: chainPk, + FPAddr: fp.FpAddr, BtcPk: btcPk, Description: &des, Commission: &commission, Pop: &proto.ProofOfPossession{ - ChainSig: fp.Pop.ChainSig, - BtcSig: fp.Pop.BtcSig, + BtcSig: fp.Pop.BtcSig, }, KeyName: fp.KeyName, ChainID: fp.ChainId, @@ -61,18 +57,14 @@ func protoFpToStoredFinalityProvider(fp *proto.FinalityProvider) (*StoredFinalit }, nil } -func (sfp *StoredFinalityProvider) GetChainPkHexString() string { - return hex.EncodeToString(sfp.ChainPk.Key) -} - func (sfp *StoredFinalityProvider) GetBIP340BTCPK() *bbn.BIP340PubKey { return bbn.NewBIP340PubKeyFromBTCPK(sfp.BtcPk) } func (sfp *StoredFinalityProvider) ToFinalityProviderInfo() *proto.FinalityProviderInfo { return &proto.FinalityProviderInfo{ - ChainPkHex: sfp.GetChainPkHexString(), - BtcPkHex: sfp.GetBIP340BTCPK().MarshalHex(), + FpAddr: sfp.FPAddr, + BtcPkHex: sfp.GetBIP340BTCPK().MarshalHex(), Description: &proto.Description{ Moniker: sfp.Description.Moniker, Identity: sfp.Description.Identity, diff --git a/go.mod b/go.mod index 0227e173..01128534 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 github.com/avast/retry-go/v4 v4.5.1 - github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 - github.com/btcsuite/btcd v0.24.0 + github.com/babylonchain/babylon v0.9.0-rc.2 + github.com/btcsuite/btcd v0.24.2 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcwallet/walletdb v1.4.0 @@ -232,6 +232,7 @@ require ( 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 github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect diff --git a/go.sum b/go.sum index c0bcd9a5..0a705512 100644 --- a/go.sum +++ b/go.sum @@ -281,8 +281,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 h1:3lXL5eQylIUzcZNxCni2lskwLT0Ix6sTyb5a7iBA/eg= -github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020/go.mod h1:YFALTW+Kp/b5jSDoA7Z70RggJjAedlmQTrpdeU8c3hY= +github.com/babylonchain/babylon v0.9.0-rc.2 h1:cnkVdfJgwXEarzQrqJ2otONuEl+Xe22bN6bXyoenBR4= +github.com/babylonchain/babylon v0.9.0-rc.2/go.mod h1:QTjpnEAEReQofIpZikCQXUZxSkdK0TrWAUbgxOSF9yA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -301,8 +301,8 @@ github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13P github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.22.0-beta.0.20220207191057-4dc4ff7963b4/go.mod h1:7alexyj/lHlOtr2PJK7L/+HDJZpcGDn/pAU98r7DY08= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= -github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= -github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= diff --git a/itest/babylon_node_handler.go b/itest/babylon_node_handler.go index f5e63e20..b790fa7d 100644 --- a/itest/babylon_node_handler.go +++ b/itest/babylon_node_handler.go @@ -15,25 +15,27 @@ import ( "github.com/stretchr/testify/require" ) -type babylonNode struct { - cmd *exec.Cmd - pidFile string - dataDir string +type BabylonNode struct { + cmd *exec.Cmd + pidFile string + DataDir string + WalletName string } -func newBabylonNode(dataDir string, cmd *exec.Cmd) *babylonNode { - return &babylonNode{ - dataDir: dataDir, - cmd: cmd, +func newBabylonNode(dataDir, walletName string, cmd *exec.Cmd) *BabylonNode { + return &BabylonNode{ + DataDir: dataDir, + cmd: cmd, + WalletName: walletName, } } -func (n *babylonNode) start() error { +func (n *BabylonNode) start() error { if err := n.cmd.Start(); err != nil { return err } - pid, err := os.Create(filepath.Join(n.dataDir, + pid, err := os.Create(filepath.Join(n.DataDir, fmt.Sprintf("%s.pid", "config"))) if err != nil { return err @@ -51,7 +53,7 @@ func (n *babylonNode) start() error { return nil } -func (n *babylonNode) stop() (err error) { +func (n *BabylonNode) stop() (err error) { if n.cmd == nil || n.cmd.Process == nil { // return if not properly initialized // or error starting the process @@ -68,7 +70,7 @@ func (n *babylonNode) stop() (err error) { return n.cmd.Process.Signal(os.Interrupt) } -func (n *babylonNode) cleanup() error { +func (n *BabylonNode) cleanup() error { if n.pidFile != "" { if err := os.Remove(n.pidFile); err != nil { log.Printf("unable to remove file %s: %v", n.pidFile, @@ -77,7 +79,7 @@ func (n *babylonNode) cleanup() error { } dirs := []string{ - n.dataDir, + n.DataDir, } var err error for _, dir := range dirs { @@ -88,7 +90,7 @@ func (n *babylonNode) cleanup() error { return nil } -func (n *babylonNode) shutdown() error { +func (n *BabylonNode) shutdown() error { if err := n.stop(); err != nil { return err } @@ -99,7 +101,7 @@ func (n *babylonNode) shutdown() error { } type BabylonNodeHandler struct { - babylonNode *babylonNode + BabylonNode *BabylonNode } func NewBabylonNodeHandler(t *testing.T, covenantQuorum int, covenantPks []*types.BIP340PubKey) *BabylonNodeHandler { @@ -112,7 +114,8 @@ func NewBabylonNodeHandler(t *testing.T, covenantQuorum int, covenantPks []*type } }() - nodeDataDir := filepath.Join(testDir, "node0", "babylond") + walletName := "node0" + nodeDataDir := filepath.Join(testDir, walletName, "babylond") slashingAddr := "SZtRT4BySL3o4efdGLh3k7Kny8GAnsBrSW" @@ -157,21 +160,21 @@ func NewBabylonNodeHandler(t *testing.T, covenantQuorum int, covenantPks []*type startCmd.Stdout = f return &BabylonNodeHandler{ - babylonNode: newBabylonNode(testDir, startCmd), + BabylonNode: newBabylonNode(testDir, walletName, startCmd), } } func (w *BabylonNodeHandler) Start() error { - if err := w.babylonNode.start(); err != nil { + if err := w.BabylonNode.start(); err != nil { // try to cleanup after start error, but return original error - _ = w.babylonNode.cleanup() + _ = w.BabylonNode.cleanup() return err } return nil } func (w *BabylonNodeHandler) Stop() error { - if err := w.babylonNode.shutdown(); err != nil { + if err := w.BabylonNode.shutdown(); err != nil { return err } @@ -179,6 +182,34 @@ func (w *BabylonNodeHandler) Stop() error { } func (w *BabylonNodeHandler) GetNodeDataDir() string { - dir := filepath.Join(w.babylonNode.dataDir, "node0", "babylond") + return w.BabylonNode.GetNodeDataDir() +} + +// GetNodeDataDir returns the home path of the babylon node. +func (n *BabylonNode) GetNodeDataDir() string { + dir := filepath.Join(n.DataDir, n.WalletName, "babylond") return dir } + +// TxBankSend send transaction to a address from the node address. +func (n *BabylonNode) TxBankSend(addr, coins string) error { + flags := []string{ + "tx", + "bank", + "send", + n.WalletName, + addr, coins, + "--keyring-backend=test", + fmt.Sprintf("--home=%s", n.GetNodeDataDir()), + "--log_level=debug", + "--chain-id=chain-test", + "-b=sync", "--yes", "--gas-prices=10ubbn", + } + + cmd := exec.Command("babylond", flags...) + _, err := cmd.Output() + if err != nil { + return err + } + return nil +} diff --git a/itest/test_manager.go b/itest/test_manager.go index b1583de1..2c42615a 100644 --- a/itest/test_manager.go +++ b/itest/test_manager.go @@ -19,12 +19,12 @@ import ( btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonchain/finality-provider/clientcontroller" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "go.uber.org/zap" @@ -65,15 +65,14 @@ type TestManager struct { } type TestDelegationData struct { - DelegatorPrivKey *btcec.PrivateKey - DelegatorKey *btcec.PublicKey - DelegatorBabylonPrivKey *secp256k1.PrivKey - DelegatorBabylonKey *secp256k1.PubKey - SlashingTx *bstypes.BTCSlashingTx - StakingTx *wire.MsgTx - StakingTxInfo *btcctypes.TransactionInfo - DelegatorSig *bbntypes.BIP340Signature - FpPks []*btcec.PublicKey + FPAddr sdk.AccAddress + DelegatorPrivKey *btcec.PrivateKey + DelegatorKey *btcec.PublicKey + SlashingTx *bstypes.BTCSlashingTx + StakingTx *wire.MsgTx + StakingTxInfo *btcctypes.TransactionInfo + DelegatorSig *bbntypes.BIP340Signature + FpPks []*btcec.PublicKey SlashingAddr string ChangeAddr string @@ -151,19 +150,34 @@ func (tm *TestManager) WaitForServicesStart(t *testing.T) { func StartManagerWithFinalityProvider(t *testing.T, n int) (*TestManager, []*service.FinalityProviderInstance) { tm := StartManager(t) app := tm.Fpa + cfg := app.GetConfig() + oldKey := cfg.BabylonConfig.Key for i := 0; i < n; i++ { fpName := fpNamePrefix + strconv.Itoa(i) moniker := monikerPrefix + strconv.Itoa(i) commission := sdkmath.LegacyZeroDec() desc := newDescription(moniker) - cfg := app.GetConfig() - _, err := service.CreateChainKey(cfg.BabylonConfig.KeyDirectory, cfg.BabylonConfig.ChainID, fpName, keyring.BackendTest, passphrase, hdPath, "") + + // needs to update key in config to be able to register and sign the creation of the finality provider with the + // same address. + cfg.BabylonConfig.Key = fpName + fpBbnKeyInfo, err := service.CreateChainKey(cfg.BabylonConfig.KeyDirectory, cfg.BabylonConfig.ChainID, cfg.BabylonConfig.Key, cfg.BabylonConfig.KeyringBackend, passphrase, hdPath, "") + require.NoError(t, err) + + cc, err := clientcontroller.NewClientController(cfg.ChainName, cfg.BabylonConfig, &cfg.BTCNetParams, zap.NewNop()) + require.NoError(t, err) + app.UpdateClientController(cc) + + // add some funds for new fp pay for fees '-' + err = tm.BabylonHandler.BabylonNode.TxBankSend(fpBbnKeyInfo.AccAddress.String(), "1000000ubbn") require.NoError(t, err) + res, err := app.CreateFinalityProvider(fpName, chainID, passphrase, hdPath, desc, &commission) require.NoError(t, err) fpPk, err := bbntypes.NewBIP340PubKeyFromHex(res.FpInfo.BtcPkHex) require.NoError(t, err) + _, err = app.RegisterFinalityProvider(fpPk.MarshalHex()) require.NoError(t, err) err = app.StartHandlingFinalityProvider(fpPk, passphrase) @@ -198,6 +212,12 @@ func StartManagerWithFinalityProvider(t *testing.T, n int) (*TestManager, []*ser }, eventuallyWaitTimeOut, eventuallyPollTime) } + // goes back to old key in app + cfg.BabylonConfig.Key = oldKey + cc, err := clientcontroller.NewClientController(cfg.ChainName, cfg.BabylonConfig, &cfg.BTCNetParams, zap.NewNop()) + require.NoError(t, err) + app.UpdateClientController(cc) + fpInsList := app.ListFinalityProviderInstances() require.Equal(t, n, len(fpInsList)) @@ -216,18 +236,6 @@ func (tm *TestManager) Stop(t *testing.T) { tm.EOTSServerHandler.Stop() } -func (tm *TestManager) WaitForFpRegistered(t *testing.T, bbnPk *secp256k1.PubKey) { - require.Eventually(t, func() bool { - queriedFps, err := tm.BBNClient.QueryFinalityProviders() - if err != nil { - return false - } - return len(queriedFps) == 1 && queriedFps[0].BabylonPk.Equals(bbnPk) - }, eventuallyWaitTimeOut, eventuallyPollTime) - - t.Logf("the finality-provider is successfully registered") -} - func (tm *TestManager) WaitForFpPubRandCommitted(t *testing.T, fpIns *service.FinalityProviderInstance) { require.Eventually(t, func() bool { lastCommittedHeight, err := fpIns.GetLastCommittedHeight() @@ -534,12 +542,10 @@ func (tm *TestManager) InsertBTCDelegation(t *testing.T, fpPks []*btcec.PublicKe unbondingTime, ) - // delegator Babylon key pairs - delBabylonPrivKey, delBabylonPubKey, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + stakerAddr := tm.BBNClient.GetKeyAddress() // proof-of-possession - pop, err := bstypes.NewPoP(delBabylonPrivKey, delBtcPrivKey) + pop, err := bstypes.NewPoPBTC(stakerAddr, delBtcPrivKey) require.NoError(t, err) // create and insert BTC headers which include the staking tx to get staking tx info @@ -619,7 +625,6 @@ func (tm *TestManager) InsertBTCDelegation(t *testing.T, fpPks []*btcec.PublicKe // submit the BTC delegation to Babylon _, err = tm.BBNClient.CreateBTCDelegation( - delBabylonPubKey.(*secp256k1.PubKey), bbntypes.NewBIP340PubKeyFromBTCPK(delBtcPubKey), fpPks, pop, @@ -632,24 +637,23 @@ func (tm *TestManager) InsertBTCDelegation(t *testing.T, fpPks []*btcec.PublicKe uint32(unbondingTime), unbondingValue, testUnbondingInfo.SlashingTx, - unbondingSig) + unbondingSig, + ) require.NoError(t, err) t.Log("successfully submitted a BTC delegation") return &TestDelegationData{ - DelegatorPrivKey: delBtcPrivKey, - DelegatorKey: delBtcPubKey, - DelegatorBabylonPrivKey: delBabylonPrivKey.(*secp256k1.PrivKey), - DelegatorBabylonKey: delBabylonPubKey.(*secp256k1.PubKey), - FpPks: fpPks, - StakingTx: testStakingInfo.StakingTx, - SlashingTx: testStakingInfo.SlashingTx, - StakingTxInfo: txInfo, - DelegatorSig: delegatorSig, - SlashingAddr: params.SlashingAddress.String(), - StakingTime: stakingTime, - StakingAmount: stakingAmount, + DelegatorPrivKey: delBtcPrivKey, + DelegatorKey: delBtcPubKey, + FpPks: fpPks, + StakingTx: testStakingInfo.StakingTx, + SlashingTx: testStakingInfo.SlashingTx, + StakingTxInfo: txInfo, + DelegatorSig: delegatorSig, + SlashingAddr: params.SlashingAddress.String(), + StakingTime: stakingTime, + StakingAmount: stakingAmount, } } diff --git a/keyring/keyringcontroller.go b/keyring/keyringcontroller.go index c04224de..9cb6e81d 100644 --- a/keyring/keyringcontroller.go +++ b/keyring/keyringcontroller.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdksecp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/go-bip39" "github.com/babylonchain/finality-provider/types" @@ -121,13 +122,19 @@ func (kc *ChainKeyringController) CreateChainKey(passphrase, hdPath, mnemonic st // CreatePop creates proof-of-possession of Babylon and BTC public keys // the input is the bytes of BTC public key used to sign // this requires both keys created beforehand -func (kc *ChainKeyringController) CreatePop(btcPrivKey *btcec.PrivateKey, passphrase string) (*bstypes.ProofOfPossession, error) { - bbnPrivKey, err := kc.GetChainPrivKey(passphrase) +func (kc *ChainKeyringController) CreatePop(fpAddr sdk.AccAddress, btcPrivKey *btcec.PrivateKey) (*bstypes.ProofOfPossessionBTC, error) { + return bstypes.NewPoPBTC(fpAddr, btcPrivKey) +} + +// Address returns the address from the keyring +func (kc *ChainKeyringController) Address(passphrase string) (sdk.AccAddress, error) { + kc.input.Reset(passphrase) + k, err := kc.kr.Key(kc.fpName) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get address: %w", err) } - return bstypes.NewPoP(bbnPrivKey, btcPrivKey) + return k.GetAddress() } func (kc *ChainKeyringController) GetChainPrivKey(passphrase string) (*sdksecp256k1.PrivKey, error) { diff --git a/keyring/keyringcontroller_test.go b/keyring/keyringcontroller_test.go index 4f654d57..0ec247de 100644 --- a/keyring/keyringcontroller_test.go +++ b/keyring/keyringcontroller_test.go @@ -11,7 +11,6 @@ import ( "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/chaincfg" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/stretchr/testify/require" eotscfg "github.com/babylonchain/finality-provider/eotsmanager/config" @@ -57,12 +56,13 @@ func FuzzCreatePoP(f *testing.F) { require.NoError(t, err) keyInfo, err := kc.CreateChainKey(passphrase, hdPath, "") require.NoError(t, err) - bbnPk := &secp256k1.PubKey{Key: keyInfo.PublicKey.SerializeCompressed()} + + fpAddr := keyInfo.AccAddress fpRecord, err := em.KeyRecord(btcPk.MustMarshal(), passphrase) require.NoError(t, err) - pop, err := kc.CreatePop(fpRecord.PrivKey, passphrase) + pop, err := kc.CreatePop(fpAddr, fpRecord.PrivKey) require.NoError(t, err) - err = pop.Verify(bbnPk, btcPk, &chaincfg.SimNetParams) + err = pop.Verify(fpAddr, btcPk, &chaincfg.SimNetParams) require.NoError(t, err) }) } diff --git a/testutil/datagen.go b/testutil/datagen.go index 6c3982c6..1865b81e 100644 --- a/testutil/datagen.go +++ b/testutil/datagen.go @@ -8,7 +8,7 @@ import ( "github.com/babylonchain/babylon/crypto/eots" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/babylonchain/finality-provider/finality-provider/store" @@ -64,26 +64,24 @@ func GenRandomFinalityProvider(r *rand.Rand, t *testing.T) *store.StoredFinality require.NoError(t, err) bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - // generate Babylon key pair - babylonSK, chainPk, err := datagen.GenRandomSecp256k1KeyPair(r) + fpAddr, err := sdk.AccAddressFromBech32(datagen.GenRandomAccount().Address) require.NoError(t, err) // generate and verify PoP, correct case - pop, err := bstypes.NewPoP(babylonSK, btcSK) + pop, err := bstypes.NewPoPBTC(fpAddr, btcSK) require.NoError(t, err) - err = pop.Verify(chainPk, bip340PK, &chaincfg.SimNetParams) + err = pop.Verify(fpAddr, bip340PK, &chaincfg.SimNetParams) require.NoError(t, err) return &store.StoredFinalityProvider{ + FPAddr: fpAddr.String(), KeyName: GenRandomHexStr(r, 4), ChainID: "chain-test", - ChainPk: &secp256k1.PubKey{Key: chainPk.Bytes()}, BtcPk: bip340PK.MustToBTCPK(), Description: RandomDescription(r), Commission: ZeroCommissionRate(), Pop: &proto.ProofOfPossession{ - ChainSig: pop.BabylonSig, - BtcSig: pop.BtcSig, + BtcSig: pop.BtcSig, }, } } diff --git a/testutil/mocks/babylon.go b/testutil/mocks/babylon.go index 9bec5685..9ee40572 100644 --- a/testutil/mocks/babylon.go +++ b/testutil/mocks/babylon.go @@ -188,18 +188,18 @@ func (mr *MockClientControllerMockRecorder) QueryLatestFinalizedBlocks(count int } // RegisterFinalityProvider mocks base method. -func (m *MockClientController) RegisterFinalityProvider(chainPk []byte, fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, description []byte) (*types0.TxResponse, error) { +func (m *MockClientController) RegisterFinalityProvider(fpPk *btcec.PublicKey, pop []byte, commission *math.LegacyDec, description []byte) (*types0.TxResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterFinalityProvider", chainPk, fpPk, pop, commission, description) + ret := m.ctrl.Call(m, "RegisterFinalityProvider", fpPk, pop, commission, description) ret0, _ := ret[0].(*types0.TxResponse) ret1, _ := ret[1].(error) return ret0, ret1 } // RegisterFinalityProvider indicates an expected call of RegisterFinalityProvider. -func (mr *MockClientControllerMockRecorder) RegisterFinalityProvider(chainPk, fpPk, pop, commission, description interface{}) *gomock.Call { +func (mr *MockClientControllerMockRecorder) RegisterFinalityProvider(fpPk, pop, commission, description interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterFinalityProvider", reflect.TypeOf((*MockClientController)(nil).RegisterFinalityProvider), chainPk, fpPk, pop, commission, description) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterFinalityProvider", reflect.TypeOf((*MockClientController)(nil).RegisterFinalityProvider), fpPk, pop, commission, description) } // SubmitBatchFinalitySigs mocks base method. diff --git a/tools/go.mod b/tools/go.mod index e6d232ad..3f5ca90d 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -4,7 +4,7 @@ go 1.21 toolchain go1.21.4 -require github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 +require github.com/babylonchain/babylon v0.9.0-rc.2 require ( cloud.google.com/go v0.112.0 // indirect @@ -42,7 +42,7 @@ require ( github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d // indirect - github.com/btcsuite/btcd v0.24.0 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect @@ -177,6 +177,7 @@ require ( 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/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect diff --git a/tools/go.sum b/tools/go.sum index cc5875d2..272dbf02 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -268,8 +268,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020 h1:3lXL5eQylIUzcZNxCni2lskwLT0Ix6sTyb5a7iBA/eg= -github.com/babylonchain/babylon v0.8.6-0.20240527005816-ae2182029020/go.mod h1:YFALTW+Kp/b5jSDoA7Z70RggJjAedlmQTrpdeU8c3hY= +github.com/babylonchain/babylon v0.9.0-rc.2 h1:cnkVdfJgwXEarzQrqJ2otONuEl+Xe22bN6bXyoenBR4= +github.com/babylonchain/babylon v0.9.0-rc.2/go.mod h1:QTjpnEAEReQofIpZikCQXUZxSkdK0TrWAUbgxOSF9yA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -287,8 +287,8 @@ github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d/go.mod h1:f1iKL6Z github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= -github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= -github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= From 9766a340f845928fa38c285f03004fd60960ca20 Mon Sep 17 00:00:00 2001 From: bap2pecs <111917526+bap2pecs@users.noreply.github.com> Date: Tue, 2 Jul 2024 07:31:51 -0400 Subject: [PATCH 12/21] chore: improve logs (#456) --- finality-provider/config/config.go | 5 +++-- finality-provider/service/fp_instance.go | 8 +++++++- itest/babylon_node_handler.go | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/finality-provider/config/config.go b/finality-provider/config/config.go index de2e4b84..ed28895e 100644 --- a/finality-provider/config/config.go +++ b/finality-provider/config/config.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/jessevdk/go-flags" + "go.uber.org/zap/zapcore" eotscfg "github.com/babylonchain/finality-provider/eotsmanager/config" "github.com/babylonchain/finality-provider/metrics" @@ -18,7 +19,7 @@ import ( const ( defaultChainName = "babylon" - defaultLogLevel = "info" + defaultLogLevel = zapcore.InfoLevel defaultLogDirname = "logs" defaultLogFilename = "fpd.log" defaultFinalityProviderKeyName = "finality-provider" @@ -91,7 +92,7 @@ func DefaultConfigWithHome(homePath string) Config { pollerCfg := DefaultChainPollerConfig() cfg := Config{ ChainName: defaultChainName, - LogLevel: defaultLogLevel, + LogLevel: defaultLogLevel.String(), DatabaseConfig: DefaultDBConfigWithHomePath(homePath), BabylonConfig: &bbnCfg, PollerConfig: &pollerCfg, diff --git a/finality-provider/service/fp_instance.go b/finality-provider/service/fp_instance.go index c3eb52ab..f3a807d6 100644 --- a/finality-provider/service/fp_instance.go +++ b/finality-provider/service/fp_instance.go @@ -744,7 +744,13 @@ func (fp *FinalityProviderInstance) SubmitFinalitySignature(b *types.BlockInfo) // get inclusion proof proofBytes, err := fp.pubRandState.GetPubRandProof(pubRand) if err != nil { - return nil, fmt.Errorf("failed to get inclusion proof of public randomness: %v", err) + return nil, fmt.Errorf( + "failed to get inclusion proof of public randomness %s for FP %s for block %d: %w", + pubRand.String(), + fp.btcPk.MarshalHex(), + b.Height, + err, + ) } // send finality signature to the consumer chain diff --git a/itest/babylon_node_handler.go b/itest/babylon_node_handler.go index b790fa7d..f479d353 100644 --- a/itest/babylon_node_handler.go +++ b/itest/babylon_node_handler.go @@ -149,6 +149,7 @@ func NewBabylonNodeHandler(t *testing.T, covenantQuorum int, covenantPks []*type f, err := os.Create(filepath.Join(testDir, "babylon.log")) require.NoError(t, err) + t.Logf("babylon log file: %s", f.Name()) startCmd := exec.Command( "babylond", From a2a7b58c1e51b29ae6a9e16f88f192e01598021d Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 4 Jul 2024 08:27:53 -0300 Subject: [PATCH 13/21] feat: add export of `ProofOfPossessionBTC` to `eotsd` (#460) This export of proof of possession is useful for building messages like `MsgCreateFinalityProvider` Add new command `eotsd pop-export [bbn-addr] ... ` --- eotsmanager/cmd/eotsd/daemon/pop.go | 139 ++++++++++++++++++++++ eotsmanager/cmd/eotsd/daemon/pop_test.go | 71 +++++++++++ eotsmanager/cmd/eotsd/daemon/sign_test.go | 2 +- eotsmanager/cmd/eotsd/main.go | 5 +- 4 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 eotsmanager/cmd/eotsd/daemon/pop.go create mode 100644 eotsmanager/cmd/eotsd/daemon/pop_test.go diff --git a/eotsmanager/cmd/eotsd/daemon/pop.go b/eotsmanager/cmd/eotsd/daemon/pop.go new file mode 100644 index 00000000..22242f38 --- /dev/null +++ b/eotsmanager/cmd/eotsd/daemon/pop.go @@ -0,0 +1,139 @@ +package daemon + +import ( + "fmt" + + "github.com/cometbft/cometbft/crypto/tmhash" + sdk "github.com/cosmos/cosmos-sdk/types" + + bbnparams "github.com/babylonchain/babylon/app/params" + bbn "github.com/babylonchain/babylon/types" + btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonchain/finality-provider/eotsmanager" + "github.com/babylonchain/finality-provider/eotsmanager/config" + "github.com/babylonchain/finality-provider/log" + "github.com/urfave/cli" +) + +func init() { + bbnparams.SetAddressPrefixes() +} + +// PoPExport the data for exporting the PoP. +// The PubKeyHex is the public key of the finality provider BTC key to load +// the private key and sign the AddressSiged. +type PoPExport struct { + PubKeyHex string `json:"pub_key_hex"` + PoPHex string `json:"pop_hex"` + BabylonAddress string `json:"babylon_address"` +} + +var ExportPoPCommand = cli.Command{ + Name: "pop-export", + Usage: "Exports the Proof of Possession by signing over the finality provider's Babylon address with the EOTS private key.", + UsageText: "pop-export [bbn-address]", + Description: `Parse the address received as argument, hash it with + sha256 and sign based on the EOTS key associated with the key-name or btc-pk flag. + If the both flags are supplied, btc-pk takes priority. Use the generated signature + to build a Proof of Possession and export it.`, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: homeFlag, + Usage: "Path to the keyring directory", + Value: config.DefaultEOTSDir, + }, + cli.StringFlag{ + Name: keyNameFlag, + Usage: "The name of the key to load private key for signing", + }, + cli.StringFlag{ + Name: fpPkFlag, + Usage: "The public key of the finality-provider to load private key for signing", + }, + cli.StringFlag{ + Name: passphraseFlag, + Usage: "The passphrase used to decrypt the keyring", + Value: defaultPassphrase, + }, + cli.StringFlag{ + Name: keyringBackendFlag, + Usage: "The backend of the keyring", + Value: defaultKeyringBackend, + }, + }, + Action: ExportPoP, +} + +func ExportPoP(ctx *cli.Context) error { + keyName := ctx.String(keyNameFlag) + fpPkStr := ctx.String(fpPkFlag) + passphrase := ctx.String(passphraseFlag) + keyringBackend := ctx.String(keyringBackendFlag) + + args := ctx.Args() + bbnAddressStr := args.First() + bbnAddr, err := sdk.AccAddressFromBech32(bbnAddressStr) + if err != nil { + return fmt.Errorf("invalid argument %s, please provide a valid bbn address as argument, err: %w", bbnAddressStr, err) + } + + if len(fpPkStr) == 0 && len(keyName) == 0 { + return fmt.Errorf("at least one of the flags: %s, %s needs to be informed", keyNameFlag, fpPkFlag) + } + + homePath, err := getHomeFlag(ctx) + if err != nil { + return fmt.Errorf("failed to load home flag: %w", err) + } + + cfg, err := config.LoadConfig(homePath) + if err != nil { + return fmt.Errorf("failed to load config at %s: %w", homePath, err) + } + + logger, err := log.NewRootLoggerWithFile(config.LogFile(homePath), cfg.LogLevel) + if err != nil { + return fmt.Errorf("failed to load the logger") + } + + dbBackend, err := cfg.DatabaseConfig.GetDbBackend() + if err != nil { + return fmt.Errorf("failed to create db backend: %w", err) + } + defer dbBackend.Close() + + eotsManager, err := eotsmanager.NewLocalEOTSManager(homePath, keyringBackend, dbBackend, logger) + if err != nil { + return fmt.Errorf("failed to create EOTS manager: %w", err) + } + + hashOfMsgToSign := tmhash.Sum(bbnAddr.Bytes()) + btcSig, pubKey, err := singMsg(eotsManager, keyName, fpPkStr, passphrase, hashOfMsgToSign) + if err != nil { + return fmt.Errorf("failed to sign address %s: %w", bbnAddr.String(), err) + } + + bip340Sig := bbn.NewBIP340SignatureFromBTCSig(btcSig) + btcSigBz, err := bip340Sig.Marshal() + if err != nil { + return fmt.Errorf("failed to marshal BTC Sig: %w", err) + } + + pop := btcstktypes.ProofOfPossessionBTC{ + BtcSigType: btcstktypes.BTCSigType_BIP340, + BtcSig: btcSigBz, + } + + popHex, err := pop.ToHexStr() + if err != nil { + return fmt.Errorf("failed to marshal pop to hex: %w", err) + } + + printRespJSON(PoPExport{ + PubKeyHex: pubKey.MarshalHex(), + PoPHex: popHex, + BabylonAddress: bbnAddr.String(), + }) + + return nil +} diff --git a/eotsmanager/cmd/eotsd/daemon/pop_test.go b/eotsmanager/cmd/eotsd/daemon/pop_test.go new file mode 100644 index 00000000..6b42b2b3 --- /dev/null +++ b/eotsmanager/cmd/eotsd/daemon/pop_test.go @@ -0,0 +1,71 @@ +package daemon_test + +import ( + "encoding/json" + "fmt" + "math/rand" + "path/filepath" + "testing" + + "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonchain/babylon/types" + btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + dcli "github.com/babylonchain/finality-provider/eotsmanager/cmd/eotsd/daemon" + "github.com/babylonchain/finality-provider/testutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/stretchr/testify/require" + "github.com/urfave/cli" +) + +func FuzzPoPExport(f *testing.F) { + testutil.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + tempDir := t.TempDir() + homeDir := filepath.Join(tempDir, "eots-home") + app := testApp() + + // init config in home folder + hFlag := fmt.Sprintf("--home=%s", homeDir) + err := app.Run([]string{"eotsd", "init", hFlag}) + require.NoError(t, err) + + keyName := testutil.GenRandomHexStr(r, 10) + keyNameFlag := fmt.Sprintf("--key-name=%s", keyName) + + outputKeysAdd := appRunWithOutput(r, t, app, []string{"eotsd", "keys", "add", hFlag, keyNameFlag}) + keyOutJson := searchInTxt(outputKeysAdd, "for recovery):") + + var keyOut dcli.KeyOutput + err = json.Unmarshal([]byte(keyOutJson), &keyOut) + require.NoError(t, err) + + bbnAddr := datagen.GenRandomAccount().GetAddress() + + btcPkFlag := fmt.Sprintf("--btc-pk=%s", keyOut.PubKeyHex) + exportedPoP := appRunPoPExport(r, t, app, []string{bbnAddr.String(), hFlag, btcPkFlag}) + pop, err := btcstktypes.NewPoPBTCFromHex(exportedPoP.PoPHex) + require.NoError(t, err) + + require.NotNil(t, exportedPoP) + require.NoError(t, pop.ValidateBasic()) + + btcPubKey, err := bbn.NewBIP340PubKeyFromHex(exportedPoP.PubKeyHex) + require.NoError(t, err) + require.NoError(t, pop.Verify(bbnAddr, btcPubKey, &chaincfg.SigNetParams)) + }) +} + +func appRunPoPExport(r *rand.Rand, t *testing.T, app *cli.App, arguments []string) dcli.PoPExport { + args := []string{"eotsd", "pop-export"} + args = append(args, arguments...) + outputSign := appRunWithOutput(r, t, app, args) + signatureStr := searchInTxt(outputSign, "") + + var dataSigned dcli.PoPExport + err := json.Unmarshal([]byte(signatureStr), &dataSigned) + require.NoError(t, err) + + return dataSigned +} diff --git a/eotsmanager/cmd/eotsd/daemon/sign_test.go b/eotsmanager/cmd/eotsd/daemon/sign_test.go index f0632c7f..9bfe3c08 100644 --- a/eotsmanager/cmd/eotsd/daemon/sign_test.go +++ b/eotsmanager/cmd/eotsd/daemon/sign_test.go @@ -149,7 +149,7 @@ func writeFpInfoToFile(r *rand.Rand, t *testing.T, fpInfoPath, btcPk string) { func testApp() *cli.App { app := cli.NewApp() app.Name = "eotsd" - app.Commands = append(app.Commands, dcli.StartCommand, dcli.InitCommand, dcli.SignSchnorrSig, dcli.VerifySchnorrSig) + app.Commands = append(app.Commands, dcli.StartCommand, dcli.InitCommand, dcli.SignSchnorrSig, dcli.VerifySchnorrSig, dcli.ExportPoPCommand) app.Commands = append(app.Commands, dcli.KeysCommands...) return app } diff --git a/eotsmanager/cmd/eotsd/main.go b/eotsmanager/cmd/eotsd/main.go index 1b63d197..5e3fba91 100644 --- a/eotsmanager/cmd/eotsd/main.go +++ b/eotsmanager/cmd/eotsd/main.go @@ -18,7 +18,10 @@ func main() { app := cli.NewApp() app.Name = "eotsd" app.Usage = "Extractable One Time Signature Daemon (eotsd)." - app.Commands = append(app.Commands, dcli.StartCommand, dcli.InitCommand, dcli.SignSchnorrSig, dcli.VerifySchnorrSig) + app.Commands = append( + app.Commands, dcli.StartCommand, dcli.InitCommand, dcli.SignSchnorrSig, dcli.VerifySchnorrSig, + dcli.ExportPoPCommand, + ) app.Commands = append(app.Commands, dcli.KeysCommands...) if err := app.Run(os.Args); err != nil { From 151e50721c3f30d14084ec7ab55e2cd534678ba9 Mon Sep 17 00:00:00 2001 From: bap2pecs <111917526+bap2pecs@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:34:11 -0400 Subject: [PATCH 14/21] (cherry-pick) fix: data race in LocalEOTSManager (#479) (#481) --- eotsmanager/localmanager.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eotsmanager/localmanager.go b/eotsmanager/localmanager.go index fe235c84..599517c8 100644 --- a/eotsmanager/localmanager.go +++ b/eotsmanager/localmanager.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" "strings" + "sync" "github.com/babylonchain/finality-provider/metrics" @@ -31,6 +32,7 @@ const ( var _ EOTSManager = &LocalEOTSManager{} type LocalEOTSManager struct { + mu sync.Mutex kr keyring.Keyring es *store.EOTSStore logger *zap.Logger @@ -273,6 +275,8 @@ func (lm *LocalEOTSManager) KeyRecord(fpPk []byte, passphrase string) (*eotstype } func (lm *LocalEOTSManager) getEOTSPrivKey(fpPk []byte, passphrase string) (*btcec.PrivateKey, error) { + lm.mu.Lock() + defer lm.mu.Unlock() keyName, err := lm.es.GetEOTSKeyName(fpPk) if err != nil { return nil, err From fa595d3a6d37ecbebdd8b51045b03b07f5fbc2c6 Mon Sep 17 00:00:00 2001 From: Christina <156356273+cratiu222@users.noreply.github.com> Date: Mon, 8 Jul 2024 04:18:05 +0300 Subject: [PATCH 15/21] Docs improvements (#486) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR corrects several grammatical errors in the documentation and comments, improving readability and clarity. These changes enhance the overall quality of the project’s written content. --- clientcontroller/babylon.go | 2 +- finality-provider/config/babylon.go | 2 +- finality-provider/config/config.go | 2 +- finality-provider/proto/finality_providers.proto | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clientcontroller/babylon.go b/clientcontroller/babylon.go index a058df57..2d3bc489 100644 --- a/clientcontroller/babylon.go +++ b/clientcontroller/babylon.go @@ -74,7 +74,7 @@ func (bc *BabylonController) mustGetTxSigner() string { } func (bc *BabylonController) GetKeyAddress() sdk.AccAddress { - // get key address, retrieves address based on key name which is configured in + // get key address, retrieves address based on the key name which is configured in // cfg *stakercfg.BBNConfig. If this fails, it means we have a misconfiguration problem // and we should panic. // This is checked at the start of BabylonController, so if it fails something is really wrong diff --git a/finality-provider/config/babylon.go b/finality-provider/config/babylon.go index c6eeb69f..3fea0e9c 100644 --- a/finality-provider/config/babylon.go +++ b/finality-provider/config/babylon.go @@ -37,7 +37,7 @@ func DefaultBBNConfig() BBNConfig { GasPrices: "0.002ubbn", Debug: dc.Debug, Timeout: dc.Timeout, - // Setting this to relatively low value, out currnet babylon client (lens) will + // Setting this to relatively low value, out current babylon client (lens) will // block for this amout of time to wait for transaction inclusion in block BlockTimeout: 1 * time.Minute, OutputFormat: dc.OutputFormat, diff --git a/finality-provider/config/config.go b/finality-provider/config/config.go index ed28895e..74e61039 100644 --- a/finality-provider/config/config.go +++ b/finality-provider/config/config.go @@ -175,7 +175,7 @@ func LoadConfig(homePath string) (*Config, error) { } // Validate checks the given configuration to be sane. This makes sure no -// illegal values or combination of values are set. All file system paths are +// illegal values or a combination of values are set. All file system paths are // normalized. The cleaned up config is returned on success. func (cfg *Config) Validate() error { if cfg.EOTSManagerAddress == "" { diff --git a/finality-provider/proto/finality_providers.proto b/finality-provider/proto/finality_providers.proto index 0b37e545..7a0f9be3 100644 --- a/finality-provider/proto/finality_providers.proto +++ b/finality-provider/proto/finality_providers.proto @@ -52,7 +52,7 @@ message CreateFinalityProviderRequest { string passphrase = 2; // hd_path is the hd path for private key derivation string hd_path = 3; - // chain_id is the identifier of the consumer chain that the finality provider connected to + // chain_id is the identifier of the consumer chain that the finality provider is connected to string chain_id = 4; // description defines the description terms for the finality provider bytes description = 5; @@ -231,4 +231,4 @@ message SignMessageFromChainKeyRequest { // SignMessageFromChainKeyResponse contains the signed message from the chain keyring. message SignMessageFromChainKeyResponse { bytes signature = 1; -} \ No newline at end of file +} From 4206b122349490fdee152648d96166f9e5f4a3d0 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Wed, 10 Jul 2024 10:58:30 -0300 Subject: [PATCH 16/21] chore: fpd to use cobra CLI (#490) Update to use `"github.com/spf13/cobra"` as CLI command in `fpd` Add `keys` subcommand imported from cosmos sdk --- docs/finality-provider.md | 5 +- finality-provider/cmd/fpd/daemon/flags.go | 20 +-- finality-provider/cmd/fpd/daemon/init.go | 51 ++++--- finality-provider/cmd/fpd/daemon/keys.go | 167 ++++++---------------- finality-provider/cmd/fpd/daemon/start.go | 82 ++++++----- finality-provider/cmd/fpd/main.go | 66 +++++++-- go.mod | 4 +- go.sum | 4 + 8 files changed, 182 insertions(+), 217 deletions(-) diff --git a/docs/finality-provider.md b/docs/finality-provider.md index 2b471832..40ae9538 100644 --- a/docs/finality-provider.md +++ b/docs/finality-provider.md @@ -107,12 +107,9 @@ to pay for fees of transactions to the consumer chain. Use the following command to add the key: ```bash -fpd keys add --key-name my-finality-provider --chain-id bbn-test-3 +fpd keys add my-finality-provider ``` -**Note**: Please verify the `chain-id` from the Babylon RPC -node https://rpc.testnet3.babylonchain.io/status - After executing the above command, the key name will be saved in the config file created in [step](#2-configuration). diff --git a/finality-provider/cmd/fpd/daemon/flags.go b/finality-provider/cmd/fpd/daemon/flags.go index 30e9fa4a..dc5bc4be 100644 --- a/finality-provider/cmd/fpd/daemon/flags.go +++ b/finality-provider/cmd/fpd/daemon/flags.go @@ -1,20 +1,8 @@ package daemon -import "github.com/cosmos/cosmos-sdk/crypto/keyring" - const ( - homeFlag = "home" - forceFlag = "force" - passphraseFlag = "passphrase" - fpPkFlag = "btc-pk" - keyNameFlag = "key-name" - hdPathFlag = "hd-path" - chainIdFlag = "chain-id" - keyringBackendFlag = "keyring-backend" - rpcListenerFlag = "rpc-listener" - recoverFlag = "recover" - - defaultKeyringBackend = keyring.BackendTest - defaultHdPath = "" - defaultPassphrase = "" + forceFlag = "force" + passphraseFlag = "passphrase" + fpPkFlag = "btc-pk" + rpcListenerFlag = "rpc-listener" ) diff --git a/finality-provider/cmd/fpd/daemon/init.go b/finality-provider/cmd/fpd/daemon/init.go index 5c95330b..3cf2e947 100644 --- a/finality-provider/cmd/fpd/daemon/init.go +++ b/finality-provider/cmd/fpd/daemon/init.go @@ -4,39 +4,48 @@ import ( "fmt" "path/filepath" + "github.com/cosmos/cosmos-sdk/client" "github.com/jessevdk/go-flags" - "github.com/urfave/cli" + "github.com/spf13/cobra" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" "github.com/babylonchain/finality-provider/util" ) -var InitCommand = cli.Command{ - Name: "init", - Usage: "Initialize a finality-provider home directory.", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: homeFlag, - Usage: "Path to where the home directory will be initialized", - Value: fpcfg.DefaultFpdDir, - }, - cli.BoolFlag{ - Name: forceFlag, - Usage: "Override existing configuration", - Required: false, - }, - }, - Action: initHome, +// CommandInit returns the init command of fpd daemon that starts the config dir. +func CommandInit() *cobra.Command { + var cmd = &cobra.Command{ + Use: "init", + Short: "Initialize a finality-provider home directory.", + Long: `Creates a new finality-provider home directory with default config`, + Example: `fpd init --home /home/user/.fpd --force`, + Args: cobra.NoArgs, + RunE: runInitCmdPrepare, + } + cmd.Flags().Bool(forceFlag, false, "Override existing configuration") + return cmd +} + +func runInitCmdPrepare(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + return runInitCmd(clientCtx, cmd, args) } -func initHome(c *cli.Context) error { - homePath, err := filepath.Abs(c.String(homeFlag)) +func runInitCmd(ctx client.Context, cmd *cobra.Command, args []string) error { + homePath, err := filepath.Abs(ctx.HomeDir) if err != nil { return err } - // Create home directory + homePath = util.CleanAndExpandPath(homePath) - force := c.Bool(forceFlag) + force, err := cmd.Flags().GetBool(forceFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpPkFlag, err) + } if util.FileExists(homePath) && !force { return fmt.Errorf("home path %s already exists", homePath) diff --git a/finality-provider/cmd/fpd/daemon/keys.go b/finality-provider/cmd/fpd/daemon/keys.go index 3deb0850..25dd2010 100644 --- a/finality-provider/cmd/fpd/daemon/keys.go +++ b/finality-provider/cmd/fpd/daemon/keys.go @@ -1,146 +1,61 @@ package daemon import ( - "bufio" - "encoding/json" - "errors" - "fmt" - "os" - - "github.com/cosmos/cosmos-sdk/client/input" - "github.com/cosmos/go-bip39" - "github.com/jessevdk/go-flags" - "github.com/urfave/cli" + "strings" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" - "github.com/babylonchain/finality-provider/finality-provider/service" + "github.com/cosmos/cosmos-sdk/client" + sdkflags "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" + goflags "github.com/jessevdk/go-flags" + "github.com/spf13/cobra" ) -type KeyOutput struct { - Name string `json:"name" yaml:"name"` - Address string `json:"address" yaml:"address"` - Mnemonic string `json:"mnemonic,omitempty" yaml:"mnemonic"` -} - -var KeysCommands = []cli.Command{ - { - Name: "keys", - Usage: "Command sets of managing keys for interacting with the consumer chain.", - Category: "Key management", - Subcommands: []cli.Command{ - AddKeyCmd, - }, - }, -} - -var AddKeyCmd = cli.Command{ - Name: "add", - Usage: "Add a key to the consumer chain's keyring. Note that this will change the config file in place.", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: homeFlag, - Usage: "Path to the keyring directory", - Value: fpcfg.DefaultFpdDir, - }, - cli.StringFlag{ - Name: keyNameFlag, - Required: true, - }, - cli.StringFlag{ - Name: chainIdFlag, - Usage: "The identifier of the consumer chain", - Required: true, - }, - cli.StringFlag{ - Name: keyringBackendFlag, - Usage: "Select keyring's backend", - Value: defaultKeyringBackend, - }, - cli.StringFlag{ - Name: passphraseFlag, - Usage: "The pass phrase used to encrypt the keys", - Value: defaultPassphrase, - }, - cli.StringFlag{ - Name: hdPathFlag, - Usage: "The hd path used to derive the private key", - Value: defaultHdPath, - }, - cli.BoolFlag{ - Name: recoverFlag, - Usage: "Provide seed phrase to recover existing key instead of creating", - }, - }, - Action: addKey, -} - -func addKey(ctx *cli.Context) error { - homePath := ctx.String(homeFlag) - chainID := ctx.String(chainIdFlag) - keyName := ctx.String(keyNameFlag) - backend := ctx.String(keyringBackendFlag) - passphrase := ctx.String(passphraseFlag) - hdPath := ctx.String(hdPathFlag) - keyBackend := ctx.String(keyringBackendFlag) - - var ( - mnemonic string - err error - ) +// CommandKeys returns the keys group command and updates the add command to do a +// post run action to update the config if exists. +func CommandKeys() *cobra.Command { + keysCmd := keys.Commands() + keyAddCmd := GetSubCommand(keysCmd, "add") + if keyAddCmd == nil { + panic("failed to find keys add command") + } - if ctx.Bool(recoverFlag) { - reader := bufio.NewReader(os.Stdin) - mnemonic, err = input.GetString("Enter your mnemonic", reader) + // add command + keyAddCmd.PostRunE = func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { - return fmt.Errorf("failed to read mnemonic from stdin: %w", err) + return err } - if !bip39.IsMnemonicValid(mnemonic) { - return errors.New("invalid mnemonic") + + // check the config file exists + cfg, err := fpcfg.LoadConfig(clientCtx.HomeDir) + if err != nil { + return nil // config does not exist, so does not update it } - } - keyInfo, err := service.CreateChainKey( - homePath, - chainID, - keyName, - backend, - passphrase, - hdPath, - mnemonic, - ) - if err != nil { - return fmt.Errorf("failed to create the chain key: %w", err) - } + keyringBackend, err := cmd.Flags().GetString(sdkflags.FlagKeyringBackend) + if err != nil { + return err + } - printRespJSON( - KeyOutput{ - Name: keyName, - Address: keyInfo.AccAddress.String(), - Mnemonic: keyInfo.Mnemonic, - }, - ) + // write the updated config into the config file + cfg.BabylonConfig.Key = args[0] + cfg.BabylonConfig.KeyringBackend = keyringBackend + fileParser := goflags.NewParser(cfg, goflags.Default) - // check the config file exists - cfg, err := fpcfg.LoadConfig(homePath) - if err != nil { - return nil // config does not exist, so does not update it + return goflags.NewIniParser(fileParser).WriteFile(fpcfg.ConfigFile(clientCtx.HomeDir), goflags.IniIncludeComments|goflags.IniIncludeDefaults) } - // write the updated config into the config file - cfg.BabylonConfig.Key = keyName - cfg.BabylonConfig.KeyringBackend = keyBackend - fileParser := flags.NewParser(cfg, flags.Default) - - return flags.NewIniParser(fileParser).WriteFile(fpcfg.ConfigFile(homePath), flags.IniIncludeComments|flags.IniIncludeDefaults) + return keysCmd } -func printRespJSON(resp interface{}) { - jsonBytes, err := json.MarshalIndent(resp, "", " ") - if err != nil { - fmt.Println("unable to decode response: ", err) - return +// GetSubCommand retuns the command if it finds, otherwise it returns nil +func GetSubCommand(cmd *cobra.Command, commandName string) *cobra.Command { + for _, c := range cmd.Commands() { + if !strings.EqualFold(c.Name(), commandName) { + continue + } + return c } - - fmt.Printf("New key for the consumer chain is created "+ - "(mnemonic should be kept in a safe place for recovery):\n%s\n", jsonBytes) + return nil } diff --git a/finality-provider/cmd/fpd/daemon/start.go b/finality-provider/cmd/fpd/daemon/start.go index a2820571..6e60d6c1 100644 --- a/finality-provider/cmd/fpd/daemon/start.go +++ b/finality-provider/cmd/fpd/daemon/start.go @@ -7,8 +7,9 @@ import ( "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcwallet/walletdb" + "github.com/cosmos/cosmos-sdk/client" "github.com/lightningnetwork/lnd/signal" - "github.com/urfave/cli" + "github.com/spf13/cobra" "go.uber.org/zap" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" @@ -17,40 +18,53 @@ import ( "github.com/babylonchain/finality-provider/util" ) -var StartCommand = cli.Command{ - Name: "start", - Usage: "Start the finality-provider app", - Description: "Start the finality-provider app. Note that eotsd should be started beforehand", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: passphraseFlag, - Usage: "The pass phrase used to decrypt the private key", - Value: defaultPassphrase, - }, - cli.StringFlag{ - Name: homeFlag, - Usage: "The path to the finality-provider home directory", - Value: fpcfg.DefaultFpdDir, - }, - cli.StringFlag{ - Name: fpPkFlag, - Usage: "The public key of the finality-provider to start", - }, - cli.StringFlag{ - Name: rpcListenerFlag, - Usage: "The address that the RPC server listens to", - }, - }, - Action: start, +// CommandStart returns the start command of fpd daemon. +func CommandStart() *cobra.Command { + var cmd = &cobra.Command{ + Use: "start", + Short: "Start the finality-provider app daemon.", + Long: `Start the finality-provider app. Note that eotsd should be started beforehand`, + Example: `fpd start --home /home/user/.fpd`, + Args: cobra.NoArgs, + RunE: runStartCmdPrepare, + } + cmd.Flags().String(fpPkFlag, "", "The public key of the finality-provider to start") + cmd.Flags().String(passphraseFlag, "", "The pass phrase used to decrypt the private key") + cmd.Flags().String(rpcListenerFlag, "", "The address that the RPC server listens to") + return cmd +} + +func runStartCmdPrepare(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + return runStartCmd(clientCtx, cmd, args) } -func start(ctx *cli.Context) error { - homePath, err := filepath.Abs(ctx.String(homeFlag)) +func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { + homePath, err := filepath.Abs(ctx.HomeDir) if err != nil { return err } homePath = util.CleanAndExpandPath(homePath) - rpcListener := ctx.String(rpcListenerFlag) + flags := cmd.Flags() + + fpStr, err := flags.GetString(fpPkFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpPkFlag, err) + } + + rpcListener, err := flags.GetString(rpcListenerFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", rpcListenerFlag, err) + } + + passphrase, err := flags.GetString(passphraseFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", passphraseFlag, err) + } cfg, err := fpcfg.LoadConfig(homePath) if err != nil { @@ -75,12 +89,12 @@ func start(ctx *cli.Context) error { return fmt.Errorf("failed to create db backend: %w", err) } - fpApp, err := loadApp(ctx, logger, cfg, dbBackend) + fpApp, err := loadApp(logger, cfg, dbBackend) if err != nil { return fmt.Errorf("failed to load app: %w", err) } - if err := startApp(ctx, fpApp); err != nil { + if err := startApp(fpApp, fpStr, passphrase); err != nil { return fmt.Errorf("failed to start app: %w", err) } @@ -96,7 +110,6 @@ func start(ctx *cli.Context) error { // loadApp initialize an finality provider app based on config and flags set. func loadApp( - ctx *cli.Context, logger *zap.Logger, cfg *fpcfg.Config, dbBackend walletdb.DB, @@ -116,8 +129,8 @@ func loadApp( // startApp starts the app and the handle of finality providers if needed based on flags. func startApp( - ctx *cli.Context, fpApp *service.FinalityProviderApp, + fpPkStr, passphrase string, ) error { // only start the app without starting any finality-provider instance // as there might be no finality-provider registered yet @@ -125,7 +138,6 @@ func startApp( return fmt.Errorf("failed to start the finality-provider app: %w", err) } - fpPkStr := ctx.String(fpPkFlag) if fpPkStr != "" { // start the finality-provider instance with the given public key fpPk, err := types.NewBIP340PubKeyFromHex(fpPkStr) @@ -133,7 +145,7 @@ func startApp( return fmt.Errorf("invalid finality-provider public key %s: %w", fpPkStr, err) } - if err := fpApp.StartHandlingFinalityProvider(fpPk, ctx.String(passphraseFlag)); err != nil { + if err := fpApp.StartHandlingFinalityProvider(fpPk, passphrase); err != nil { return fmt.Errorf("failed to start the finality-provider instance %s: %w", fpPkStr, err) } } diff --git a/finality-provider/cmd/fpd/main.go b/finality-provider/cmd/fpd/main.go index 71d166da..d8260e56 100644 --- a/finality-provider/cmd/fpd/main.go +++ b/finality-provider/cmd/fpd/main.go @@ -4,23 +4,63 @@ import ( "fmt" "os" - dcli "github.com/babylonchain/finality-provider/finality-provider/cmd/fpd/daemon" - "github.com/urfave/cli" + "github.com/babylonchain/babylon/app" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" + + "github.com/babylonchain/finality-provider/finality-provider/cmd/fpd/daemon" + fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" ) -func fatal(err error) { - fmt.Fprintf(os.Stderr, "[btc-finality-provider] %v\n", err) - os.Exit(1) +// NewRootCmd creates a new root command for fpd. It is called once in the main function. +func NewRootCmd() *cobra.Command { + var ( + clientCtx client.Context + ) + + rootCmd := &cobra.Command{ + Use: "fpd", + Short: "fpd - Finality Provider Daemon (fpd).", + Long: `fpd is the daemon to create and manage finality providers.`, + SilenceErrors: false, + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { + // TODO(verify): if it uses the default encoding config it fails to list keys! output: + // "xx" is not a valid name or address: unable to unmarshal item.Data: + // Bytes left over in UnmarshalBinaryLengthPrefixed, should read 10 more bytes but have 154 + // [cosmos/cosmos-sdk@v0.50.6/crypto/keyring/keyring.go:973 + tempApp := app.NewTmpBabylonApp() + + clientCtx = clientCtx. + WithCodec(tempApp.AppCodec()). + WithInterfaceRegistry(tempApp.InterfaceRegistry()). + WithTxConfig(tempApp.TxConfig()). + WithLegacyAmino(tempApp.LegacyAmino()). + WithInput(os.Stdin) + + // set the default command outputs + cmd.SetOut(cmd.OutOrStdout()) + cmd.SetErr(cmd.ErrOrStderr()) + + clientCtx = clientCtx.WithCmdContext(cmd.Context()) + if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { + return err + } + + return nil + }, + } + rootCmd.PersistentFlags().String(flags.FlagHome, fpcfg.DefaultFpdDir, "The application home directory") + + return rootCmd } func main() { - app := cli.NewApp() - app.Name = "fpd" - app.Usage = "Finality Provider Daemon (fpd)." - app.Commands = append(app.Commands, dcli.StartCommand, dcli.InitCommand) - app.Commands = append(app.Commands, dcli.KeysCommands...) - - if err := app.Run(os.Args); err != nil { - fatal(err) + cmd := NewRootCmd() + cmd.AddCommand(daemon.CommandKeys(), daemon.CommandStart(), daemon.CommandInit()) + + if err := cmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Whoops. There was an error while executing your fpd CLI '%s'", err) + os.Exit(1) } } diff --git a/go.mod b/go.mod index 01128534..c6217a66 100644 --- a/go.mod +++ b/go.mod @@ -95,7 +95,7 @@ require ( github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect 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 @@ -228,7 +228,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/cobra v1.8.1 // 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 diff --git a/go.sum b/go.sum index 0a705512..398c2cc8 100644 --- a/go.sum +++ b/go.sum @@ -440,6 +440,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/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= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= @@ -1209,6 +1211,8 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= From 8cc98212b5b33ce44938a31df7a05a8583c551ba Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 15 Jul 2024 13:18:15 -0300 Subject: [PATCH 17/21] chore: migrate fpcli to cobra CLI (#493) - move `fpcli` subcommands to `fpd` - use `cobra` instead of `urfave` - update docs - Branched out from #490 (should be merged after) --- Dockerfile | 1 - README.md | 3 +- docs/finality-provider.md | 20 +- finality-provider/cmd/cmd.go | 52 +++ .../cmd/fpcli/daemon/daemoncmd.go | 394 ------------------ finality-provider/cmd/fpcli/daemon/flags.go | 24 -- finality-provider/cmd/fpcli/main.go | 34 -- .../cmd/fpd/daemon/daemon_commands.go | 393 +++++++++++++++++ .../cmd/{fpcli => fpd}/daemon/export.go | 104 ++--- finality-provider/cmd/fpd/daemon/flags.go | 22 +- finality-provider/cmd/fpd/daemon/init.go | 12 +- finality-provider/cmd/fpd/daemon/keys.go | 15 +- finality-provider/cmd/fpd/daemon/start.go | 12 +- finality-provider/cmd/fpd/main.go | 47 +-- finality-provider/service/client/rpcclient.go | 5 +- 15 files changed, 550 insertions(+), 588 deletions(-) create mode 100644 finality-provider/cmd/cmd.go delete mode 100644 finality-provider/cmd/fpcli/daemon/daemoncmd.go delete mode 100644 finality-provider/cmd/fpcli/daemon/flags.go delete mode 100644 finality-provider/cmd/fpcli/main.go create mode 100644 finality-provider/cmd/fpd/daemon/daemon_commands.go rename finality-provider/cmd/{fpcli => fpd}/daemon/export.go (56%) diff --git a/Dockerfile b/Dockerfile index 6f9899cc..a54bf816 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,6 @@ RUN addgroup --gid 1138 -S finality-provider && adduser --uid 1138 -S finality-p RUN apk add bash curl jq COPY --from=builder /go/src/github.com/babylonchain/finality-provider/build/fpd /bin/fpd -COPY --from=builder /go/src/github.com/babylonchain/finality-provider/build/fpcli /bin/fpcli COPY --from=builder /go/src/github.com/babylonchain/finality-provider/build/eotsd /bin/eotsd WORKDIR /home/finality-provider diff --git a/README.md b/README.md index 5403c0f8..76e294a0 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,7 @@ The above command will build and install the following binaries to `$GOPATH/bin`: - `eotsd`: The daemon program for the EOTS manager. -- `fpd`: The daemon program for the finality-provider. -- `fpcli`: The CLI tool for interacting with the finality-provider daemon. +- `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 diff --git a/docs/finality-provider.md b/docs/finality-provider.md index 40ae9538..6c8e725f 100644 --- a/docs/finality-provider.md +++ b/docs/finality-provider.md @@ -20,8 +20,8 @@ providers: finality votes for each block each maintained finality provider has committed to vote for. -The daemon is controlled by the `fpd` tool. The `fpcli` tool implements commands for -interacting with the daemon. +The daemon is controlled by the `fpd` tool, which has overall commands for +interacting with the running daemon. ## 2. Configuration @@ -150,14 +150,14 @@ can also be set in the configuration file. ## 5. Create and Register a Finality Provider We create a finality provider instance through the -`fpcli create-finality-provider` or `fpcli cfp` command. The created instance is +`fpd create-finality-provider` or `fpd cfp` command. The created instance is associated with a BTC public key which serves as its unique identifier and a Babylon account to which staking rewards will be directed. Note that if the `--key-name` flag is not specified, the `Key` field of config specified in [step](#3-add-key-for-the-consumer-chain) will be used. ```bash -fpcli create-finality-provider --key-name my-finality-provider \ +fpd create-finality-provider --key-name my-finality-provider \ --chain-id bbn-test-3 --moniker my-name { "fp_addr": "bbn19khdh5vf8zv9x49f84cfuxx5t45m7klwq827mp", @@ -170,11 +170,11 @@ fpcli create-finality-provider --key-name my-finality-provider \ ``` We register a created finality provider in Babylon through -the `fpcli register-finality-provider` or `fpcli rfp` command. The output contains +the `fpd register-finality-provider` or `fpd rfp` command. The output contains the hash of the Babylon finality provider registration transaction. ```bash -fpcli register-finality-provider \ +fpd register-finality-provider \ --btc-pk d0fc4db48643fbb4339dc4bbf15f272411716b0d60f18bdfeb3861544bf5ef63 { "tx_hash": "800AE5BBDADE974C5FA5BD44336C7F1A952FAB9F5F9B43F7D4850BA449319BAA" @@ -186,7 +186,7 @@ A finality provider instance will be initiated and start running right after the finality provider is successfully registered in Babylon. We can view the status of all the running finality providers through -the `fpcli list-finality-providers` or `fpcli ls` command. The `status` field can +the `fpd list-finality-providers` or `fpd ls` command. The `status` field can receive the following values: - `CREATED`: The finality provider is created but not registered yet @@ -199,7 +199,7 @@ receive the following values: - `SLASHED`: The finality provider is slashed due to malicious behavior ```bash -fpcli list-finality-providers +fpd list-finality-providers { "finality-providers": [ ... @@ -217,7 +217,7 @@ fpcli list-finality-providers ``` After the creation of the finality provider in the local db, it is possible -to export the finality provider information through the `fpcli export-finality-provider` command. +to export the finality provider information through the `fpd export-finality-provider` command. This command connects with the `fpd` daemon to retrieve the finality provider previously created using the flag `--btc-pk` as key. @@ -235,7 +235,7 @@ passphrase is required. - `--hd-path` the hd derivation path of the private key. ```shell -$ fpcli export-finality-provider --btc-pk 02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077 \ +$ fpd export-finality-provider --btc-pk 02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077 \ --home ./export-fp/fpd --key-name finality-provider --signed ``` diff --git a/finality-provider/cmd/cmd.go b/finality-provider/cmd/cmd.go new file mode 100644 index 00000000..c4e513d2 --- /dev/null +++ b/finality-provider/cmd/cmd.go @@ -0,0 +1,52 @@ +package cmd + +import ( + "os" + + "github.com/babylonchain/babylon/app" + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" +) + +// PersistClientCtx persist some vars from the cmd to the client context. +func PersistClientCtx(clientCtx client.Context) func(cmd *cobra.Command, _ []string) error { + return func(cmd *cobra.Command, _ []string) error { + // TODO(verify): if it uses the default encoding config it fails to list keys! output: + // "xx" is not a valid name or address: unable to unmarshal item.Data: + // Bytes left over in UnmarshalBinaryLengthPrefixed, should read 10 more bytes but have 154 + // [cosmos/cosmos-sdk@v0.50.6/crypto/keyring/keyring.go:973 + tempApp := app.NewTmpBabylonApp() + + clientCtx = clientCtx. + WithCodec(tempApp.AppCodec()). + WithInterfaceRegistry(tempApp.InterfaceRegistry()). + WithTxConfig(tempApp.TxConfig()). + WithLegacyAmino(tempApp.LegacyAmino()). + WithInput(os.Stdin) + + // set the default command outputs + cmd.SetOut(cmd.OutOrStdout()) + cmd.SetErr(cmd.ErrOrStderr()) + + clientCtx = clientCtx.WithCmdContext(cmd.Context()) + if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { + return err + } + + return nil + } +} + +// RunEWithClientCtx 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/finality-provider/cmd/fpcli/daemon/daemoncmd.go b/finality-provider/cmd/fpcli/daemon/daemoncmd.go deleted file mode 100644 index 7d662094..00000000 --- a/finality-provider/cmd/fpcli/daemon/daemoncmd.go +++ /dev/null @@ -1,394 +0,0 @@ -package daemon - -import ( - "context" - "encoding/hex" - "encoding/json" - "fmt" - "strconv" - - "cosmossdk.io/math" - bbntypes "github.com/babylonchain/babylon/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/urfave/cli" - - fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" - dc "github.com/babylonchain/finality-provider/finality-provider/service/client" -) - -var ( - defaultFpdDaemonAddress = "127.0.0.1:" + strconv.Itoa(fpcfg.DefaultRPCPort) - defaultAppHashStr = "fd903d9baeb3ab1c734ee003de75f676c5a9a8d0574647e5385834d57d3e79ec" -) - -var GetDaemonInfoCmd = cli.Command{ - Name: "get-info", - ShortName: "gi", - Usage: "Get information of the running daemon.", - Action: getInfo, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - }, -} - -func getInfo(ctx *cli.Context) error { - daemonAddress := ctx.String(fpdDaemonAddressFlag) - client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) - if err != nil { - return err - } - defer cleanUp() - - info, err := client.GetInfo(context.Background()) - - if err != nil { - return err - } - - printRespJSON(info) - - return nil -} - -var CreateFpDaemonCmd = cli.Command{ - Name: "create-finality-provider", - ShortName: "cfp", - Usage: "Create a finality provider object and save it in database.", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - cli.StringFlag{ - Name: keyNameFlag, - Usage: "The unique name of the finality provider key", - }, - cli.StringFlag{ - Name: homeFlag, - Usage: "The home path of the finality provider daemon (fpd)", - Value: fpcfg.DefaultFpdDir, - }, - cli.StringFlag{ - Name: chainIdFlag, - Usage: "The identifier of the consumer chain", - Required: true, - }, - cli.StringFlag{ - Name: passphraseFlag, - Usage: "The pass phrase used to encrypt the keys", - Value: defaultPassphrase, - }, - cli.StringFlag{ - Name: hdPathFlag, - Usage: "The hd path used to derive the private key", - Value: defaultHdPath, - }, - cli.StringFlag{ - Name: commissionRateFlag, - Usage: "The commission rate for the finality provider, e.g., 0.05", - Value: "0.05", - }, - cli.StringFlag{ - Name: monikerFlag, - Usage: "A human-readable name for the finality provider", - Value: "", - }, - cli.StringFlag{ - Name: identityFlag, - Usage: "An optional identity signature (ex. UPort or Keybase)", - Value: "", - }, - cli.StringFlag{ - Name: websiteFlag, - Usage: "An optional website link", - Value: "", - }, - cli.StringFlag{ - Name: securityContactFlag, - Usage: "An optional email for security contact", - Value: "", - }, - cli.StringFlag{ - Name: detailsFlag, - Usage: "Other optional details", - Value: "", - }, - }, - Action: createFpDaemon, -} - -func createFpDaemon(ctx *cli.Context) error { - daemonAddress := ctx.String(fpdDaemonAddressFlag) - - commissionRate, err := math.LegacyNewDecFromStr(ctx.String(commissionRateFlag)) - if err != nil { - return fmt.Errorf("invalid commission rate: %w", err) - } - - description, err := getDescriptionFromContext(ctx) - if err != nil { - return fmt.Errorf("invalid description: %w", err) - } - - keyName, err := loadKeyName(ctx) - if err != nil { - return fmt.Errorf("not able to load key name: %w", err) - } - - client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) - if err != nil { - return err - } - defer cleanUp() - - info, err := client.CreateFinalityProvider( - context.Background(), - keyName, - ctx.String(chainIdFlag), - ctx.String(passphraseFlag), - ctx.String(hdPathFlag), - description, - &commissionRate, - ) - - if err != nil { - return err - } - - printRespJSON(info.FinalityProvider) - - return nil -} - -func getDescriptionFromContext(ctx *cli.Context) (stakingtypes.Description, error) { - // get information for description - monikerStr := ctx.String(monikerFlag) - identityStr := ctx.String(identityFlag) - websiteStr := ctx.String(websiteFlag) - securityContactStr := ctx.String(securityContactFlag) - detailsStr := ctx.String(detailsFlag) - - description := stakingtypes.NewDescription(monikerStr, identityStr, websiteStr, securityContactStr, detailsStr) - - return description.EnsureLength() -} - -var LsFpDaemonCmd = cli.Command{ - Name: "list-finality-providers", - ShortName: "ls", - Usage: "List finality providers stored in the database.", - Action: lsFpDaemon, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - }, -} - -func lsFpDaemon(ctx *cli.Context) error { - daemonAddress := ctx.String(fpdDaemonAddressFlag) - rpcClient, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) - if err != nil { - return err - } - defer cleanUp() - - resp, err := rpcClient.QueryFinalityProviderList(context.Background()) - if err != nil { - return err - } - - printRespJSON(resp) - - return nil -} - -var FpInfoDaemonCmd = cli.Command{ - Name: "finality-provider-info", - ShortName: "fpi", - Usage: "Show the information of the finality provider.", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - cli.StringFlag{ - Name: fpBTCPkFlag, - Usage: "The hex string of the BTC public key", - Required: true, - }, - }, - Action: fpInfoDaemon, -} - -func fpInfoDaemon(ctx *cli.Context) error { - daemonAddress := ctx.String(fpdDaemonAddressFlag) - rpcClient, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) - if err != nil { - return err - } - defer cleanUp() - - fpPk, err := bbntypes.NewBIP340PubKeyFromHex(ctx.String(fpBTCPkFlag)) - if err != nil { - return err - } - - resp, err := rpcClient.QueryFinalityProviderInfo(context.Background(), fpPk) - if err != nil { - return err - } - - printRespJSON(resp.FinalityProvider) - - return nil -} - -var RegisterFpDaemonCmd = cli.Command{ - Name: "register-finality-provider", - ShortName: "rfp", - Usage: "Register a created finality provider to Babylon.", - UsageText: fmt.Sprintf("register-finality-provider --%s [btc-pk]", fpBTCPkFlag), - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - cli.StringFlag{ - Name: fpBTCPkFlag, - Usage: "The hex string of the finality provider BTC public key", - Required: true, - }, - cli.StringFlag{ - Name: passphraseFlag, - Usage: "The pass phrase used to encrypt the keys", - Value: defaultPassphrase, - }, - }, - Action: registerFp, -} - -func registerFp(ctx *cli.Context) error { - fpPkStr := ctx.String(fpBTCPkFlag) - fpPk, err := bbntypes.NewBIP340PubKeyFromHex(fpPkStr) - if err != nil { - return fmt.Errorf("invalid BTC public key: %w", err) - } - - daemonAddress := ctx.String(fpdDaemonAddressFlag) - rpcClient, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) - if err != nil { - return err - } - defer cleanUp() - - res, err := rpcClient.RegisterFinalityProvider(context.Background(), fpPk, ctx.String(passphraseFlag)) - if err != nil { - return err - } - - printRespJSON(res) - - return nil -} - -// AddFinalitySigDaemonCmd allows manual submission of finality signatures -// NOTE: should only be used for presentation/testing purposes -var AddFinalitySigDaemonCmd = cli.Command{ - Name: "add-finality-sig", - ShortName: "afs", - Usage: "Send a finality signature to the consumer chain. This command should only be used for presentation/testing purposes", - UsageText: fmt.Sprintf("add-finality-sig --%s [btc_pk_hex]", fpBTCPkFlag), - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - cli.StringFlag{ - Name: fpBTCPkFlag, - Usage: "The hex string of the BTC public key", - Required: true, - }, - cli.Uint64Flag{ - Name: blockHeightFlag, - Usage: "The height of the chain block", - Required: true, - }, - cli.StringFlag{ - Name: appHashFlag, - Usage: "The last commit hash of the chain block", - Value: defaultAppHashStr, - }, - }, - Action: addFinalitySig, -} - -func addFinalitySig(ctx *cli.Context) error { - daemonAddress := ctx.String(fpdDaemonAddressFlag) - rpcClient, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) - if err != nil { - return err - } - defer cleanUp() - - fpPk, err := bbntypes.NewBIP340PubKeyFromHex(ctx.String(fpBTCPkFlag)) - if err != nil { - return err - } - - appHash, err := hex.DecodeString(ctx.String(appHashFlag)) - if err != nil { - return err - } - - res, err := rpcClient.AddFinalitySignature( - context.Background(), fpPk.MarshalHex(), ctx.Uint64(blockHeightFlag), appHash) - if err != nil { - return err - } - - printRespJSON(res) - - return nil -} - -func printRespJSON(resp interface{}) { - jsonBytes, err := json.MarshalIndent(resp, "", " ") - if err != nil { - fmt.Println("unable to decode response: ", err) - return - } - - fmt.Printf("%s\n", jsonBytes) -} - -func loadKeyName(ctx *cli.Context) (string, error) { - keyName := ctx.String(keyNameFlag) - // if key name is not specified, we use the key of the config - if keyName != "" { - return keyName, nil - } - - // we add the following check to ensure that the chain key is created - // beforehand - cfg, err := fpcfg.LoadConfig(ctx.String(homeFlag)) - if err != nil { - return "", fmt.Errorf("failed to load config from %s: %w", fpcfg.ConfigFile(ctx.String(homeFlag)), err) - } - - keyName = cfg.BabylonConfig.Key - if keyName == "" { - return "", fmt.Errorf("the key in config is empty") - } - return keyName, nil -} diff --git a/finality-provider/cmd/fpcli/daemon/flags.go b/finality-provider/cmd/fpcli/daemon/flags.go deleted file mode 100644 index d2436abc..00000000 --- a/finality-provider/cmd/fpcli/daemon/flags.go +++ /dev/null @@ -1,24 +0,0 @@ -package daemon - -const ( - fpdDaemonAddressFlag = "daemon-address" - keyNameFlag = "key-name" - homeFlag = "home" - fpBTCPkFlag = "btc-pk" - blockHeightFlag = "height" - appHashFlag = "app-hash" - passphraseFlag = "passphrase" - hdPathFlag = "hd-path" - chainIdFlag = "chain-id" - signedFlag = "signed" - defaultPassphrase = "" - defaultHdPath = "" - - // flags for description - monikerFlag = "moniker" - identityFlag = "identity" - websiteFlag = "website" - securityContactFlag = "security-contact" - detailsFlag = "details" - commissionRateFlag = "commission" -) diff --git a/finality-provider/cmd/fpcli/main.go b/finality-provider/cmd/fpcli/main.go deleted file mode 100644 index 21e96aab..00000000 --- a/finality-provider/cmd/fpcli/main.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "fmt" - "os" - - dcli "github.com/babylonchain/finality-provider/finality-provider/cmd/fpcli/daemon" - "github.com/urfave/cli" -) - -func fatal(err error) { - fmt.Fprintf(os.Stderr, "[fpd] %v\n", err) - os.Exit(1) -} - -func main() { - app := cli.NewApp() - app.Name = "fpcli" - app.Usage = "Control plane for the Finality Provider Daemon (fpd)." - - app.Commands = append(app.Commands, - dcli.GetDaemonInfoCmd, - dcli.CreateFpDaemonCmd, - dcli.LsFpDaemonCmd, - dcli.FpInfoDaemonCmd, - dcli.RegisterFpDaemonCmd, - dcli.AddFinalitySigDaemonCmd, - dcli.ExportFinalityProvider, - ) - - if err := app.Run(os.Args); err != nil { - fatal(err) - } -} diff --git a/finality-provider/cmd/fpd/daemon/daemon_commands.go b/finality-provider/cmd/fpd/daemon/daemon_commands.go new file mode 100644 index 00000000..cce479f9 --- /dev/null +++ b/finality-provider/cmd/fpd/daemon/daemon_commands.go @@ -0,0 +1,393 @@ +package daemon + +import ( + "context" + "encoding/hex" + "encoding/json" + "fmt" + "strconv" + + "cosmossdk.io/math" + bbntypes "github.com/babylonchain/babylon/types" + "github.com/cosmos/cosmos-sdk/client" + sdkflags "github.com/cosmos/cosmos-sdk/client/flags" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" + fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" + dc "github.com/babylonchain/finality-provider/finality-provider/service/client" +) + +var ( + defaultFpdDaemonAddress = "127.0.0.1:" + strconv.Itoa(fpcfg.DefaultRPCPort) + defaultAppHashStr = "fd903d9baeb3ab1c734ee003de75f676c5a9a8d0574647e5385834d57d3e79ec" +) + +// CommandGetDaemonInfo returns the get-info command by connecting to the fpd daemon. +func CommandGetDaemonInfo() *cobra.Command { + var cmd = &cobra.Command{ + Use: "get-info", + Aliases: []string{"gi"}, + Short: "Get information of the running fpd daemon.", + Example: fmt.Sprintf(`fpd get-info --daemon-address %s`, defaultFpdDaemonAddress), + Args: cobra.NoArgs, + RunE: runCommandGetDaemonInfo, + } + cmd.Flags().String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + return cmd +} + +func runCommandGetDaemonInfo(cmd *cobra.Command, args []string) error { + daemonAddress, err := cmd.Flags().GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) + if err != nil { + return err + } + defer cleanUp() + + info, err := client.GetInfo(context.Background()) + if err != nil { + return err + } + + printRespJSON(info) + return nil +} + +// CommandCreateFP returns the create-finality-provider command by connecting to the fpd daemon. +func CommandCreateFP() *cobra.Command { + var cmd = &cobra.Command{ + Use: "create-finality-provider", + Aliases: []string{"cfp"}, + Short: "Create a finality provider object and save it in database.", + Example: fmt.Sprintf(`fpd create-finality-provider --daemon-address %s ...`, defaultFpdDaemonAddress), + Args: cobra.NoArgs, + RunE: fpcmd.RunEWithClientCtx(runCommandCreateFP), + } + + f := cmd.Flags() + f.String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + f.String(keyNameFlag, "", "The unique name of the finality provider key") + f.String(sdkflags.FlagHome, fpcfg.DefaultFpdDir, "The application home directory") + f.String(chainIdFlag, "", "The identifier of the consumer chain") + f.String(passphraseFlag, "", "The pass phrase used to encrypt the keys") + f.String(hdPathFlag, "", "The hd path used to derive the private key") + f.String(commissionRateFlag, "0.05", "The commission rate for the finality provider, e.g., 0.05") + f.String(monikerFlag, "", "A human-readable name for the finality provider") + f.String(identityFlag, "", "An optional identity signature (ex. UPort or Keybase)") + f.String(websiteFlag, "", "An optional website link") + f.String(securityContactFlag, "", "An email for security contact") + f.String(detailsFlag, "", "Other optional details") + + return cmd +} + +func runCommandCreateFP(ctx client.Context, cmd *cobra.Command, _ []string) error { + flags := cmd.Flags() + daemonAddress, err := flags.GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + + commissionRateStr, err := flags.GetString(commissionRateFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", commissionRateFlag, err) + } + commissionRate, err := math.LegacyNewDecFromStr(commissionRateStr) + if err != nil { + return fmt.Errorf("invalid commission rate: %w", err) + } + + description, err := getDescriptionFromFlags(flags) + if err != nil { + return fmt.Errorf("invalid description: %w", err) + } + + keyName, err := loadKeyName(ctx.HomeDir, cmd) + if err != nil { + return fmt.Errorf("not able to load key name: %w", err) + } + + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) + if err != nil { + return err + } + defer cleanUp() + + chainId, err := flags.GetString(chainIdFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", chainIdFlag, err) + } + + passphrase, err := flags.GetString(passphraseFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", passphraseFlag, err) + } + + hdPath, err := flags.GetString(hdPathFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", hdPathFlag, err) + } + + info, err := client.CreateFinalityProvider( + context.Background(), + keyName, + chainId, + passphrase, + hdPath, + description, + &commissionRate, + ) + if err != nil { + return err + } + + printRespJSON(info.FinalityProvider) + return nil +} + +func getDescriptionFromFlags(f *pflag.FlagSet) (desc stakingtypes.Description, err error) { + // get information for description + monikerStr, err := f.GetString(monikerFlag) + if err != nil { + return desc, fmt.Errorf("failed to read flag %s: %w", monikerFlag, err) + } + identityStr, err := f.GetString(identityFlag) + if err != nil { + return desc, fmt.Errorf("failed to read flag %s: %w", identityFlag, err) + } + websiteStr, err := f.GetString(websiteFlag) + if err != nil { + return desc, fmt.Errorf("failed to read flag %s: %w", websiteFlag, err) + } + securityContactStr, err := f.GetString(securityContactFlag) + if err != nil { + return desc, fmt.Errorf("failed to read flag %s: %w", securityContactFlag, err) + } + detailsStr, err := f.GetString(detailsFlag) + if err != nil { + return desc, fmt.Errorf("failed to read flag %s: %w", detailsFlag, err) + } + + description := stakingtypes.NewDescription(monikerStr, identityStr, websiteStr, securityContactStr, detailsStr) + return description.EnsureLength() +} + +// CommandLsFP returns the list-finality-providers command by connecting to the fpd daemon. +func CommandLsFP() *cobra.Command { + var cmd = &cobra.Command{ + Use: "list-finality-providers", + Aliases: []string{"ls"}, + Short: "List finality providers stored in the database.", + Example: fmt.Sprintf(`fpd list-finality-providers --daemon-address %s`, defaultFpdDaemonAddress), + Args: cobra.NoArgs, + RunE: runCommandLsFP, + } + cmd.Flags().String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + return cmd +} + +func runCommandLsFP(cmd *cobra.Command, args []string) error { + daemonAddress, err := cmd.Flags().GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) + if err != nil { + return err + } + defer cleanUp() + + resp, err := client.QueryFinalityProviderList(context.Background()) + if err != nil { + return err + } + printRespJSON(resp) + + return nil +} + +// CommandInfoFP returns the finality-provider-info command by connecting to the fpd daemon. +func CommandInfoFP() *cobra.Command { + var cmd = &cobra.Command{ + Use: "finality-provider-info [fp-pk-btc-hex]", + Aliases: []string{"fpi"}, + Short: "List finality providers stored in the database.", + Example: fmt.Sprintf(`fpd finality-provider-info --daemon-address %s`, defaultFpdDaemonAddress), + Args: cobra.ExactArgs(1), + RunE: runCommandInfoFP, + } + cmd.Flags().String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + return cmd +} + +func runCommandInfoFP(cmd *cobra.Command, args []string) error { + fpPk, err := bbntypes.NewBIP340PubKeyFromHex(args[0]) + if err != nil { + return err + } + + daemonAddress, err := cmd.Flags().GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) + if err != nil { + return err + } + defer cleanUp() + + resp, err := client.QueryFinalityProviderInfo(context.Background(), fpPk) + if err != nil { + return err + } + printRespJSON(resp) + + return nil +} + +// CommandRegisterFP returns the register-finality-provider command by connecting to the fpd daemon. +func CommandRegisterFP() *cobra.Command { + var cmd = &cobra.Command{ + Use: "register-finality-provider [fp-pk-btc-hex]", + Aliases: []string{"rfp"}, + Short: "Register a created finality provider to Babylon.", + Example: fmt.Sprintf(`fpd register-finality-provider --daemon-address %s`, defaultFpdDaemonAddress), + Args: cobra.ExactArgs(1), + RunE: runCommandRegisterFP, + } + f := cmd.Flags() + f.String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + f.String(passphraseFlag, "", "The pass phrase used to encrypt the keys") + return cmd +} + +func runCommandRegisterFP(cmd *cobra.Command, args []string) error { + fpPk, err := bbntypes.NewBIP340PubKeyFromHex(args[0]) + if err != nil { + return err + } + + flags := cmd.Flags() + daemonAddress, err := flags.GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) + if err != nil { + return err + } + defer cleanUp() + + passphrase, err := flags.GetString(passphraseFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", passphraseFlag, err) + } + + res, err := client.RegisterFinalityProvider(context.Background(), fpPk, passphrase) + if err != nil { + return err + } + printRespJSON(res) + + return nil +} + +// CommandAddFinalitySig returns the add-finality-sig command by connecting to the fpd daemon. +func CommandAddFinalitySig() *cobra.Command { + var cmd = &cobra.Command{ + Use: "add-finality-sig [fp-pk-btc-hex] [block-height]", + Aliases: []string{"afs"}, + Short: "Send a finality signature to the consumer chain. This command should only be used for presentation/testing purposes", + Example: fmt.Sprintf(`fpd add-finality-sig --daemon-address %s`, defaultFpdDaemonAddress), + Args: cobra.ExactArgs(2), + RunE: runCommandAddFinalitySig, + } + cmd.Flags().String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + cmd.Flags().String(appHashFlag, defaultAppHashStr, "The last commit hash of the chain block") + return cmd +} + +func runCommandAddFinalitySig(cmd *cobra.Command, args []string) error { + fpPk, err := bbntypes.NewBIP340PubKeyFromHex(args[0]) + if err != nil { + return err + } + blkHeight, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return err + } + + flags := cmd.Flags() + daemonAddress, err := flags.GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + + appHashHex, err := flags.GetString(appHashFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", appHashFlag, err) + } + + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) + if err != nil { + return err + } + defer cleanUp() + + appHash, err := hex.DecodeString(appHashHex) + if err != nil { + return err + } + + res, err := client.AddFinalitySignature(context.Background(), fpPk.MarshalHex(), blkHeight, appHash) + if err != nil { + return err + } + printRespJSON(res) + + return nil +} + +func printRespJSON(resp interface{}) { + jsonBytes, err := json.MarshalIndent(resp, "", " ") + if err != nil { + fmt.Println("unable to decode response: ", err) + return + } + + fmt.Printf("%s\n", jsonBytes) +} + +func loadKeyName(homeDir string, cmd *cobra.Command) (string, error) { + keyName, err := cmd.Flags().GetString(keyNameFlag) + if err != nil { + return "", fmt.Errorf("failed to read flag %s: %w", keyNameFlag, err) + } + // if key name is not specified, we use the key of the config + if keyName != "" { + return keyName, nil + } + + // we add the following check to ensure that the chain key is created + // beforehand + cfg, err := fpcfg.LoadConfig(homeDir) + if err != nil { + return "", fmt.Errorf("failed to load config from %s: %w", fpcfg.ConfigFile(homeDir), err) + } + + keyName = cfg.BabylonConfig.Key + if keyName == "" { + return "", fmt.Errorf("the key in config is empty") + } + return keyName, nil +} diff --git a/finality-provider/cmd/fpcli/daemon/export.go b/finality-provider/cmd/fpd/daemon/export.go similarity index 56% rename from finality-provider/cmd/fpcli/daemon/export.go rename to finality-provider/cmd/fpd/daemon/export.go index dffd3fab..f9d83677 100644 --- a/finality-provider/cmd/fpcli/daemon/export.go +++ b/finality-provider/cmd/fpd/daemon/export.go @@ -6,14 +6,16 @@ import ( "fmt" "cosmossdk.io/math" + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" dc "github.com/babylonchain/finality-provider/finality-provider/service/client" + "github.com/cosmos/cosmos-sdk/client" + sdkflags "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/spf13/cobra" bbn "github.com/babylonchain/babylon/types" btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" - - "github.com/urfave/cli" ) // FinalityProviderSigned wraps the finality provider by adding the @@ -25,61 +27,46 @@ type FinalityProviderSigned struct { FpSigHex string `json:"fp_sig_hex"` } -var ExportFinalityProvider = cli.Command{ - Name: "export-finality-provider", - ShortName: "exfp", - Usage: "It exports the finality provider by the given BTC public key.", - Description: `Fetches the finality provider from the database and exports it - by printing the json structure on the stdout.`, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: fpdDaemonAddressFlag, - Usage: "The RPC server address of fpd", - Value: defaultFpdDaemonAddress, - }, - cli.StringFlag{ - Name: fpBTCPkFlag, - Usage: "The hex string of the BTC public key", - Required: true, - }, - cli.BoolFlag{ - Name: signedFlag, - Usage: `Specify if the exported finality provider information should be signed, +// CommandExportFP returns the export-finality-provider command by loading the fp and export the data. +func CommandExportFP() *cobra.Command { + var cmd = &cobra.Command{ + Use: "export-finality-provider [fp-btc-pk-hex]", + Aliases: []string{"exfp"}, + Short: "It exports the finality provider by the given BTC public key.", + Example: fmt.Sprintf(`fpd export-finality-provider --daemon-address %s`, defaultFpdDaemonAddress), + Args: cobra.NoArgs, + RunE: fpcmd.RunEWithClientCtx(runCommandExportFP), + } + + f := cmd.Flags() + f.String(fpdDaemonAddressFlag, defaultFpdDaemonAddress, "The RPC server address of fpd") + f.Bool(signedFlag, false, + `Specify if the exported finality provider information should be signed, if true, it will sign using the flag key-name, if not set it will load from the babylon key on config.`, - }, - cli.StringFlag{ - Name: keyNameFlag, - Usage: "The unique name of the finality provider key", - }, - cli.StringFlag{ - Name: homeFlag, - Usage: "The home path of the finality provider daemon (fpd)", - Value: fpcfg.DefaultFpdDir, - }, - cli.StringFlag{ - Name: passphraseFlag, - Usage: "The pass phrase used to encrypt the keys", - Value: defaultPassphrase, - }, - cli.StringFlag{ - Name: hdPathFlag, - Usage: "The hd path used to derive the private key", - Value: defaultHdPath, - }, - }, - Action: exportFp, + ) + f.String(keyNameFlag, "", "The unique name of the finality provider key") + f.String(sdkflags.FlagHome, fpcfg.DefaultFpdDir, "The application home directory") + f.String(passphraseFlag, "", "The pass phrase used to encrypt the keys") + f.String(hdPathFlag, "", "The hd path used to derive the private key") + + return cmd } -func exportFp(ctx *cli.Context) error { - daemonAddress := ctx.String(fpdDaemonAddressFlag) +func runCommandExportFP(ctx client.Context, cmd *cobra.Command, args []string) error { + flags := cmd.Flags() + daemonAddress, err := flags.GetString(fpdDaemonAddressFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", fpdDaemonAddressFlag, err) + } + client, cleanUp, err := dc.NewFinalityProviderServiceGRpcClient(daemonAddress) if err != nil { return fmt.Errorf("failled to connect to daemon addr %s: %w", daemonAddress, err) } defer cleanUp() - fpBtcPkHex := ctx.String(fpBTCPkFlag) + fpBtcPkHex := args[0] fpPk, err := bbn.NewBIP340PubKeyFromHex(fpBtcPkHex) if err != nil { return fmt.Errorf("invalid fp btc pk hex %s: %w", fpBtcPkHex, err) @@ -111,12 +98,16 @@ func exportFp(ctx *cli.Context) error { Pop: nil, // TODO: fill PoP? } - if !ctx.Bool(signedFlag) { + signed, err := flags.GetBool(signedFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", signedFlag, err) + } + if !signed { printRespJSON(fp) return nil } - keyName, err := loadKeyName(ctx) + keyName, err := loadKeyName(ctx.HomeDir, cmd) if err != nil { return fmt.Errorf("not able to load key name: %w", err) } @@ -127,11 +118,21 @@ func exportFp(ctx *cli.Context) error { return fmt.Errorf("failed to marshal finality provider %+v: %w", fp, err) } + passphrase, err := flags.GetString(passphraseFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", passphraseFlag, err) + } + + hdPath, err := flags.GetString(hdPathFlag) + if err != nil { + return fmt.Errorf("failed to read flag %s: %w", hdPathFlag, err) + } + resp, err := client.SignMessageFromChainKey( context.Background(), keyName, - ctx.String(passphraseFlag), - ctx.String(hdPathFlag), + passphrase, + hdPath, fpbz, ) if err != nil { @@ -142,6 +143,5 @@ func exportFp(ctx *cli.Context) error { FinalityProvider: fp, FpSigHex: hex.EncodeToString(resp.Signature), }) - return nil } diff --git a/finality-provider/cmd/fpd/daemon/flags.go b/finality-provider/cmd/fpd/daemon/flags.go index dc5bc4be..847a2997 100644 --- a/finality-provider/cmd/fpd/daemon/flags.go +++ b/finality-provider/cmd/fpd/daemon/flags.go @@ -1,8 +1,22 @@ package daemon const ( - forceFlag = "force" - passphraseFlag = "passphrase" - fpPkFlag = "btc-pk" - rpcListenerFlag = "rpc-listener" + forceFlag = "force" + fpPkFlag = "btc-pk" + rpcListenerFlag = "rpc-listener" + fpdDaemonAddressFlag = "daemon-address" + keyNameFlag = "key-name" + appHashFlag = "app-hash" + passphraseFlag = "passphrase" + hdPathFlag = "hd-path" + chainIdFlag = "chain-id" + signedFlag = "signed" + + // flags for description + monikerFlag = "moniker" + identityFlag = "identity" + websiteFlag = "website" + securityContactFlag = "security-contact" + detailsFlag = "details" + commissionRateFlag = "commission" ) diff --git a/finality-provider/cmd/fpd/daemon/init.go b/finality-provider/cmd/fpd/daemon/init.go index 3cf2e947..723f56ac 100644 --- a/finality-provider/cmd/fpd/daemon/init.go +++ b/finality-provider/cmd/fpd/daemon/init.go @@ -8,6 +8,7 @@ import ( "github.com/jessevdk/go-flags" "github.com/spf13/cobra" + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" "github.com/babylonchain/finality-provider/util" ) @@ -20,21 +21,12 @@ func CommandInit() *cobra.Command { Long: `Creates a new finality-provider home directory with default config`, Example: `fpd init --home /home/user/.fpd --force`, Args: cobra.NoArgs, - RunE: runInitCmdPrepare, + RunE: fpcmd.RunEWithClientCtx(runInitCmd), } cmd.Flags().Bool(forceFlag, false, "Override existing configuration") return cmd } -func runInitCmdPrepare(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - return runInitCmd(clientCtx, cmd, args) -} - func runInitCmd(ctx client.Context, cmd *cobra.Command, args []string) error { homePath, err := filepath.Abs(ctx.HomeDir) if err != nil { diff --git a/finality-provider/cmd/fpd/daemon/keys.go b/finality-provider/cmd/fpd/daemon/keys.go index 25dd2010..483e68fb 100644 --- a/finality-provider/cmd/fpd/daemon/keys.go +++ b/finality-provider/cmd/fpd/daemon/keys.go @@ -3,6 +3,7 @@ package daemon import ( "strings" + helper "github.com/babylonchain/finality-provider/finality-provider/cmd" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" "github.com/cosmos/cosmos-sdk/client" sdkflags "github.com/cosmos/cosmos-sdk/client/flags" @@ -20,15 +21,9 @@ func CommandKeys() *cobra.Command { panic("failed to find keys add command") } - // add command - keyAddCmd.PostRunE = func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - + keyAddCmd.PostRunE = helper.RunEWithClientCtx(func(ctx client.Context, cmd *cobra.Command, args []string) error { // check the config file exists - cfg, err := fpcfg.LoadConfig(clientCtx.HomeDir) + cfg, err := fpcfg.LoadConfig(ctx.HomeDir) if err != nil { return nil // config does not exist, so does not update it } @@ -43,8 +38,8 @@ func CommandKeys() *cobra.Command { cfg.BabylonConfig.KeyringBackend = keyringBackend fileParser := goflags.NewParser(cfg, goflags.Default) - return goflags.NewIniParser(fileParser).WriteFile(fpcfg.ConfigFile(clientCtx.HomeDir), goflags.IniIncludeComments|goflags.IniIncludeDefaults) - } + return goflags.NewIniParser(fileParser).WriteFile(fpcfg.ConfigFile(ctx.HomeDir), goflags.IniIncludeComments|goflags.IniIncludeDefaults) + }) return keysCmd } diff --git a/finality-provider/cmd/fpd/daemon/start.go b/finality-provider/cmd/fpd/daemon/start.go index 6e60d6c1..48a30ac3 100644 --- a/finality-provider/cmd/fpd/daemon/start.go +++ b/finality-provider/cmd/fpd/daemon/start.go @@ -12,6 +12,7 @@ import ( "github.com/spf13/cobra" "go.uber.org/zap" + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" "github.com/babylonchain/finality-provider/finality-provider/service" "github.com/babylonchain/finality-provider/log" @@ -26,7 +27,7 @@ func CommandStart() *cobra.Command { Long: `Start the finality-provider app. Note that eotsd should be started beforehand`, Example: `fpd start --home /home/user/.fpd`, Args: cobra.NoArgs, - RunE: runStartCmdPrepare, + RunE: fpcmd.RunEWithClientCtx(runStartCmd), } cmd.Flags().String(fpPkFlag, "", "The public key of the finality-provider to start") cmd.Flags().String(passphraseFlag, "", "The pass phrase used to decrypt the private key") @@ -34,15 +35,6 @@ func CommandStart() *cobra.Command { return cmd } -func runStartCmdPrepare(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - return runStartCmd(clientCtx, cmd, args) -} - func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { homePath, err := filepath.Abs(ctx.HomeDir) if err != nil { diff --git a/finality-provider/cmd/fpd/main.go b/finality-provider/cmd/fpd/main.go index d8260e56..72eef5b6 100644 --- a/finality-provider/cmd/fpd/main.go +++ b/finality-provider/cmd/fpd/main.go @@ -4,51 +4,23 @@ import ( "fmt" "os" - "github.com/babylonchain/babylon/app" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" "github.com/babylonchain/finality-provider/finality-provider/cmd/fpd/daemon" fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" ) // NewRootCmd creates a new root command for fpd. It is called once in the main function. func NewRootCmd() *cobra.Command { - var ( - clientCtx client.Context - ) - rootCmd := &cobra.Command{ - Use: "fpd", - Short: "fpd - Finality Provider Daemon (fpd).", - Long: `fpd is the daemon to create and manage finality providers.`, - SilenceErrors: false, - PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { - // TODO(verify): if it uses the default encoding config it fails to list keys! output: - // "xx" is not a valid name or address: unable to unmarshal item.Data: - // Bytes left over in UnmarshalBinaryLengthPrefixed, should read 10 more bytes but have 154 - // [cosmos/cosmos-sdk@v0.50.6/crypto/keyring/keyring.go:973 - tempApp := app.NewTmpBabylonApp() - - clientCtx = clientCtx. - WithCodec(tempApp.AppCodec()). - WithInterfaceRegistry(tempApp.InterfaceRegistry()). - WithTxConfig(tempApp.TxConfig()). - WithLegacyAmino(tempApp.LegacyAmino()). - WithInput(os.Stdin) - - // set the default command outputs - cmd.SetOut(cmd.OutOrStdout()) - cmd.SetErr(cmd.ErrOrStderr()) - - clientCtx = clientCtx.WithCmdContext(cmd.Context()) - if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { - return err - } - - return nil - }, + Use: "fpd", + Short: "fpd - Finality Provider Daemon (fpd).", + Long: `fpd is the daemon to create and manage finality providers.`, + SilenceErrors: false, + PersistentPreRunE: fpcmd.PersistClientCtx(client.Context{}), } rootCmd.PersistentFlags().String(flags.FlagHome, fpcfg.DefaultFpdDir, "The application home directory") @@ -57,7 +29,12 @@ func NewRootCmd() *cobra.Command { func main() { cmd := NewRootCmd() - cmd.AddCommand(daemon.CommandKeys(), daemon.CommandStart(), daemon.CommandInit()) + cmd.AddCommand( + daemon.CommandInit(), daemon.CommandStart(), daemon.CommandKeys(), + daemon.CommandGetDaemonInfo(), daemon.CommandCreateFP(), daemon.CommandLsFP(), + daemon.CommandInfoFP(), daemon.CommandRegisterFP(), daemon.CommandAddFinalitySig(), + daemon.CommandExportFP(), + ) if err := cmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "Whoops. There was an error while executing your fpd CLI '%s'", err) diff --git a/finality-provider/service/client/rpcclient.go b/finality-provider/service/client/rpcclient.go index dffcd75d..1f475b86 100644 --- a/finality-provider/service/client/rpcclient.go +++ b/finality-provider/service/client/rpcclient.go @@ -17,13 +17,14 @@ type FinalityProviderServiceGRpcClient struct { client proto.FinalityProvidersClient } -func NewFinalityProviderServiceGRpcClient(remoteAddr string) (*FinalityProviderServiceGRpcClient, func(), error) { +// NewFinalityProviderServiceGRpcClient creates a new GRPC connection with finality provider daemon. +func NewFinalityProviderServiceGRpcClient(remoteAddr string) (client *FinalityProviderServiceGRpcClient, cleanUp func(), err error) { conn, err := grpc.Dial(remoteAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, nil, fmt.Errorf("failed to build gRPC connection to %s: %w", remoteAddr, err) } - cleanUp := func() { + cleanUp = func() { conn.Close() } From 281905f5a0b59d344eff3ebae29083689f82a4e5 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 15 Jul 2024 16:27:54 -0300 Subject: [PATCH 18/21] chore: fpd signed msg create fp and tx sign (#500) - Add tx subcommands - Tx sign - Tx create-finality-provider --- finality-provider/cmd/cmd.go | 65 +++++++++++++++++--- finality-provider/cmd/cmd_test.go | 82 ++++++++++++++++++++++++++ finality-provider/cmd/fpd/daemon/tx.go | 27 +++++++++ finality-provider/cmd/fpd/main.go | 2 +- finality-provider/service/rpcserver.go | 1 - 5 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 finality-provider/cmd/cmd_test.go create mode 100644 finality-provider/cmd/fpd/daemon/tx.go diff --git a/finality-provider/cmd/cmd.go b/finality-provider/cmd/cmd.go index c4e513d2..0375844f 100644 --- a/finality-provider/cmd/cmd.go +++ b/finality-provider/cmd/cmd.go @@ -3,13 +3,19 @@ package cmd import ( "os" - "github.com/babylonchain/babylon/app" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "github.com/babylonchain/babylon/app" + fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" ) -// PersistClientCtx persist some vars from the cmd to the client context. -func PersistClientCtx(clientCtx client.Context) func(cmd *cobra.Command, _ []string) error { +// PersistClientCtx persist some vars from the cmd or config to the client context. +// It gives preferences to flags over the values in the config. If the flag is not set +// and exists a value in the config that could be used, it will be set in the ctx. +func PersistClientCtx(ctx client.Context) func(cmd *cobra.Command, _ []string) error { return func(cmd *cobra.Command, _ []string) error { // TODO(verify): if it uses the default encoding config it fails to list keys! output: // "xx" is not a valid name or address: unable to unmarshal item.Data: @@ -17,7 +23,7 @@ func PersistClientCtx(clientCtx client.Context) func(cmd *cobra.Command, _ []str // [cosmos/cosmos-sdk@v0.50.6/crypto/keyring/keyring.go:973 tempApp := app.NewTmpBabylonApp() - clientCtx = clientCtx. + ctx = ctx. WithCodec(tempApp.AppCodec()). WithInterfaceRegistry(tempApp.InterfaceRegistry()). WithTxConfig(tempApp.TxConfig()). @@ -28,13 +34,58 @@ func PersistClientCtx(clientCtx client.Context) func(cmd *cobra.Command, _ []str cmd.SetOut(cmd.OutOrStdout()) cmd.SetErr(cmd.ErrOrStderr()) - clientCtx = clientCtx.WithCmdContext(cmd.Context()) - if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { + ctx = ctx.WithCmdContext(cmd.Context()) + if err := client.SetCmdClientContextHandler(ctx, cmd); err != nil { return err } - return nil + ctx = client.GetClientContextFromCmd(cmd) + // check the config file exists + cfg, err := fpcfg.LoadConfig(ctx.HomeDir) + if err != nil { + return nil // if no conifg is found just stop. + } + + // config was found, load the defaults if not set by flag + // flags have preference over config. + ctx, err = FillContextFromBabylonConfig(ctx, cmd.Flags(), cfg.BabylonConfig) + if err != nil { + return err + } + + // updates the ctx in the cmd in case something was modified bt the config + return client.SetCmdClientContext(cmd, ctx) + } +} + +// FillContextFromBabylonConfig loads the bbn config to the context if values were not set by flag. +// Preference is FlagSet values over the config. +func FillContextFromBabylonConfig(ctx client.Context, flagSet *pflag.FlagSet, bbnConf *fpcfg.BBNConfig) (client.Context, error) { + if !flagSet.Changed(flags.FlagFrom) { + ctx = ctx.WithFrom(bbnConf.Key) + } + if !flagSet.Changed(flags.FlagChainID) { + ctx = ctx.WithChainID(bbnConf.ChainID) + } + if !flagSet.Changed(flags.FlagKeyringBackend) { + kr, err := client.NewKeyringFromBackend(ctx, bbnConf.KeyringBackend) + if err != nil { + return ctx, err + } + + ctx = ctx.WithKeyring(kr) + } + if !flagSet.Changed(flags.FlagKeyringDir) { + ctx = ctx.WithKeyringDir(bbnConf.KeyDirectory) + } + if !flagSet.Changed(flags.FlagOutput) { + ctx = ctx.WithOutputFormat(bbnConf.OutputFormat) } + if !flagSet.Changed(flags.FlagSignMode) { + ctx = ctx.WithSignModeStr(bbnConf.SignModeStr) + } + + return ctx, nil } // RunEWithClientCtx runs cmd with client context and returns an error. diff --git a/finality-provider/cmd/cmd_test.go b/finality-provider/cmd/cmd_test.go new file mode 100644 index 00000000..2c0be72b --- /dev/null +++ b/finality-provider/cmd/cmd_test.go @@ -0,0 +1,82 @@ +package cmd_test + +import ( + "math/rand" + "path/filepath" + "testing" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" + "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/testutil/datagen" + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" + fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" + "github.com/babylonchain/finality-provider/util" + goflags "github.com/jessevdk/go-flags" +) + +func TestPersistClientCtx(t *testing.T) { + ctx := client.Context{} + cmd := cobra.Command{} + + tempDir := t.TempDir() + defaultHome := filepath.Join(tempDir, "defaultHome") + + cmd.Flags().String(flags.FlagHome, defaultHome, "The application home directory") + cmd.Flags().String(flags.FlagChainID, "", "chain id") + + err := fpcmd.PersistClientCtx(ctx)(&cmd, []string{}) + require.NoError(t, err) + + // verify that has the defaults to ctx + ctx = client.GetClientContextFromCmd(&cmd) + require.Equal(t, defaultHome, ctx.HomeDir) + require.Equal(t, "", ctx.ChainID) + + flagHomeValue := filepath.Join(tempDir, "flagHome") + err = cmd.Flags().Set(flags.FlagHome, flagHomeValue) + require.NoError(t, err) + + err = fpcmd.PersistClientCtx(ctx)(&cmd, []string{}) + require.NoError(t, err) + + ctx = client.GetClientContextFromCmd(&cmd) + require.Equal(t, flagHomeValue, ctx.HomeDir) + + r := rand.New(rand.NewSource(10)) + randChainID := datagen.GenRandomHexStr(r, 10) + + // creates fpd config with chainID at flagHomeValue + err = util.MakeDirectory(flagHomeValue) + require.NoError(t, err) + + config := fpcfg.DefaultConfigWithHome(flagHomeValue) + config.BabylonConfig.ChainID = randChainID + fileParser := goflags.NewParser(&config, goflags.Default) + + err = goflags.NewIniParser(fileParser).WriteFile(fpcfg.ConfigFile(flagHomeValue), goflags.IniIncludeComments|goflags.IniIncludeDefaults) + require.NoError(t, err) + + // parses the ctx from cmd with config, should modify the chain ID + err = fpcmd.PersistClientCtx(ctx)(&cmd, []string{}) + require.NoError(t, err) + + ctx = client.GetClientContextFromCmd(&cmd) + require.Equal(t, flagHomeValue, ctx.HomeDir) + require.Equal(t, randChainID, ctx.ChainID) + + flagChainID := "chainIDFromFlag" + err = cmd.Flags().Set(flags.FlagChainID, flagChainID) + require.NoError(t, err) + + // parses the ctx from cmd with config, but it has set in flags which should give + // preference over the config set, so it should use from the flag value set. + err = fpcmd.PersistClientCtx(ctx)(&cmd, []string{}) + require.NoError(t, err) + + ctx = client.GetClientContextFromCmd(&cmd) + require.Equal(t, flagHomeValue, ctx.HomeDir) + require.Equal(t, flagChainID, ctx.ChainID) +} diff --git a/finality-provider/cmd/fpd/daemon/tx.go b/finality-provider/cmd/fpd/daemon/tx.go new file mode 100644 index 00000000..2c8ddbff --- /dev/null +++ b/finality-provider/cmd/fpd/daemon/tx.go @@ -0,0 +1,27 @@ +package daemon + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" + + btcstakingcli "github.com/babylonchain/babylon/x/btcstaking/client/cli" + authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" +) + +// CommandTxs returns the transaction commands for finality provider related msgs. +func CommandTxs() *cobra.Command { + cmd := &cobra.Command{ + Use: "tx", + Short: "transactions subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + authcli.GetSignCommand(), + btcstakingcli.NewCreateFinalityProviderCmd(), + ) + + return cmd +} diff --git a/finality-provider/cmd/fpd/main.go b/finality-provider/cmd/fpd/main.go index 72eef5b6..f549398a 100644 --- a/finality-provider/cmd/fpd/main.go +++ b/finality-provider/cmd/fpd/main.go @@ -33,7 +33,7 @@ func main() { daemon.CommandInit(), daemon.CommandStart(), daemon.CommandKeys(), daemon.CommandGetDaemonInfo(), daemon.CommandCreateFP(), daemon.CommandLsFP(), daemon.CommandInfoFP(), daemon.CommandRegisterFP(), daemon.CommandAddFinalitySig(), - daemon.CommandExportFP(), + daemon.CommandExportFP(), daemon.CommandTxs(), ) if err := cmd.Execute(); err != nil { diff --git a/finality-provider/service/rpcserver.go b/finality-provider/service/rpcserver.go index 7c97a5d5..10d24f53 100644 --- a/finality-provider/service/rpcserver.go +++ b/finality-provider/service/rpcserver.go @@ -110,7 +110,6 @@ func (r *rpcServer) CreateFinalityProvider(ctx context.Context, req *proto.Creat return &proto.CreateFinalityProviderResponse{ FinalityProvider: result.FpInfo, }, nil - } // RegisterFinalityProvider sends a transactions to Babylon to register a BTC finality-provider From aab192d89905e32f8755a23dd8b1c89c2d89a936 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 18 Jul 2024 09:43:08 -0300 Subject: [PATCH 19/21] chore: migrate from btc-pk to eots-pk in eotsd related commands and docs (#523) This only changes the naming in flag and docs, suggested at https://github.com/babylonchain/pm/pull/67#discussion_r1677552147 --- docs/eots.md | 8 ++++---- eotsmanager/cmd/eotsd/daemon/flags.go | 2 +- eotsmanager/cmd/eotsd/daemon/pop.go | 12 ++++++------ eotsmanager/cmd/eotsd/daemon/pop_test.go | 4 ++-- eotsmanager/cmd/eotsd/daemon/sign.go | 16 ++++++++-------- eotsmanager/cmd/eotsd/daemon/sign_test.go | 16 ++++++++-------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/eots.md b/docs/eots.md index b09b77a7..8b20cb03 100644 --- a/docs/eots.md +++ b/docs/eots.md @@ -127,8 +127,8 @@ You can use your key to create a Schnorr signature over arbitrary data through the `eotsd sign-schnorr` command. The command takes as an argument the file path, hashes the file content using sha256, and signs the hash with the EOTS private key in Schnorr format by the -given `key-name` or `btc-pk`. If both flags `--key-name` and `--btc-pk` are -provided, `btc-pk` takes priority. +given `key-name` or `eots-pk`. If both flags `--key-name` and `--eots-pk` are +provided, `eots-pk` takes priority. ```shell eotsd sign-schnorr /path/to/data/file --home /path/to/eotsd/home/ --key-name my-key-name --keyring-backend file @@ -146,12 +146,12 @@ You can verify the Schnorr signature signed in the previous step through the `eptsd veify-schnorr-sig` command. The command takes as an argument the file path, hashes the file content using sha256 to generate the signed data, and verifies the signature from the `--signature` -flag using the given public key from the `--btc-pk` flag. +flag using the given public key from the `--eots-pk` flag. If the signature is valid, you will see `Verification is successful!` in the output. Otherwise, an error message will be printed out. ```shell -eotsd verify-schnorr-sig /path/to/data/file --btc-pk 50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383 \ +eotsd verify-schnorr-sig /path/to/data/file --eots-pk 50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383 \ --signature b91fc06b30b78c0ca66a7e033184d89b61cd6ab572329b20f6052411ab83502effb5c9a1173ed69f20f6502a741eeb5105519bb3f67d37612bc2bcce411f8d72 \ --keyring-backend file ``` diff --git a/eotsmanager/cmd/eotsd/daemon/flags.go b/eotsmanager/cmd/eotsd/daemon/flags.go index c4679a5b..42ec8901 100644 --- a/eotsmanager/cmd/eotsd/daemon/flags.go +++ b/eotsmanager/cmd/eotsd/daemon/flags.go @@ -6,7 +6,7 @@ const ( homeFlag = "home" forceFlag = "force" rpcListenerFlag = "rpc-listener" - fpPkFlag = "btc-pk" + eotsPkFlag = "eots-pk" signatureFlag = "signature" // flags for keys diff --git a/eotsmanager/cmd/eotsd/daemon/pop.go b/eotsmanager/cmd/eotsd/daemon/pop.go index 22242f38..c4b9a927 100644 --- a/eotsmanager/cmd/eotsd/daemon/pop.go +++ b/eotsmanager/cmd/eotsd/daemon/pop.go @@ -20,7 +20,7 @@ func init() { } // PoPExport the data for exporting the PoP. -// The PubKeyHex is the public key of the finality provider BTC key to load +// The PubKeyHex is the public key of the finality provider EOTS key to load // the private key and sign the AddressSiged. type PoPExport struct { PubKeyHex string `json:"pub_key_hex"` @@ -33,8 +33,8 @@ var ExportPoPCommand = cli.Command{ Usage: "Exports the Proof of Possession by signing over the finality provider's Babylon address with the EOTS private key.", UsageText: "pop-export [bbn-address]", Description: `Parse the address received as argument, hash it with - sha256 and sign based on the EOTS key associated with the key-name or btc-pk flag. - If the both flags are supplied, btc-pk takes priority. Use the generated signature + sha256 and sign based on the EOTS key associated with the key-name or eots-pk flag. + If the both flags are supplied, eots-pk takes priority. Use the generated signature to build a Proof of Possession and export it.`, Flags: []cli.Flag{ cli.StringFlag{ @@ -47,7 +47,7 @@ var ExportPoPCommand = cli.Command{ Usage: "The name of the key to load private key for signing", }, cli.StringFlag{ - Name: fpPkFlag, + Name: eotsPkFlag, Usage: "The public key of the finality-provider to load private key for signing", }, cli.StringFlag{ @@ -66,7 +66,7 @@ var ExportPoPCommand = cli.Command{ func ExportPoP(ctx *cli.Context) error { keyName := ctx.String(keyNameFlag) - fpPkStr := ctx.String(fpPkFlag) + fpPkStr := ctx.String(eotsPkFlag) passphrase := ctx.String(passphraseFlag) keyringBackend := ctx.String(keyringBackendFlag) @@ -78,7 +78,7 @@ func ExportPoP(ctx *cli.Context) error { } if len(fpPkStr) == 0 && len(keyName) == 0 { - return fmt.Errorf("at least one of the flags: %s, %s needs to be informed", keyNameFlag, fpPkFlag) + return fmt.Errorf("at least one of the flags: %s, %s needs to be informed", keyNameFlag, eotsPkFlag) } homePath, err := getHomeFlag(ctx) diff --git a/eotsmanager/cmd/eotsd/daemon/pop_test.go b/eotsmanager/cmd/eotsd/daemon/pop_test.go index 6b42b2b3..7202b56f 100644 --- a/eotsmanager/cmd/eotsd/daemon/pop_test.go +++ b/eotsmanager/cmd/eotsd/daemon/pop_test.go @@ -43,8 +43,8 @@ func FuzzPoPExport(f *testing.F) { bbnAddr := datagen.GenRandomAccount().GetAddress() - btcPkFlag := fmt.Sprintf("--btc-pk=%s", keyOut.PubKeyHex) - exportedPoP := appRunPoPExport(r, t, app, []string{bbnAddr.String(), hFlag, btcPkFlag}) + eotsBtcPkFlag := fmt.Sprintf("--eots-pk=%s", keyOut.PubKeyHex) + exportedPoP := appRunPoPExport(r, t, app, []string{bbnAddr.String(), hFlag, eotsBtcPkFlag}) pop, err := btcstktypes.NewPoPBTCFromHex(exportedPoP.PoPHex) require.NoError(t, err) diff --git a/eotsmanager/cmd/eotsd/daemon/sign.go b/eotsmanager/cmd/eotsd/daemon/sign.go index abfa14d1..3dfdeafc 100644 --- a/eotsmanager/cmd/eotsd/daemon/sign.go +++ b/eotsmanager/cmd/eotsd/daemon/sign.go @@ -28,9 +28,9 @@ var SignSchnorrSig = cli.Command{ Name: "sign-schnorr", Usage: "Signs a Schnorr signature over arbitrary data with the EOTS private key.", UsageText: "sign-schnorr [file-path]", - Description: `Read the file received as argument, hash it with - sha256 and sign based on the Schnorr key associated with the key-name or btc-pk flag. - If the both flags are supplied, btc-pk takes priority`, + Description: fmt.Sprintf(`Read the file received as argument, hash it with + sha256 and sign based on the Schnorr key associated with the %s or %s flag. + If the both flags are supplied, %s takes priority`, keyNameFlag, eotsPkFlag, eotsPkFlag), Flags: []cli.Flag{ cli.StringFlag{ Name: homeFlag, @@ -42,7 +42,7 @@ var SignSchnorrSig = cli.Command{ Usage: "The name of the key to load private key for signing", }, cli.StringFlag{ - Name: fpPkFlag, + Name: eotsPkFlag, Usage: "The public key of the finality-provider to load private key for signing", }, cli.StringFlag{ @@ -65,7 +65,7 @@ var VerifySchnorrSig = cli.Command{ UsageText: "verify-schnorr-sig [file-path]", Flags: []cli.Flag{ cli.StringFlag{ - Name: fpPkFlag, + Name: eotsPkFlag, Usage: "The EOTS public key that will be used to verify the signature", Required: true, }, @@ -79,7 +79,7 @@ var VerifySchnorrSig = cli.Command{ } func SignSchnorrVerify(ctx *cli.Context) error { - fpPkStr := ctx.String(fpPkFlag) + fpPkStr := ctx.String(eotsPkFlag) signatureHex := ctx.String(signatureFlag) args := ctx.Args() @@ -123,7 +123,7 @@ func SignSchnorrVerify(ctx *cli.Context) error { func SignSchnorr(ctx *cli.Context) error { keyName := ctx.String(keyNameFlag) - fpPkStr := ctx.String(fpPkFlag) + fpPkStr := ctx.String(eotsPkFlag) passphrase := ctx.String(passphraseFlag) keyringBackend := ctx.String(keyringBackendFlag) @@ -134,7 +134,7 @@ func SignSchnorr(ctx *cli.Context) error { } if len(fpPkStr) == 0 && len(keyName) == 0 { - return fmt.Errorf("at least one of the flags: %s, %s needs to be informed", keyNameFlag, fpPkFlag) + return fmt.Errorf("at least one of the flags: %s, %s needs to be informed", keyNameFlag, eotsPkFlag) } homePath, err := getHomeFlag(ctx) diff --git a/eotsmanager/cmd/eotsd/daemon/sign_test.go b/eotsmanager/cmd/eotsd/daemon/sign_test.go index 9bfe3c08..94b8199c 100644 --- a/eotsmanager/cmd/eotsd/daemon/sign_test.go +++ b/eotsmanager/cmd/eotsd/daemon/sign_test.go @@ -52,13 +52,13 @@ func FuzzSignAndVerifySchnorrSig(f *testing.F) { fpInfoPath := filepath.Join(tempDir, "fpInfo.json") writeFpInfoToFile(r, t, fpInfoPath, keyOut.PubKeyHex) - btcPkFlag := fmt.Sprintf("--btc-pk=%s", keyOut.PubKeyHex) - dataSignedBtcPk := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, btcPkFlag}) - err = app.Run([]string{"eotsd", "verify-schnorr-sig", fpInfoPath, btcPkFlag, fmt.Sprintf("--signature=%s", dataSignedBtcPk.SchnorrSignatureHex)}) + eotsBtcPkFlag := fmt.Sprintf("--eots-pk=%s", keyOut.PubKeyHex) + dataSignedBtcPk := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, eotsBtcPkFlag}) + err = app.Run([]string{"eotsd", "verify-schnorr-sig", fpInfoPath, eotsBtcPkFlag, fmt.Sprintf("--signature=%s", dataSignedBtcPk.SchnorrSignatureHex)}) require.NoError(t, err) dataSignedKeyName := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, keyNameFlag}) - err = app.Run([]string{"eotsd", "verify-schnorr-sig", fpInfoPath, btcPkFlag, fmt.Sprintf("--signature=%s", dataSignedKeyName.SchnorrSignatureHex)}) + err = app.Run([]string{"eotsd", "verify-schnorr-sig", fpInfoPath, eotsBtcPkFlag, fmt.Sprintf("--signature=%s", dataSignedKeyName.SchnorrSignatureHex)}) require.NoError(t, err) // check if both generated signatures match @@ -66,13 +66,13 @@ func FuzzSignAndVerifySchnorrSig(f *testing.F) { require.Equal(t, dataSignedBtcPk.SchnorrSignatureHex, dataSignedKeyName.SchnorrSignatureHex) require.Equal(t, dataSignedBtcPk.SignedDataHashHex, dataSignedKeyName.SignedDataHashHex) - // sign with both keys and btc-pk, should give btc-pk preference - dataSignedBoth := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, btcPkFlag, keyNameFlag}) + // sign with both keys and eots-pk, should give eots-pk preference + dataSignedBoth := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, eotsBtcPkFlag, keyNameFlag}) require.Equal(t, dataSignedBoth, dataSignedKeyName) - // the keyname can even be from a invalid keyname, since it gives btc-pk preference + // the keyname can even be from a invalid keyname, since it gives eots-pk preference badKeyname := "badKeyName" - dataSignedBothBadKeyName := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, btcPkFlag, fmt.Sprintf("--key-name=%s", badKeyname)}) + dataSignedBothBadKeyName := appRunSignSchnorr(r, t, app, []string{fpInfoPath, hFlag, eotsBtcPkFlag, fmt.Sprintf("--key-name=%s", badKeyname)}) require.Equal(t, badKeyname, dataSignedBothBadKeyName.KeyName) require.Equal(t, dataSignedBtcPk.PubKeyHex, dataSignedBothBadKeyName.PubKeyHex) require.Equal(t, dataSignedBtcPk.SchnorrSignatureHex, dataSignedBothBadKeyName.SchnorrSignatureHex) From 3a82e96eba4b1d98896ac2c9b7b95e4703cf7c47 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 18 Jul 2024 10:14:06 -0300 Subject: [PATCH 20/21] chore: migrate from btc-pk to eots-pk in fpd related commands and docs (#524) Only modifies naming of flags, no logic is modified --- docs/finality-provider.md | 10 +++++----- finality-provider/cmd/fpd/daemon/daemon_commands.go | 6 +++--- finality-provider/cmd/fpd/daemon/export.go | 4 ++-- finality-provider/cmd/fpd/daemon/flags.go | 2 +- finality-provider/cmd/fpd/daemon/init.go | 2 +- finality-provider/cmd/fpd/daemon/start.go | 6 +++--- finality-provider/service/fp_manager.go | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/finality-provider.md b/docs/finality-provider.md index 6c8e725f..527eafc6 100644 --- a/docs/finality-provider.md +++ b/docs/finality-provider.md @@ -131,7 +131,7 @@ this value and specify a custom address using the `--rpc-listener` flag. This will also start all the registered finality provider instances except for slashed ones added in [step](#5-create-and-register-a-finality-provider). To start the daemon with a specific finality provider instance, use the -`--btc-pk` flag followed by the hex string of the BTC public key of the finality +`--eots-pk` flag followed by the hex string of the BTC public key of the finality provider (`btc_pk_hex`) obtained in [step](#5-create-and-register-a-finality-provider). @@ -175,7 +175,7 @@ the hash of the Babylon finality provider registration transaction. ```bash fpd register-finality-provider \ - --btc-pk d0fc4db48643fbb4339dc4bbf15f272411716b0d60f18bdfeb3861544bf5ef63 + --eots-pk d0fc4db48643fbb4339dc4bbf15f272411716b0d60f18bdfeb3861544bf5ef63 { "tx_hash": "800AE5BBDADE974C5FA5BD44336C7F1A952FAB9F5F9B43F7D4850BA449319BAA" } @@ -219,11 +219,11 @@ fpd list-finality-providers After the creation of the finality provider in the local db, it is possible to export the finality provider information through the `fpd export-finality-provider` command. This command connects with the `fpd` daemon to retrieve the finality -provider previously created using the flag `--btc-pk` as key. +provider previously created using the flag `--eots-pk` as key. This command also has several flag options: -- `--btc-pk` the hex string of the BTC public key. +- `--eots-pk` the hex string of the BTC public key. - `--daemon-address` the RPC server address of `fpd` daemon. - `--signed` signs the finality provider with the chain key of the PoS chain secured as a proof of untempered exported data. @@ -235,7 +235,7 @@ passphrase is required. - `--hd-path` the hd derivation path of the private key. ```shell -$ fpd export-finality-provider --btc-pk 02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077 \ +$ fpd export-finality-provider --eots-pk 02face5996b2792114677604ec9dfad4fe66eeace3df92dab834754add5bdd7077 \ --home ./export-fp/fpd --key-name finality-provider --signed ``` diff --git a/finality-provider/cmd/fpd/daemon/daemon_commands.go b/finality-provider/cmd/fpd/daemon/daemon_commands.go index cce479f9..c8334590 100644 --- a/finality-provider/cmd/fpd/daemon/daemon_commands.go +++ b/finality-provider/cmd/fpd/daemon/daemon_commands.go @@ -217,7 +217,7 @@ func runCommandLsFP(cmd *cobra.Command, args []string) error { // CommandInfoFP returns the finality-provider-info command by connecting to the fpd daemon. func CommandInfoFP() *cobra.Command { var cmd = &cobra.Command{ - Use: "finality-provider-info [fp-pk-btc-hex]", + Use: "finality-provider-info [fp-eots-pk-hex]", Aliases: []string{"fpi"}, Short: "List finality providers stored in the database.", Example: fmt.Sprintf(`fpd finality-provider-info --daemon-address %s`, defaultFpdDaemonAddress), @@ -257,7 +257,7 @@ func runCommandInfoFP(cmd *cobra.Command, args []string) error { // CommandRegisterFP returns the register-finality-provider command by connecting to the fpd daemon. func CommandRegisterFP() *cobra.Command { var cmd = &cobra.Command{ - Use: "register-finality-provider [fp-pk-btc-hex]", + Use: "register-finality-provider [fp-eots-pk-hex]", Aliases: []string{"rfp"}, Short: "Register a created finality provider to Babylon.", Example: fmt.Sprintf(`fpd register-finality-provider --daemon-address %s`, defaultFpdDaemonAddress), @@ -305,7 +305,7 @@ func runCommandRegisterFP(cmd *cobra.Command, args []string) error { // CommandAddFinalitySig returns the add-finality-sig command by connecting to the fpd daemon. func CommandAddFinalitySig() *cobra.Command { var cmd = &cobra.Command{ - Use: "add-finality-sig [fp-pk-btc-hex] [block-height]", + Use: "add-finality-sig [fp-eots-pk-hex] [block-height]", Aliases: []string{"afs"}, Short: "Send a finality signature to the consumer chain. This command should only be used for presentation/testing purposes", Example: fmt.Sprintf(`fpd add-finality-sig --daemon-address %s`, defaultFpdDaemonAddress), diff --git a/finality-provider/cmd/fpd/daemon/export.go b/finality-provider/cmd/fpd/daemon/export.go index f9d83677..d00d93c0 100644 --- a/finality-provider/cmd/fpd/daemon/export.go +++ b/finality-provider/cmd/fpd/daemon/export.go @@ -30,9 +30,9 @@ type FinalityProviderSigned struct { // CommandExportFP returns the export-finality-provider command by loading the fp and export the data. func CommandExportFP() *cobra.Command { var cmd = &cobra.Command{ - Use: "export-finality-provider [fp-btc-pk-hex]", + Use: "export-finality-provider [fp-eots-pk-hex]", Aliases: []string{"exfp"}, - Short: "It exports the finality provider by the given BTC public key.", + Short: "It exports the finality provider by the given EOTS public key.", Example: fmt.Sprintf(`fpd export-finality-provider --daemon-address %s`, defaultFpdDaemonAddress), Args: cobra.NoArgs, RunE: fpcmd.RunEWithClientCtx(runCommandExportFP), diff --git a/finality-provider/cmd/fpd/daemon/flags.go b/finality-provider/cmd/fpd/daemon/flags.go index 847a2997..0debceb2 100644 --- a/finality-provider/cmd/fpd/daemon/flags.go +++ b/finality-provider/cmd/fpd/daemon/flags.go @@ -2,7 +2,7 @@ package daemon const ( forceFlag = "force" - fpPkFlag = "btc-pk" + fpEotsPkFlag = "eots-pk" rpcListenerFlag = "rpc-listener" fpdDaemonAddressFlag = "daemon-address" keyNameFlag = "key-name" diff --git a/finality-provider/cmd/fpd/daemon/init.go b/finality-provider/cmd/fpd/daemon/init.go index 723f56ac..d5618fe5 100644 --- a/finality-provider/cmd/fpd/daemon/init.go +++ b/finality-provider/cmd/fpd/daemon/init.go @@ -36,7 +36,7 @@ func runInitCmd(ctx client.Context, cmd *cobra.Command, args []string) error { homePath = util.CleanAndExpandPath(homePath) force, err := cmd.Flags().GetBool(forceFlag) if err != nil { - return fmt.Errorf("failed to read flag %s: %w", fpPkFlag, err) + return fmt.Errorf("failed to read flag %s: %w", fpEotsPkFlag, err) } if util.FileExists(homePath) && !force { diff --git a/finality-provider/cmd/fpd/daemon/start.go b/finality-provider/cmd/fpd/daemon/start.go index 48a30ac3..43162ee3 100644 --- a/finality-provider/cmd/fpd/daemon/start.go +++ b/finality-provider/cmd/fpd/daemon/start.go @@ -29,7 +29,7 @@ func CommandStart() *cobra.Command { Args: cobra.NoArgs, RunE: fpcmd.RunEWithClientCtx(runStartCmd), } - cmd.Flags().String(fpPkFlag, "", "The public key of the finality-provider to start") + cmd.Flags().String(fpEotsPkFlag, "", "The EOTS public key of the finality-provider to start") cmd.Flags().String(passphraseFlag, "", "The pass phrase used to decrypt the private key") cmd.Flags().String(rpcListenerFlag, "", "The address that the RPC server listens to") return cmd @@ -43,9 +43,9 @@ func runStartCmd(ctx client.Context, cmd *cobra.Command, args []string) error { homePath = util.CleanAndExpandPath(homePath) flags := cmd.Flags() - fpStr, err := flags.GetString(fpPkFlag) + fpStr, err := flags.GetString(fpEotsPkFlag) if err != nil { - return fmt.Errorf("failed to read flag %s: %w", fpPkFlag, err) + return fmt.Errorf("failed to read flag %s: %w", fpEotsPkFlag, err) } rpcListener, err := flags.GetString(rpcListenerFlag) diff --git a/finality-provider/service/fp_manager.go b/finality-provider/service/fp_manager.go index 2625a029..7ecc0917 100644 --- a/finality-provider/service/fp_manager.go +++ b/finality-provider/service/fp_manager.go @@ -248,7 +248,7 @@ func (fpm *FinalityProviderManager) StartAll() error { for _, fp := range storedFps { if fp.Status == proto.FinalityProviderStatus_CREATED || fp.Status == proto.FinalityProviderStatus_SLASHED { fpm.logger.Info("the finality provider cannot be started with status", - zap.String("btc-pk", fp.GetBIP340BTCPK().MarshalHex()), + zap.String("eots-pk", fp.GetBIP340BTCPK().MarshalHex()), zap.String("status", fp.Status.String())) continue } From 937cb8c0b1126e9af50c834a5fde6f0e33e52a39 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 18 Jul 2024 10:14:23 -0300 Subject: [PATCH 21/21] feat: add validate-signed-finality-provider command (#522) Add new command helper to validate signed `MsgCreateFinalityProvider` stored in file Closes: https://github.com/babylonchain/finality-provider/issues/521 --- finality-provider/cmd/fpd/daemon/tx.go | 90 ++++++++++ finality-provider/cmd/fpd/daemon/tx_test.go | 172 ++++++++++++++++++++ finality-provider/config/config.go | 37 +++-- 3 files changed, 285 insertions(+), 14 deletions(-) create mode 100644 finality-provider/cmd/fpd/daemon/tx_test.go diff --git a/finality-provider/cmd/fpd/daemon/tx.go b/finality-provider/cmd/fpd/daemon/tx.go index 2c8ddbff..8bb903ed 100644 --- a/finality-provider/cmd/fpd/daemon/tx.go +++ b/finality-provider/cmd/fpd/daemon/tx.go @@ -1,10 +1,16 @@ package daemon import ( + "fmt" + "strings" + "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" btcstakingcli "github.com/babylonchain/babylon/x/btcstaking/client/cli" + btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" ) @@ -21,7 +27,91 @@ func CommandTxs() *cobra.Command { cmd.AddCommand( authcli.GetSignCommand(), btcstakingcli.NewCreateFinalityProviderCmd(), + NewValidateSignedFinalityProviderCmd(), ) return cmd } + +// NewValidateSignedFinalityProviderCmd returns the command line for +// tx validate-signed-finality-provider +func NewValidateSignedFinalityProviderCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "validate-signed-finality-provider [file_path_signed_msg]", + Args: cobra.ExactArgs(1), + Short: "Validates the signed MsgCreateFinalityProvider", + Long: strings.TrimSpace(` + Loads the signed MsgCreateFinalityProvider and checks if the basic + information is satisfied and the Proof of Possession is valid against the + signer of the msg and the finality provider's BTC public key + `), + Example: strings.TrimSpace( + `fdp tx validate-signed-finality-provider ./path/to/signed-msg.json`, + ), + RunE: func(cmd *cobra.Command, args []string) error { + ctx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + stdTx, err := authclient.ReadTxFromFile(ctx, args[0]) + if err != nil { + return err + } + + msgsV2, err := stdTx.GetMsgsV2() + if err != nil { + return err + } + + msgs := stdTx.GetMsgs() + if len(msgs) == 0 { + return fmt.Errorf("invalid msg, there is no msg inside %s file", args[0]) + } + + for i, sdkMsg := range msgs { + msgV2 := msgsV2[i] + msg, ok := sdkMsg.(*btcstakingtypes.MsgCreateFinalityProvider) + if !ok { + return fmt.Errorf("unable to parse %+v to MsgCreateFinalityProvider", msg) + } + + if err := msg.ValidateBasic(); err != nil { + return fmt.Errorf("error validating basic msg: %w", err) + } + + signers, err := ctx.Codec.GetMsgV2Signers(msgV2) + if err != nil { + return fmt.Errorf("failed to get signers from msg %+v: %w", msg, err) + } + + if len(signers) == 0 { + return fmt.Errorf("no signer at msg %+v", msgV2) + } + + signerAddrStr, err := ctx.Codec.InterfaceRegistry().SigningContext().AddressCodec().BytesToString(signers[0]) + if err != nil { + return err + } + + signerBbnAddr, err := sdk.AccAddressFromBech32(signerAddrStr) + if err != nil { + return fmt.Errorf("invalid signer address %s, please sign with a valid bbn address, err: %w", signerAddrStr, err) + } + + if !strings.EqualFold(msg.Addr, signerAddrStr) { + return fmt.Errorf("signer address: %s is different from finality provider address: %s", signerAddrStr, msg.Addr) + } + + if err := msg.Pop.VerifyBIP340(signerBbnAddr, msg.BtcPk); err != nil { + return fmt.Errorf("invalid Proof of Possession with signer %s: %w", signerBbnAddr.String(), err) + } + } + + _, err = cmd.OutOrStdout().Write([]byte("The signed MsgCreateFinalityProvider is valid")) + return err + }, + } + + return cmd +} diff --git a/finality-provider/cmd/fpd/daemon/tx_test.go b/finality-provider/cmd/fpd/daemon/tx_test.go new file mode 100644 index 00000000..69b8dfdf --- /dev/null +++ b/finality-provider/cmd/fpd/daemon/tx_test.go @@ -0,0 +1,172 @@ +package daemon_test + +import ( + "bytes" + "encoding/json" + "fmt" + "math/rand" + "os" + "path/filepath" + "testing" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/keys" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/spf13/cobra" + + "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/app" + "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonchain/babylon/types" + + btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" + fpcmd "github.com/babylonchain/finality-provider/finality-provider/cmd" + "github.com/babylonchain/finality-provider/finality-provider/cmd/fpd/daemon" + fpcfg "github.com/babylonchain/finality-provider/finality-provider/config" + "github.com/babylonchain/finality-provider/testutil" +) + +func FuzzNewValidateSignedFinalityProviderCmd(f *testing.F) { + testutil.AddRandomSeedsToFuzzer(f, 10) + tempApp := app.NewTmpBabylonApp() + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + rootCmdBuff := new(bytes.Buffer) + root := rootCmd(rootCmdBuff) + + tDir := t.TempDir() + tempHome := filepath.Join(tDir, "homefpnew") + homeFlag := fmt.Sprintf("--home=%s", tempHome) + + exec(t, root, rootCmdBuff, "init", homeFlag) + + keyName := datagen.GenRandomHexStr(r, 5) + kbt := "--keyring-backend=test" + + keyOut := execUnmarshal[keys.KeyOutput](t, root, rootCmdBuff, "keys", "add", keyName, homeFlag, kbt) + require.Equal(t, keyName, keyOut.Name) + + fpAddr, err := sdk.AccAddressFromBech32(keyOut.Address) + require.NoError(t, err) + + btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + pop, err := btcstakingtypes.NewPoPBTC(fpAddr, btcSK) + require.NoError(t, err) + + popHex, err := pop.ToHexStr() + require.NoError(t, err) + + bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) + + _, unsignedMsgStr := exec( + t, root, rootCmdBuff, "tx", "create-finality-provider", bip340PK.MarshalHex(), popHex, homeFlag, kbt, + fmt.Sprintf("--from=%s", keyName), "--generate-only", "--gas-prices=10ubbn", + "--commission-rate=0.05", "--moniker='niceFP'", "--identity=x", "--website=test.com", + "--security-contact=niceEmail", "--details='no Details'", + ) + + tx, err := tempApp.TxConfig().TxJSONDecoder()([]byte(unsignedMsgStr)) + require.NoError(t, err) + + txMsgs := tx.GetMsgs() + require.Len(t, txMsgs, 1) + sdkMsg := txMsgs[0] + + msg, ok := sdkMsg.(*btcstakingtypes.MsgCreateFinalityProvider) + require.True(t, ok) + require.Equal(t, msg.Addr, fpAddr.String()) + + // sends the unsigned msg to a file to be signed. + unsignedMsgFilePath := writeToTempFile(t, r, unsignedMsgStr) + + _, signedMsgStr := exec(t, root, rootCmdBuff, "tx", "sign", unsignedMsgFilePath, homeFlag, kbt, + fmt.Sprintf("--from=%s", keyName), "--offline", "--account-number=0", "--sequence=0", + ) + // sends the signed msg to a file. + signedMsgFilePath := writeToTempFile(t, r, signedMsgStr) + + tx, err = tempApp.TxConfig().TxJSONDecoder()([]byte(signedMsgStr)) + require.NoError(t, err) + + msgSigned := tx.GetMsgs()[0].(*btcstakingtypes.MsgCreateFinalityProvider) + require.Equal(t, msgSigned.Addr, fpAddr.String()) + + // executes the verification. + _, outputValidate := exec(t, root, rootCmdBuff, "tx", "validate-signed-finality-provider", signedMsgFilePath, homeFlag) + require.Equal(t, "The signed MsgCreateFinalityProvider is valid", outputValidate) + }) +} + +func rootCmd(outputBuff *bytes.Buffer) *cobra.Command { + cmd := &cobra.Command{ + Use: "fpd", + PersistentPreRunE: fpcmd.PersistClientCtx(client.Context{}.WithOutput(outputBuff)), + } + cmd.PersistentFlags().String(flags.FlagHome, fpcfg.DefaultFpdDir, "The application home directory") + + cmd.AddCommand( + daemon.CommandInit(), daemon.CommandStart(), daemon.CommandKeys(), + daemon.CommandGetDaemonInfo(), daemon.CommandCreateFP(), daemon.CommandLsFP(), + daemon.CommandInfoFP(), daemon.CommandRegisterFP(), daemon.CommandAddFinalitySig(), + daemon.CommandExportFP(), daemon.CommandTxs(), + ) + + return cmd +} + +// exec executes a command based on the cmd passed, the args should only search for subcommands, not parent commands +// it also receives rootCmdBuf as a parameter, which is the buff set in the cmd context standard output for the commands +// that do print to the context stdout instead of the root stdout. +func exec(t *testing.T, root *cobra.Command, rootCmdBuf *bytes.Buffer, args ...string) (c *cobra.Command, output string) { + buf := new(bytes.Buffer) + root.SetOut(buf) + root.SetErr(buf) + root.SetArgs(args) + + c, err := root.ExecuteC() + require.NoError(t, err) + + outStr := buf.String() + if len(outStr) > 0 { + return c, outStr + } + + _, err = buf.Write(rootCmdBuf.Bytes()) + require.NoError(t, err) + + return c, buf.String() +} + +func execUnmarshal[structure any](t *testing.T, root *cobra.Command, rootCmdBuf *bytes.Buffer, args ...string) (output structure) { + var typed structure + _, outStr := exec(t, root, rootCmdBuf, args...) + + // helpfull for debug + // fmt.Printf("\nargs %s", strings.Join(args, " ")) + // fmt.Printf("\nout %s", outStr) + + err := json.Unmarshal([]byte(outStr), &typed) + require.NoError(t, err) + + return typed +} + +func writeToTempFile(t *testing.T, r *rand.Rand, str string) (outputFilePath string) { + outputFilePath = filepath.Join(t.TempDir(), datagen.GenRandomHexStr(r, 5)) + + outPutFile, err := os.Create(outputFilePath) + require.NoError(t, err) + defer outPutFile.Close() + + _, err = outPutFile.WriteString(str) + require.NoError(t, err) + + return outputFilePath +} diff --git a/finality-provider/config/config.go b/finality-provider/config/config.go index 74e61039..9d1a69a2 100644 --- a/finality-provider/config/config.go +++ b/finality-provider/config/config.go @@ -184,22 +184,13 @@ func (cfg *Config) Validate() error { // Multiple networks can't be selected simultaneously. Count number of // network flags passed; assign active network params // while we're at it. - switch cfg.BitcoinNetwork { - case "mainnet": - cfg.BTCNetParams = chaincfg.MainNetParams - case "testnet": - cfg.BTCNetParams = chaincfg.TestNet3Params - case "regtest": - cfg.BTCNetParams = chaincfg.RegressionNetParams - case "simnet": - cfg.BTCNetParams = chaincfg.SimNetParams - case "signet": - cfg.BTCNetParams = chaincfg.SigNetParams - default: - return fmt.Errorf("invalid network: %v", cfg.BitcoinNetwork) + btcNetConfig, err := NetParamsBTC(cfg.BitcoinNetwork) + if err != nil { + return err } + cfg.BTCNetParams = btcNetConfig - _, err := net.ResolveTCPAddr("tcp", cfg.RpcListener) + _, err = net.ResolveTCPAddr("tcp", cfg.RpcListener) if err != nil { return fmt.Errorf("invalid RPC listener address %s, %w", cfg.RpcListener, err) } @@ -215,3 +206,21 @@ func (cfg *Config) Validate() error { // All good, return the sanitized result. return nil } + +// NetParamsBTC parses the BTC net params from config. +func NetParamsBTC(btcNet string) (p chaincfg.Params, err error) { + switch btcNet { + case "mainnet": + return chaincfg.MainNetParams, nil + case "testnet": + return chaincfg.TestNet3Params, nil + case "regtest": + return chaincfg.RegressionNetParams, nil + case "simnet": + return chaincfg.SimNetParams, nil + case "signet": + return chaincfg.SigNetParams, nil + default: + return p, fmt.Errorf("invalid network: %v", btcNet) + } +}