From 65922734040cd00a3971522d086863accd6bc07a Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Fri, 13 Mar 2026 15:31:47 -0400 Subject: [PATCH 01/22] evm support draft --- .github/workflows/build&release.yml | 13 + .gitignore | 1 + cmd/sncli/go.mod | 65 +- cmd/sncli/go.sum | 223 +++- docs/evm-migration.md | 366 ++++++ go.mod | 72 +- go.sum | 229 ++-- pkg/keyring/keyring.go | 51 +- pkg/keyring/keyring_test.go | 184 +++ pkg/lumera/client.go | 5 + pkg/lumera/codec/encoding.go | 6 + pkg/lumera/codec/encoding_test.go | 33 + pkg/lumera/interface.go | 4 + pkg/lumera/lumera_mock.go | 15 + pkg/lumera/modules/bank/bank_mock.go | 15 + pkg/lumera/modules/bank/impl.go | 13 + pkg/lumera/modules/bank/interface.go | 2 + pkg/testutil/lumera.go | 12 + sdk/adapters/lumera/adapter.go | 17 + sdk/task/helpers.go | 13 +- sdk/task/ica_signature.go | 12 + sdk/task/ica_signature_test.go | 89 ++ sdk/task/spendable_balance_test.go | 39 + sdk/task/task.go | 34 +- sn-manager/go.mod | 92 +- sn-manager/go.sum | 74 +- supernode/cmd/evmigration.go | 529 ++++++++ supernode/cmd/evmigration_test.go | 1071 +++++++++++++++++ supernode/cmd/start.go | 12 + supernode/config/config.go | 4 + .../reachability_active_probing_test.go | 2 + .../evmigration/evmigration_test.go | 292 +++++ tests/system/go.mod | 98 +- tests/system/go.sum | 221 +++- 34 files changed, 3458 insertions(+), 450 deletions(-) create mode 100644 docs/evm-migration.md create mode 100644 pkg/lumera/codec/encoding_test.go create mode 100644 sdk/task/spendable_balance_test.go create mode 100644 supernode/cmd/evmigration.go create mode 100644 supernode/cmd/evmigration_test.go create mode 100644 tests/integration/evmigration/evmigration_test.go diff --git a/.github/workflows/build&release.yml b/.github/workflows/build&release.yml index cd99058b..b5225901 100644 --- a/.github/workflows/build&release.yml +++ b/.github/workflows/build&release.yml @@ -72,6 +72,17 @@ jobs: echo "GHOEOF" } >> "$GITHUB_OUTPUT" + - name: Check deploy intent + id: deploy_check + run: | + TAG_MSG="${{ steps.tag_info.outputs.tag_message }}" + if echo "$TAG_MSG" | grep -qi '\[no-deploy\]'; then + echo "draft=true" >> $GITHUB_OUTPUT + echo "⚠️ [no-deploy] detected — release will be created as DRAFT" + else + echo "draft=false" >> $GITHUB_OUTPUT + fi + - name: Setup Go and dependencies uses: ./.github/actions/setup-env # with: @@ -205,6 +216,7 @@ jobs: if: success() && steps.rel_check.outputs.exists != 'true' with: tag_name: ${{ steps.tag_info.outputs.tag_name }} + draft: ${{ steps.deploy_check.outputs.draft == 'true' }} files: | release/${{ steps.vars.outputs.binary_name }}.tar.gz release/${{ steps.vars.outputs.binary_name }} @@ -216,6 +228,7 @@ jobs: if: success() && steps.rel_check.outputs.exists == 'true' with: tag_name: ${{ steps.tag_info.outputs.tag_name }} + draft: ${{ steps.deploy_check.outputs.draft == 'true' }} files: | release/${{ steps.vars.outputs.binary_name }}.tar.gz release/${{ steps.vars.outputs.binary_name }} diff --git a/.gitignore b/.gitignore index 00197fb4..e0837eb5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ tests/system/testnet tests/system/**/supernode-data* tests/system/data tests/system/1 +supernode/__debug* # env file .env /data diff --git a/cmd/sncli/go.mod b/cmd/sncli/go.mod index 6fc6fb86..1ea3493f 100644 --- a/cmd/sncli/go.mod +++ b/cmd/sncli/go.mod @@ -1,8 +1,9 @@ module github.com/LumeraProtocol/supernode/v2/cmd/sncli -go 1.25.5 +go 1.26.1 replace ( + github.com/LumeraProtocol/lumera => ../../../lumera github.com/LumeraProtocol/supernode/v2 => ../.. github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 @@ -11,17 +12,17 @@ replace ( require ( github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c - github.com/LumeraProtocol/lumera v1.11.0-rc + github.com/LumeraProtocol/lumera v1.11.0 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 - github.com/cosmos/cosmos-sdk v0.53.5 + github.com/cosmos/cosmos-sdk v0.53.6 github.com/spf13/cobra v1.10.1 - google.golang.org/grpc v1.77.0 + google.golang.org/grpc v1.79.2 google.golang.org/protobuf v1.36.11 ) require ( cosmossdk.io/api v0.9.2 // indirect - cosmossdk.io/collections v1.3.1 // indirect + cosmossdk.io/collections v1.4.0 // indirect cosmossdk.io/core v0.11.3 // indirect cosmossdk.io/depinject v1.2.1 // indirect cosmossdk.io/errors v1.0.2 // indirect @@ -29,6 +30,7 @@ require ( cosmossdk.io/math v1.5.3 // indirect cosmossdk.io/schema v1.1.0 // indirect cosmossdk.io/store v1.1.2 // indirect + cosmossdk.io/x/feegrant v0.2.0 // indirect cosmossdk.io/x/tx v0.14.0 // indirect cosmossdk.io/x/upgrade v0.2.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -41,10 +43,15 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.2.0 // indirect + github.com/bits-and-blooms/bitset v1.24.3 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect + github.com/btcsuite/btcd/btcutil v1.1.6 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.14.2 // indirect - github.com/bytedance/sonic/loader v0.4.0 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect @@ -54,18 +61,22 @@ require ( github.com/cockroachdb/pebble v1.1.5 // indirect github.com/cockroachdb/redact v1.1.6 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.20 // indirect + github.com/cometbft/cometbft v0.38.21 // indirect github.com/cometbft/cometbft-db v0.14.1 // indirect + github.com/consensys/gnark-crypto v0.18.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.1.3 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/evm v0.6.0 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/gogoproto v1.7.2 // indirect github.com/cosmos/iavl v1.2.6 // indirect github.com/cosmos/ibc-go/v10 v10.5.0 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.16.0 // indirect + github.com/cosmos/ledger-cosmos-go v1.0.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/danieljoos/wincred v1.2.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect @@ -76,10 +87,13 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect + github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/getsentry/sentry-go v0.35.0 // indirect + github.com/getsentry/sentry-go v0.42.0 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -111,6 +125,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/holiman/uint256 v1.3.2 // indirect github.com/huandu/skiplist v1.2.1 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect @@ -118,7 +133,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -141,8 +156,8 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/cors v1.11.1 // indirect @@ -156,10 +171,16 @@ require ( github.com/spf13/viper v1.21.0 // indirect github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/supranational/blst v0.3.14 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.7.0 // indirect + github.com/tidwall/btree v1.8.1 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/sjson v1.2.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v1.0.1 // indirect @@ -169,19 +190,19 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.17.0 // indirect - golang.org/x/crypto v0.47.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect - golang.org/x/net v0.48.0 // indirect + golang.org/x/net v0.49.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.2 // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/cmd/sncli/go.sum b/cmd/sncli/go.sum index 4cc94260..859e0fb0 100644 --- a/cmd/sncli/go.sum +++ b/cmd/sncli/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -56,8 +56,8 @@ cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/client/v2 v2.0.0-beta.11 h1:iHbjDw/NuNz2OVaPmx0iE9eu2HrbX+WAv2u9guRcd6o= cosmossdk.io/client/v2 v2.0.0-beta.11/go.mod h1:ZmmxMUpALO2r1aG6fNOonE7f8I1g/WsafJgVAeQ0ffs= -cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= -cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= +cosmossdk.io/collections v1.4.0 h1:b373bkxCxKiRbapxZ42TRmcKJEnBVBebdQVk9I5IkkE= +cosmossdk.io/collections v1.4.0/go.mod h1:gxbieVY3tjbvWlkm3yOXf7sGyDrVi12haZH+sek6whw= cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= @@ -111,8 +111,6 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.11.0-rc h1:ISJLUhjihuOterLMHpgGWpMZmybR1vmQLNgmSHkc1WA= -github.com/LumeraProtocol/lumera v1.11.0-rc/go.mod h1:p2sZZG3bLzSBdaW883qjuU3DXXY4NJzTTwLywr8uI0w= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= @@ -121,6 +119,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.6 h1:k1/zc2jNfeiZBA5aFTRy37jlBIuCkXCm0XmvpzCKI9I= @@ -159,19 +159,33 @@ github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE5 github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.24.3 h1:Bte86SlO3lwPQqww+7BE9ZuUCKIjfqnG5jtEyqA9y9Y= github.com/bits-and-blooms/bitset v1.24.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= 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.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.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU= github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protoc-gen-validate v1.3.0 h1:0lq2b9qA1uzfVnMW6oFJepiVVihDOOzj+VuTGSX4EgE= @@ -180,10 +194,10 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/ github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= -github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE= -github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980= -github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o= -github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -213,8 +227,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-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= 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= @@ -235,10 +249,12 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1: github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coder/websocket v1.8.7 h1:jiep6gmlfP/yq2w1gBoubJEXL9gf8x3bp6lzzX8nJxE= github.com/coder/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -github.com/cometbft/cometbft v0.38.20 h1:i9v9rvh3Z4CZvGSWrByAOpiqNq5WLkat3r/tE/B49RU= -github.com/cometbft/cometbft v0.38.20/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= +github.com/cometbft/cometbft v0.38.21 h1:qcIJSH9LiwU5s6ZgKR5eRbsLNucbubfraDs5bzgjtOI= +github.com/cometbft/cometbft v0.38.21/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= github.com/cometbft/cometbft-db v0.14.1 h1:SxoamPghqICBAIcGpleHbmoPqy+crij/++eZz3DlerQ= github.com/cometbft/cometbft-db v0.14.1/go.mod h1:KHP1YghilyGV/xjD5DP3+2hyigWx0WTp9X+0Gnx0RxQ= +github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= +github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -251,8 +267,10 @@ github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOP github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= 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.53.5 h1:JPue+SFn2gyDzTV9TYb8mGpuIH3kGt7WbGadulkpTcU= -github.com/cosmos/cosmos-sdk v0.53.5/go.mod h1:AQJx0jpon70WAD4oOs/y+SlST4u7VIwEPR6F8S7JMdo= +github.com/cosmos/cosmos-sdk v0.53.6 h1:aJeInld7rbsHtH1qLHu2aZJF9t40mGlqp3ylBLDT0HI= +github.com/cosmos/cosmos-sdk v0.53.6/go.mod h1:N6YuprhAabInbT3YGumGDKONbvPX5dNro7RjHvkQoKE= +github.com/cosmos/evm v0.6.0 h1:jwJerLS7btDgDpZOYy7lUC+1rNRCGGE80TJ6r4guufo= +github.com/cosmos/evm v0.6.0/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= 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= @@ -268,10 +286,16 @@ github.com/cosmos/ibc-go/v10 v10.5.0 h1:NI+cX04fXdu9JfP0V0GYeRi1ENa7PPdq0BYtVYo8 github.com/cosmos/ibc-go/v10 v10.5.0/go.mod h1:a74pAPUSJ7NewvmvELU74hUClJhwnmm5MGbEaiTw/kE= github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= -github.com/cosmos/ledger-cosmos-go v0.16.0 h1:YKlWPG9NnGZIEUb2bEfZ6zhON1CHlNTg0QKRRGcNEd0= -github.com/cosmos/ledger-cosmos-go v0.16.0/go.mod h1:WrM2xEa8koYoH2DgeIuZXNarF7FGuZl3mrIOnp3Dp0o= +github.com/cosmos/ledger-cosmos-go v1.0.0 h1:jNKW89nPf0vR0EkjHG8Zz16h6p3zqwYEOxlHArwgYtw= +github.com/cosmos/ledger-cosmos-go v1.0.0/go.mod h1:mGaw2wDOf+Z6SfRJsMGxU9DIrBa4du0MAiPlpPhLAOE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= +github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= +github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= @@ -281,10 +305,15 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo= github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= @@ -322,12 +351,16 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 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/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= +github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= +github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-ethereum v1.15.11 h1:JK73WKeu0WC0O1eyX+mdQAVHUV+UR1a9VB/domDngBU= github.com/ethereum/go-ethereum v1.15.11/go.mod h1:mf8YiHIb0GR4x4TipcvBUPxJLw1mFdmxzoDi11sDRoI= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 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.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= @@ -345,8 +378,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/getsentry/sentry-go v0.35.0 h1:+FJNlnjJsZMG3g0/rmmP7GiKjQoUF5EXfEtBwtPtkzY= -github.com/getsentry/sentry-go v0.35.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= +github.com/getsentry/sentry-go v0.42.0 h1:eeFMACuZTbUQf90RE8dE4tXeSe4CZyfvR1MBL7RLEt8= +github.com/getsentry/sentry-go v0.42.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -376,6 +409,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -399,6 +434,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -513,6 +550,7 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -575,6 +613,8 @@ github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8 github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -583,6 +623,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.1 h1:dTi93MgjwErA/8idWTzIw4Y1kZsMWx35fmI2c8Rij7w= github.com/huandu/skiplist v1.2.1/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -595,7 +637,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -628,8 +673,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -645,6 +690,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -673,6 +720,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -723,20 +772,24 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU= -github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= +github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -770,6 +823,16 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 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= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -808,8 +871,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b 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.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= 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= @@ -817,11 +880,13 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx 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.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= 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= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/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= @@ -845,6 +910,8 @@ github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6v github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shamaton/msgpack/v2 v2.2.3 h1:uDOHmxQySlvlUYfQwdjxyybAOzjlQsD1Vjy+4jmO9NM= github.com/shamaton/msgpack/v2 v2.2.3/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -901,16 +968,34 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 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.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= +github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= -github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= +github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= +github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= +github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= +github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= @@ -925,6 +1010,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/golem v0.27.0 h1:IbBjGIXF3SoGOZHsILJvIM/F/ylwJzMcHAcggiqniPw= github.com/zondax/golem v0.27.0/go.mod h1:AmorCgJPt00L8xN1VrMBe13PSifoZksnQ1Ge906bu4A= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -947,22 +1034,22 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= 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= @@ -988,8 +1075,8 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU= @@ -1013,8 +1100,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= 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= @@ -1056,6 +1143,7 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1091,6 +1179,7 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1111,8 +1200,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= 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= @@ -1122,8 +1211,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= 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= @@ -1182,10 +1271,12 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1220,8 +1311,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -1231,8 +1322,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= 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= @@ -1248,8 +1339,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= 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= @@ -1399,10 +1490,10 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= 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= @@ -1429,8 +1520,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/docs/evm-migration.md b/docs/evm-migration.md new file mode 100644 index 00000000..9824d7a6 --- /dev/null +++ b/docs/evm-migration.md @@ -0,0 +1,366 @@ +# EVM Account Migration + +This document describes the EVM migration support added to the Lumera supernode. +It covers how operators migrate from legacy secp256k1 keys (coin type 118) to +EVM-compatible eth_secp256k1 keys (coin type 60), the architecture of the +migration flow, and all related code changes. + +## Overview + +The Lumera chain now requires EVM-compatible keys (`eth_secp256k1`, BIP44 coin +type 60). Existing supernodes that were set up with legacy Cosmos keys +(`secp256k1`, coin type 118) must migrate their on-chain state — balances, +delegations, supernode registration, and optionally validator state — to a new +address derived from the same mnemonic under the EVM HD path. + +The migration is: +- **One-time**: runs automatically at supernode startup when a legacy key is detected +- **Rerunnable**: safe to retry if interrupted at any point +- **Self-authenticating**: uses dual signatures (legacy + new key) embedded in the + message, so no Cosmos-level tx signing is needed + +## Operator Guide + +### Prerequisites + +1. Your supernode binary must be the EVM-compatible version. +2. The connected Lumera chain must have the `evm` module active. +3. You need the **mnemonic** used to create your original supernode key. + +### Migration Steps + +1. **Derive your new EVM key** from the same mnemonic: + ```bash + supernode keys recover --name evm-key --mnemonic "your twelve or twenty four words ..." + ``` + This creates an `eth_secp256k1` key under the name `evm-key` using HD path + `m/44'/60'/0'/0/0`. The resulting address will be different from your legacy + address — this is expected. + +2. **Add `evm_key_name` to your config.yaml** under the `supernode` section: + ```yaml + supernode: + key_name: mykey # your existing legacy key name + evm_key_name: evm-key # the name you used in step 1 + identity: lumera1... # your current legacy address + ``` + +3. **Restart the supernode**. On startup it will: + - Detect the legacy `secp256k1` key under `key_name` + - Validate that `evm_key_name` points to a valid `eth_secp256k1` key + - Query the chain for an existing migration record (handles reruns) + - Run a pre-flight `MigrationEstimate` to check if the migration would succeed + - Sign the migration payload with both keys + - Broadcast `MsgClaimLegacyAccount` (or `MsgMigrateValidator` for validators) + - Wait for block confirmation (DeliverTx) + - Delete the legacy key from the keyring + - Update `config.yaml`: `key_name` -> `evm-key`, `identity` -> new address, + `evm_key_name` cleared + +4. **After migration completes**, your config will look like: + ```yaml + supernode: + key_name: evm-key + identity: lumera1 + ``` + The `evm_key_name` field is automatically removed. No further action is needed. + +### Troubleshooting + +| Error | Cause | Fix | +| ----- | ----- | --- | +| `no evm_key_name configured` | Legacy key detected but config missing `evm_key_name` | Add `evm_key_name` to config and restart | +| `not an eth_secp256k1 key` | `evm_key_name` points to a secp256k1 key (wrong derivation) | Re-derive using `supernode keys recover` (uses coin type 60) | +| `new address mismatch` | On-chain migration record has a different destination address than your local EVM key | Your `evm_key_name` doesn't match the key originally used for migration; fix the config | +| `migration estimate indicates migration would fail` | Chain rejected the pre-flight check | Check `rejection_reason` in logs; migration may be disabled or account may not exist | +| `migration tx was not confirmed` | Tx was not included in a block within 60s | Restart to retry; the check is idempotent | +| `failed to save updated config` | Config file write error after successful migration | Manually update config as instructed in the error message | + +## Chain-Side Reference + +The on-chain `x/evmigration` module is documented in detail in the Lumera chain +repo at `docs/evm-integration.md` (section "Legacy Account Migration"). Key +aspects relevant to supernode operators: + +### What the chain does when it processes the migration message + +**`MsgClaimLegacyAccount` (non-validator accounts):** + +1. Pre-checks: params enabled, migration window open, rate limit, dual-signature verification +2. Withdraw pending distribution rewards to legacy bank balance +3. Re-key staking (delegations, unbonding, redelegations) +4. Migrate auth account record (vesting-aware) +5. Transfer all bank balances from legacy to new address +6. Finalize vesting at new address (if applicable) +7. Re-key authz grants and feegrant allowances +8. Update supernode account field +9. Update action creator/supernode references +10. Update claim destAddress references +11. Store MigrationRecord, increment counters, emit event + +**`MsgMigrateValidator` (validator operator accounts):** + +Same as above, plus validator record re-keying (operator address, consensus key +mapping, power index updates). The chain rejects `MsgClaimLegacyAccount` for +validator operators with `ErrUseValidatorMigration`. + +### Migration parameters (chain-side) + +| Param | Default | Description | +| ----- | ------- | ----------- | +| `enable_migration` | `true` | Master switch | +| `migration_end_time` | `0` | Unix timestamp deadline (0 = no deadline) | +| `max_migrations_per_block` | `50` | Rate limit | +| `max_validator_delegations` | `2000` | Max delegators for validator migration | + +### Fee waiving + +Migration transactions are fee-exempt on-chain (the new address has zero balance +before migration). The `ante/evmigration_fee_decorator.go` decorator handles this. + +## Architecture + +### Migration Flow + +``` +Startup + | + v +requireEVMChain() + | Queries upgrade module for "evm" module version. + | Fails fast if chain doesn't have EVM support. + v +ensureLegacyAccountMigrated() + | + v +isLegacyKey(key_name)? + |-- No --> return nil (already EVM, no migration needed) + |-- Yes --> continue + v +Validate evm_key_name exists and is eth_secp256k1 + v +Query MigrationRecord(legacy_address) + |-- Record exists, NewAddress matches --> skip broadcast (already migrated) + |-- Record exists, NewAddress differs --> ERROR (config mismatch) + |-- Query error --> proceed anyway (best-effort) + |-- No record --> continue to broadcast + v +Query MigrationEstimate(legacy_address) + |-- WouldSucceed=false --> ERROR (with rejection reason) + |-- Query error --> proceed anyway, default isValidator=false + |-- WouldSucceed=true --> capture IsValidator flag + v +Build payload: "lumera-evm-migration:{claim|validator}::" + v +Dual sign: + - Legacy: kr.Sign(SHA256(payload)) -- secp256k1 internally SHA256s again + - EVM: kr.Sign(payload) -- eth_secp256k1 internally Keccak-256s + v +Build message: + - IsValidator=true --> MsgMigrateValidator + - IsValidator=false --> MsgClaimLegacyAccount + v +broadcastMigrationTx() + | Simulate gas -> broadcast SYNC -> poll GetTx for block confirmation + v +Verify new address registered as supernode (non-fatal) + v +Delete legacy key from keyring + v +Update config (key_name, identity, evm_key_name) and save +``` + +### Signing Protocol + +The chain expects different signing protocols for each key type: + +**Legacy (secp256k1):** +``` +supernode: hash = SHA256(payload) + sig = kr.Sign(hash) -- internally: Sign(SHA256(hash)) +chain: VerifySignature(hash, sig) -- internally: verify(SHA256(hash), sig) +``` + +**EVM (eth_secp256k1):** +``` +supernode: sig = kr.Sign(payload) -- internally: Sign(Keccak256(payload)) +chain: VerifySignature(payload, sig) -- internally: verify(Keccak256(payload), sig) +``` + +### Key Architectural Decisions + +- **No `kr.Rename`**: The Cosmos SDK `Rename` method uses amino armor export/import + internally, which doesn't support `eth_secp256k1` keys. Instead, after migration + the EVM key keeps its original name and `config.yaml key_name` is updated to point + to it. + +- **SYNC broadcast + polling**: `BROADCAST_MODE_SYNC` only waits for `CheckTx`. + Local state (keyring, config) is only mutated after `waitForTxConfirmation` polls + `GetTx` and confirms block inclusion via `DeliverTx`. + +- **`migrationChainClient` interface**: Chain interactions (queries + broadcast) are + abstracted behind an interface, enabling comprehensive unit testing without a live + gRPC connection. + +## Code Changes + +### New Files + +| File | Description | +| ---- | ----------- | +| `supernode/cmd/evmigration.go` | Core migration logic: chain detection, key validation, dual signing, broadcast, config update | +| `supernode/cmd/evmigration_test.go` | Unit tests with mock chain client | +| `tests/integration/evmigration/evmigration_test.go` | Integration tests for keyring lifecycle, signing protocol, config persistence | + +### Modified Files + +| File | Changes | +| ---- | ------- | +| `pkg/keyring/keyring.go` | Switched to EVM defaults: `DefaultHDPath = "m/44'/60'/0'/0/0"`, `EthSecp256k1Option()`, `evmcryptocodec.RegisterInterfaces()` | +| `pkg/keyring/keyring_test.go` | Added 10 tests for EVM key creation, derivation, signing, legacy-vs-EVM address differences | +| `pkg/lumera/codec/encoding.go` | Registers `evmcryptocodec` and `evmigrationtypes` interfaces | +| `pkg/lumera/interface.go` | Added `Conn() *grpc.ClientConn` to Client interface | +| `pkg/lumera/client.go` | Implemented `Conn()` method | +| `pkg/lumera/lumera_mock.go` | Added `Conn()` to mock client | +| `pkg/testutil/lumera.go` | Added `Conn()` to `MockLumeraClient` | +| `supernode/config/config.go` | Added `EVMKeyName string` field to `SupernodeConfig` | +| `supernode/cmd/start.go` | Integrated `requireEVMChain()` and `ensureLegacyAccountMigrated()` at startup | +| `go.mod` / `go.sum` | Added `github.com/cosmos/evm` dependency | + +### Key Types and Functions + +#### `supernode/cmd/evmigration.go` + +```go +// Interface for testability +type migrationChainClient interface { + MigrationRecord(ctx, legacyAddr) -> (*QueryMigrationRecordResponse, error) + MigrationEstimate(ctx, legacyAddr) -> (*QueryMigrationEstimateResponse, error) + BroadcastMigrationTx(ctx, msg) -> error +} + +// Production implementation +type grpcMigrationClient struct { conn *grpc.ClientConn } + +// Core functions +func requireEVMChain(ctx, conn) error +func isLegacyKey(kr, keyName) (bool, error) +func isEthSecp256k1Key(kr, keyName) (bool, error) +func ensureLegacyAccountMigrated(ctx, kr, cfg, chainClient, snModule) error +func broadcastMigrationTx(ctx, conn, msg) error +func waitForTxConfirmation(ctx, txClient, txHash) error +``` + +#### `pkg/keyring/keyring.go` + +```go +const DefaultHDPath = "m/44'/60'/0'/0/0" // EVM coin type 60 + +func InitKeyring(cfg) // Uses EthSecp256k1Option() +func CreateNewAccount(kr, name) // Creates eth_secp256k1 key +func RecoverAccountFromMnemonic(kr, name, mnemonic) // Recovers with eth_secp256k1 +func DerivePrivKeyFromMnemonic(mnemonic, hdPath) // Derives eth_secp256k1.PrivKey +``` + +#### `supernode/config/config.go` + +```go +type SupernodeConfig struct { + KeyName string `yaml:"key_name"` + Identity string `yaml:"identity"` + EVMKeyName string `yaml:"evm_key_name,omitempty"` // NEW + // ... +} +``` + +## Test Coverage + +### Unit Tests (`supernode/cmd/evmigration_test.go`) + +**Key type detection (5 tests):** + +- `TestIsLegacyKey_WithSecp256k1` — detects legacy key +- `TestIsLegacyKey_WithEthSecp256k1` — rejects EVM key as legacy +- `TestIsLegacyKey_KeyNotFound` — handles missing key +- `TestIsEthSecp256k1Key_WithEVMKey` — detects EVM key +- `TestIsEthSecp256k1Key_WithLegacyKey` — rejects legacy key as EVM + +**Early-return / validation (7 tests):** + +- `TestEnsureLegacyAccountMigrated_NoMigrationNeeded` — no-op for EVM keys +- `TestEnsureLegacyAccountMigrated_LegacyKeyNoEVMKeyName` — error when evm_key_name missing +- `TestEnsureLegacyAccountMigrated_EVMKeyNotFound` — error when EVM key not in keyring +- `TestEnsureLegacyAccountMigrated_EVMKeyWrongType` — error when EVM key is wrong algorithm +- `TestEnsureLegacyAccountMigrated_AddressCollision` — validates different addresses +- `TestEnsureLegacyAccountMigrated_Idempotent_AlreadyEVM` — no-op when already EVM +- `TestEnsureLegacyAccountMigrated_KeyNameNotFound` — error when key missing + +**Already-migrated / rerun (4 tests):** + +- `TestEnsureLegacyAccountMigrated_AlreadyMigrated_MatchingAddress` — skip broadcast, clean up +- `TestEnsureLegacyAccountMigrated_AlreadyMigrated_MismatchedAddress` — error on address mismatch +- `TestEnsureLegacyAccountMigrated_AlreadyMigrated_ConfigPersisted` — skip broadcast, verify config file saved to disk +- `TestEnsureLegacyAccountMigrated_MigrationRecordQueryError_ProceedsToMigrate` — resilient to query failures +- `TestEnsureLegacyAccountMigrated_MigrationRecordNilRecord_ProceedsToMigrate` — nil Record field in response proceeds to broadcast + +**Validator migration (5 tests):** + +- `TestEnsureLegacyAccountMigrated_ValidatorUsesMsgMigrateValidator` — correct message for validators +- `TestEnsureLegacyAccountMigrated_ValidatorFullHappyPath` — full validator flow: MsgMigrateValidator broadcast, key delete, config save, disk persistence +- `TestEnsureLegacyAccountMigrated_NonValidatorUsesMsgClaimLegacyAccount` — correct message for non-validators +- `TestEnsureLegacyAccountMigrated_EstimateErrorFallsBackToNonValidator` — defaults to claim on error +- `TestEnsureLegacyAccountMigrated_EstimateWouldNotSucceed` — blocks on failed estimate + +**Failure handling (3 tests):** + +- `TestEnsureLegacyAccountMigrated_BroadcastFails` — preserves legacy key on broadcast error +- `TestEnsureLegacyAccountMigrated_BroadcastFails_PreservesFullState` — verifies all local state (key, config, identity) unchanged on DeliverTx failure +- `TestEnsureLegacyAccountMigrated_ConfigSaveFailsAfterKeyDelete` — handles partial failure + +**Tx confirmation (`waitForTxConfirmation`) (4 tests):** + +- `TestWaitForTxConfirmation_Success` — polls through not-found and nil responses until confirmed +- `TestWaitForTxConfirmation_DeliverTxFailure` — returns error with code/codespace/rawlog on non-zero DeliverTx code +- `TestWaitForTxConfirmation_ContextCancelled` — respects context cancellation +- `TestWaitForTxConfirmation_Timeout` — returns error when context deadline expires + +**Supernode verification (2 tests):** + +- `TestEnsureLegacyAccountMigrated_SupernodeVerificationFails_NonFatal` — query error is non-fatal, migration completes +- `TestEnsureLegacyAccountMigrated_SupernodeVerificationReturnsNil_NonFatal` — nil supernode result is non-fatal + +**Message fields and resilience (2 tests):** + +- `TestEnsureLegacyAccountMigrated_MessageFieldsCorrect` — verifies addresses, public keys, and signatures in broadcasted message +- `TestEnsureLegacyAccountMigrated_BothQueriesFail_StillBroadcasts` — both MigrationRecord and MigrationEstimate fail, still broadcasts with defaults + +**End-to-end (1 test):** + +- `TestEnsureLegacyAccountMigrated_FullHappyPath` — broadcast -> key delete -> config save -> verify + +**Keyring / config helpers (4 tests):** + +- `TestEnsureLegacyAccountMigrated_ValidationPassesBeforeNetwork` +- `TestKeyDeleteAfterMigration` +- `TestConfigUpdateAfterMigration` +- `TestConfigSaveCreatesFile` + +### Keyring Unit Tests (`pkg/keyring/keyring_test.go`) + +- `TestGetBech32Address` — bech32 encoding +- `TestDefaultHDPath_IsCoinType60` — verifies coin type 60 +- `TestCreateNewAccount_ProducesEthSecp256k1Key` — eth_secp256k1 creation +- `TestRecoverAccountFromMnemonic_ProducesEthSecp256k1Key` — recovery +- `TestRecoverAccountFromMnemonic_Deterministic` — deterministic derivation +- `TestDerivePrivKeyFromMnemonic_ReturnsEthSecp256k1` — private key type +- `TestDerivePrivKeyFromMnemonic_MatchesKeyring` — derivation consistency +- `TestLegacyAndEVMKeys_ProduceDifferentAddresses` — coin type 118 vs 60 +- `TestSignBytes_WithEVMKey` — signing +- `TestGetAddress_WithEVMKey` — address retrieval + +### Integration Tests (`tests/integration/evmigration/evmigration_test.go`) + +- `TestFullMigrationKeyringFlow` — complete lifecycle: create legacy key, import EVM key from same mnemonic, dual-sign payload, delete legacy key, verify EVM key accessible +- `TestConfigPersistenceAfterMigration` — save/reload config, verify identity updated and evm_key_name cleared, verify omitempty in raw YAML +- `TestDualSigningProtocol` — validates exact signing protocol: SHA256 pre-hash for legacy, raw for EVM; verifies cross-protocol signatures don't validate +- `TestMigrationIdempotency` — post-migration state: legacy key gone, EVM key is eth_secp256k1, second migration check is no-op diff --git a/go.mod b/go.mod index ef4abf9b..4fc54e1a 100644 --- a/go.mod +++ b/go.mod @@ -1,24 +1,30 @@ module github.com/LumeraProtocol/supernode/v2 -go 1.25.5 +go 1.26.1 replace ( + // Use local Lumera with EVM support (evmigration, erc20policy, etc.) + github.com/LumeraProtocol/lumera => ../lumera github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 + // cosmos/evm requires a forked go-ethereum with custom EVM operation methods + github.com/ethereum/go-ethereum => github.com/cosmos/go-ethereum v1.16.2-cosmos-1 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 nhooyr.io/websocket => github.com/coder/websocket v1.8.7 ) require ( cosmossdk.io/math v1.5.3 + cosmossdk.io/x/upgrade v0.2.0 github.com/AlecAivazis/survey/v2 v2.3.7 github.com/DataDog/zstd v1.5.7 github.com/LumeraProtocol/lumera v1.11.2-0.20260331140230-4aeb5d0d7a89 github.com/LumeraProtocol/rq-go v0.2.1 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/cenkalti/backoff/v4 v4.3.0 - github.com/cometbft/cometbft v0.38.20 + github.com/cometbft/cometbft v0.38.21 github.com/cosmos/btcutil v1.0.5 - github.com/cosmos/cosmos-sdk v0.53.5 + github.com/cosmos/cosmos-sdk v0.53.6 + github.com/cosmos/evm v0.6.0 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/gogoproto v1.7.2 github.com/cosmos/ibc-go/v10 v10.5.0 @@ -40,11 +46,11 @@ require ( go.uber.org/mock v0.6.0 go.uber.org/ratelimit v0.3.1 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.47.0 + golang.org/x/crypto v0.48.0 golang.org/x/sync v0.19.0 - golang.org/x/sys v0.40.0 - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 - google.golang.org/grpc v1.77.0 + golang.org/x/sys v0.41.0 + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 + google.golang.org/grpc v1.79.2 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.4.1 @@ -52,15 +58,15 @@ require ( require ( cosmossdk.io/api v0.9.2 // indirect - cosmossdk.io/collections v1.3.1 // indirect + cosmossdk.io/collections v1.4.0 // indirect cosmossdk.io/core v0.11.3 // indirect cosmossdk.io/depinject v1.2.1 // indirect cosmossdk.io/errors v1.0.2 // indirect cosmossdk.io/log v1.6.1 // indirect cosmossdk.io/schema v1.1.0 // indirect cosmossdk.io/store v1.1.2 // indirect + cosmossdk.io/x/feegrant v0.2.0 // indirect cosmossdk.io/x/tx v0.14.0 // indirect - cosmossdk.io/x/upgrade v0.2.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect @@ -70,9 +76,14 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.2.0 // indirect + github.com/bits-and-blooms/bitset v1.24.3 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect + github.com/btcsuite/btcd/btcutil v1.1.6 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.14.2 // indirect - github.com/bytedance/sonic/loader v0.4.0 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/cockroachdb/errors v1.12.0 // indirect @@ -82,12 +93,15 @@ require ( github.com/cockroachdb/redact v1.1.6 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft-db v0.14.1 // indirect + github.com/consensys/gnark-crypto v0.18.0 // indirect github.com/cosmos/cosmos-db v1.1.3 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.2.6 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.16.0 // indirect + github.com/cosmos/ledger-cosmos-go v1.0.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/danieljoos/wincred v1.2.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect @@ -97,10 +111,13 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect + github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/getsentry/sentry-go v0.35.0 // indirect + github.com/getsentry/sentry-go v0.42.0 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -129,13 +146,14 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/holiman/uint256 v1.3.2 // indirect github.com/huandu/skiplist v1.2.1 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -158,8 +176,8 @@ require ( github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/cors v1.11.1 // indirect @@ -174,12 +192,18 @@ require ( github.com/spf13/viper v1.21.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/supranational/blst v0.3.14 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.7.0 // indirect + github.com/tidwall/btree v1.8.1 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/sjson v1.2.5 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect @@ -187,18 +211,18 @@ require ( go.etcd.io/bbolt v1.4.0-alpha.1 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.17.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect - golang.org/x/mod v0.31.0 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/tools v0.40.0 // indirect + golang.org/x/mod v0.32.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.41.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.2 // indirect lukechampine.com/uint128 v1.3.0 // indirect diff --git a/go.sum b/go.sum index 1c799cc9..64cd09a5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -56,8 +56,8 @@ cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/client/v2 v2.0.0-beta.11 h1:iHbjDw/NuNz2OVaPmx0iE9eu2HrbX+WAv2u9guRcd6o= cosmossdk.io/client/v2 v2.0.0-beta.11/go.mod h1:ZmmxMUpALO2r1aG6fNOonE7f8I1g/WsafJgVAeQ0ffs= -cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= -cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= +cosmossdk.io/collections v1.4.0 h1:b373bkxCxKiRbapxZ42TRmcKJEnBVBebdQVk9I5IkkE= +cosmossdk.io/collections v1.4.0/go.mod h1:gxbieVY3tjbvWlkm3yOXf7sGyDrVi12haZH+sek6whw= cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= @@ -125,6 +125,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.6 h1:k1/zc2jNfeiZBA5aFTRy37jlBIuCkXCm0XmvpzCKI9I= @@ -163,19 +165,33 @@ github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE5 github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.24.3 h1:Bte86SlO3lwPQqww+7BE9ZuUCKIjfqnG5jtEyqA9y9Y= github.com/bits-and-blooms/bitset v1.24.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= 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.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.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU= github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protoc-gen-validate v1.3.0 h1:0lq2b9qA1uzfVnMW6oFJepiVVihDOOzj+VuTGSX4EgE= @@ -184,10 +200,10 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/ github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= -github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE= -github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980= -github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o= -github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -217,8 +233,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-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= 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= @@ -239,10 +255,12 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1: github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coder/websocket v1.8.7 h1:jiep6gmlfP/yq2w1gBoubJEXL9gf8x3bp6lzzX8nJxE= github.com/coder/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -github.com/cometbft/cometbft v0.38.20 h1:i9v9rvh3Z4CZvGSWrByAOpiqNq5WLkat3r/tE/B49RU= -github.com/cometbft/cometbft v0.38.20/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= +github.com/cometbft/cometbft v0.38.21 h1:qcIJSH9LiwU5s6ZgKR5eRbsLNucbubfraDs5bzgjtOI= +github.com/cometbft/cometbft v0.38.21/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= github.com/cometbft/cometbft-db v0.14.1 h1:SxoamPghqICBAIcGpleHbmoPqy+crij/++eZz3DlerQ= github.com/cometbft/cometbft-db v0.14.1/go.mod h1:KHP1YghilyGV/xjD5DP3+2hyigWx0WTp9X+0Gnx0RxQ= +github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= +github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -255,10 +273,14 @@ github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOP github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= 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.53.5 h1:JPue+SFn2gyDzTV9TYb8mGpuIH3kGt7WbGadulkpTcU= -github.com/cosmos/cosmos-sdk v0.53.5/go.mod h1:AQJx0jpon70WAD4oOs/y+SlST4u7VIwEPR6F8S7JMdo= +github.com/cosmos/cosmos-sdk v0.53.6 h1:aJeInld7rbsHtH1qLHu2aZJF9t40mGlqp3ylBLDT0HI= +github.com/cosmos/cosmos-sdk v0.53.6/go.mod h1:N6YuprhAabInbT3YGumGDKONbvPX5dNro7RjHvkQoKE= +github.com/cosmos/evm v0.6.0 h1:jwJerLS7btDgDpZOYy7lUC+1rNRCGGE80TJ6r4guufo= +github.com/cosmos/evm v0.6.0/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= 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/go-ethereum v1.16.2-cosmos-1 h1:QIaIS6HIdPSBdTvpFhxswhMLUJgcr4irbd2o9ZKldAI= +github.com/cosmos/go-ethereum v1.16.2-cosmos-1/go.mod h1:X5CIOyo8SuK1Q5GnaEizQVLHT/DfsiGWuNeVdQcEMNA= 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= @@ -272,10 +294,14 @@ github.com/cosmos/ibc-go/v10 v10.5.0 h1:NI+cX04fXdu9JfP0V0GYeRi1ENa7PPdq0BYtVYo8 github.com/cosmos/ibc-go/v10 v10.5.0/go.mod h1:a74pAPUSJ7NewvmvELU74hUClJhwnmm5MGbEaiTw/kE= github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= -github.com/cosmos/ledger-cosmos-go v0.16.0 h1:YKlWPG9NnGZIEUb2bEfZ6zhON1CHlNTg0QKRRGcNEd0= -github.com/cosmos/ledger-cosmos-go v0.16.0/go.mod h1:WrM2xEa8koYoH2DgeIuZXNarF7FGuZl3mrIOnp3Dp0o= +github.com/cosmos/ledger-cosmos-go v1.0.0 h1:jNKW89nPf0vR0EkjHG8Zz16h6p3zqwYEOxlHArwgYtw= +github.com/cosmos/ledger-cosmos-go v1.0.0/go.mod h1:mGaw2wDOf+Z6SfRJsMGxU9DIrBa4du0MAiPlpPhLAOE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= +github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= @@ -287,10 +313,15 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo= github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= @@ -330,18 +361,22 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 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/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= -github.com/ethereum/go-ethereum v1.15.11 h1:JK73WKeu0WC0O1eyX+mdQAVHUV+UR1a9VB/domDngBU= -github.com/ethereum/go-ethereum v1.15.11/go.mod h1:mf8YiHIb0GR4x4TipcvBUPxJLw1mFdmxzoDi11sDRoI= +github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= +github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 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.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -353,8 +388,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/getsentry/sentry-go v0.35.0 h1:+FJNlnjJsZMG3g0/rmmP7GiKjQoUF5EXfEtBwtPtkzY= -github.com/getsentry/sentry-go v0.35.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= +github.com/getsentry/sentry-go v0.42.0 h1:eeFMACuZTbUQf90RE8dE4tXeSe4CZyfvR1MBL7RLEt8= +github.com/getsentry/sentry-go v0.42.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -410,6 +445,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -524,6 +561,7 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -588,6 +626,8 @@ github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -596,6 +636,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.1 h1:dTi93MgjwErA/8idWTzIw4Y1kZsMWx35fmI2c8Rij7w= github.com/huandu/skiplist v1.2.1/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -608,7 +650,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -643,8 +688,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kolesa-team/go-webp v1.0.4 h1:wQvU4PLG/X7RS0vAeyhiivhLRoxfLVRlDq4I3frdxIQ= @@ -662,6 +707,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -694,6 +741,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -703,6 +752,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -712,6 +763,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -746,20 +799,24 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU= -github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= +github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -793,6 +850,16 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 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= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -833,8 +900,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b 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.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= 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= @@ -842,11 +909,13 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx 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.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= 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= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/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= @@ -870,6 +939,8 @@ github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6v github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shamaton/msgpack/v2 v2.2.3 h1:uDOHmxQySlvlUYfQwdjxyybAOzjlQsD1Vjy+4jmO9NM= github.com/shamaton/msgpack/v2 v2.2.3/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -932,12 +1003,24 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 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.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= +github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= -github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= +github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= @@ -946,6 +1029,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= @@ -984,22 +1069,22 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= 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= @@ -1025,8 +1110,8 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU= @@ -1050,8 +1135,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= 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= @@ -1096,8 +1181,9 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= -golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +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= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1133,6 +1219,7 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1153,8 +1240,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= 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= @@ -1164,8 +1251,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= 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= @@ -1226,10 +1313,12 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1266,8 +1355,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -1277,8 +1366,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= 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= @@ -1295,8 +1384,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= 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= @@ -1365,8 +1454,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= 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= @@ -1448,10 +1537,10 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= 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= @@ -1478,8 +1567,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/pkg/keyring/keyring.go b/pkg/keyring/keyring.go index 76fb1f67..3795be03 100644 --- a/pkg/keyring/keyring.go +++ b/pkg/keyring/keyring.go @@ -7,15 +7,17 @@ import ( "io" "os" "strings" + "sync" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/hd" sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" + evmcryptocodec "github.com/cosmos/evm/crypto/codec" + "github.com/cosmos/evm/crypto/ethsecp256k1" + evmhd "github.com/cosmos/evm/crypto/hd" "github.com/cosmos/go-bip39" "github.com/LumeraProtocol/supernode/v2/supernode/config" @@ -23,18 +25,35 @@ import ( const ( DefaultBIP39Passphrase = "" - DefaultHDPath = "m/44'/118'/0'/0/0" + DefaultHDPath = "m/44'/60'/0'/0/0" AccountAddressPrefix = "lumera" KeyringServiceName = "supernode-keyring" defaultEntropySize = 256 ) +var initSDKConfigOnce sync.Once + func InitSDKConfig() { - cfg := types.GetConfig() - cfg.SetBech32PrefixForAccount(AccountAddressPrefix, AccountAddressPrefix+"pub") - cfg.SetBech32PrefixForValidator(AccountAddressPrefix+"valoper", AccountAddressPrefix+"valoperpub") - cfg.SetBech32PrefixForConsensusNode(AccountAddressPrefix+"valcons", AccountAddressPrefix+"valconspub") - cfg.Seal() + initSDKConfigOnce.Do(func() { + cfg := types.GetConfig() + + // Cosmos SDK config is process-global and may already be sealed by another + // package during startup. In that case there is nothing left to mutate, so + // avoid crashing paths like `supernode --help`. + defer func() { + if r := recover(); r != nil { + if fmt.Sprint(r) == "Config is sealed" { + return + } + panic(r) + } + }() + + cfg.SetBech32PrefixForAccount(AccountAddressPrefix, AccountAddressPrefix+"pub") + cfg.SetBech32PrefixForValidator(AccountAddressPrefix+"valoper", AccountAddressPrefix+"valoperpub") + cfg.SetBech32PrefixForConsensusNode(AccountAddressPrefix+"valcons", AccountAddressPrefix+"valconspub") + cfg.Seal() + }) } func InitKeyring(cfg config.KeyringConfig) (sdkkeyring.Keyring, error) { @@ -57,9 +76,10 @@ func InitKeyring(cfg config.KeyringConfig) (sdkkeyring.Keyring, error) { reg := codectypes.NewInterfaceRegistry() cryptocodec.RegisterInterfaces(reg) + evmcryptocodec.RegisterInterfaces(reg) cdc := codec.NewProtoCodec(reg) - return sdkkeyring.New(KeyringServiceName, backend, dir, reader, cdc) + return sdkkeyring.New(KeyringServiceName, backend, dir, reader, cdc, evmhd.EthSecp256k1Option()) } // buildReaderAndPossiblySwapStdin returns the reader handed to Cosmos-SDK. @@ -178,25 +198,24 @@ func CreateNewAccount(kr sdkkeyring.Keyring, name string) (string, *sdkkeyring.R if err != nil { return "", nil, err } - info, err := kr.NewAccount(name, mn, DefaultBIP39Passphrase, DefaultHDPath, hd.Secp256k1) + info, err := kr.NewAccount(name, mn, DefaultBIP39Passphrase, DefaultHDPath, evmhd.EthSecp256k1) return mn, info, err } func RecoverAccountFromMnemonic(kr sdkkeyring.Keyring, name, mnemonic string) (*sdkkeyring.Record, error) { - return kr.NewAccount(name, mnemonic, DefaultBIP39Passphrase, DefaultHDPath, hd.Secp256k1) + return kr.NewAccount(name, mnemonic, DefaultBIP39Passphrase, DefaultHDPath, evmhd.EthSecp256k1) } -func DerivePrivKeyFromMnemonic(mnemonic, hdPath string) (*secp256k1.PrivKey, error) { +func DerivePrivKeyFromMnemonic(mnemonic, hdPath string) (*ethsecp256k1.PrivKey, error) { if hdPath == "" { hdPath = DefaultHDPath } - seed := bip39.NewSeed(mnemonic, DefaultBIP39Passphrase) - master, ch := hd.ComputeMastersFromSeed(seed) - derived, err := hd.DerivePrivateKeyForPath(master, ch, hdPath) + deriveFn := evmhd.EthSecp256k1.Derive() + privKeyBytes, err := deriveFn(mnemonic, DefaultBIP39Passphrase, hdPath) if err != nil { return nil, err } - return &secp256k1.PrivKey{Key: derived}, nil + return ðsecp256k1.PrivKey{Key: privKeyBytes}, nil } func SignBytes(kr sdkkeyring.Keyring, name string, bz []byte) ([]byte, error) { diff --git a/pkg/keyring/keyring_test.go b/pkg/keyring/keyring_test.go index 828999be..dad4b00e 100644 --- a/pkg/keyring/keyring_test.go +++ b/pkg/keyring/keyring_test.go @@ -2,6 +2,8 @@ package keyring import ( "bytes" + "os" + "os/exec" "testing" "github.com/cosmos/cosmos-sdk/codec" @@ -9,9 +11,25 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" + evmcryptocodec "github.com/cosmos/evm/crypto/codec" + "github.com/cosmos/evm/crypto/ethsecp256k1" + evmhd "github.com/cosmos/evm/crypto/hd" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) +// newEVMKeyring creates an in-memory keyring supporting both key algorithms. +func newEVMKeyring(t *testing.T) sdkkeyring.Keyring { + t.Helper() + reg := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(reg) + evmcryptocodec.RegisterInterfaces(reg) + cdc := codec.NewProtoCodec(reg) + return sdkkeyring.NewInMemory(cdc, evmhd.EthSecp256k1Option()) +} + func TestGetBech32Address(t *testing.T) { reg := codectypes.NewInterfaceRegistry() cryptocodec.RegisterInterfaces(reg) @@ -42,3 +60,169 @@ func TestGetBech32Address(t *testing.T) { t.Fatalf("decoded address mismatch") } } + +func TestDefaultHDPath_IsCoinType60(t *testing.T) { + assert.Equal(t, "m/44'/60'/0'/0/0", DefaultHDPath, + "DefaultHDPath should use EVM coin type 60") +} + +func TestCreateNewAccount_ProducesEthSecp256k1Key(t *testing.T) { + kr := newEVMKeyring(t) + + _, rec, err := CreateNewAccount(kr, "test-evm") + require.NoError(t, err) + + pubKey, err := rec.GetPubKey() + require.NoError(t, err) + + _, isEthSecp := pubKey.(*ethsecp256k1.PubKey) + assert.True(t, isEthSecp, "CreateNewAccount should produce eth_secp256k1 key") + + _, isLegacy := pubKey.(*secp256k1.PubKey) + assert.False(t, isLegacy, "CreateNewAccount should NOT produce legacy secp256k1 key") +} + +func TestRecoverAccountFromMnemonic_ProducesEthSecp256k1Key(t *testing.T) { + kr := newEVMKeyring(t) + + mn, err := GenerateMnemonic() + require.NoError(t, err) + + rec, err := RecoverAccountFromMnemonic(kr, "recovered", mn) + require.NoError(t, err) + + pubKey, err := rec.GetPubKey() + require.NoError(t, err) + + _, isEthSecp := pubKey.(*ethsecp256k1.PubKey) + assert.True(t, isEthSecp, "recovered key should be eth_secp256k1") +} + +func TestRecoverAccountFromMnemonic_Deterministic(t *testing.T) { + mn, err := GenerateMnemonic() + require.NoError(t, err) + + kr1 := newEVMKeyring(t) + rec1, err := RecoverAccountFromMnemonic(kr1, "key1", mn) + require.NoError(t, err) + addr1, err := rec1.GetAddress() + require.NoError(t, err) + + kr2 := newEVMKeyring(t) + rec2, err := RecoverAccountFromMnemonic(kr2, "key2", mn) + require.NoError(t, err) + addr2, err := rec2.GetAddress() + require.NoError(t, err) + + assert.Equal(t, addr1.String(), addr2.String(), + "same mnemonic should produce same address") +} + +func TestDerivePrivKeyFromMnemonic_ReturnsEthSecp256k1(t *testing.T) { + mn, err := GenerateMnemonic() + require.NoError(t, err) + + privKey, err := DerivePrivKeyFromMnemonic(mn, "") + require.NoError(t, err) + require.NotNil(t, privKey) + + assert.IsType(t, ðsecp256k1.PrivKey{}, privKey) + assert.Len(t, privKey.Key, 32, "private key should be 32 bytes") +} + +func TestDerivePrivKeyFromMnemonic_MatchesKeyring(t *testing.T) { + mn, err := GenerateMnemonic() + require.NoError(t, err) + + // Derive via standalone function. + privKey, err := DerivePrivKeyFromMnemonic(mn, "") + require.NoError(t, err) + derivedAddr := sdk.AccAddress(privKey.PubKey().Address()) + + // Recover via keyring. + kr := newEVMKeyring(t) + rec, err := RecoverAccountFromMnemonic(kr, "test", mn) + require.NoError(t, err) + krAddr, err := rec.GetAddress() + require.NoError(t, err) + + assert.Equal(t, krAddr.String(), derivedAddr.String(), + "DerivePrivKeyFromMnemonic and RecoverAccountFromMnemonic should produce same address") +} + +func TestLegacyAndEVMKeys_ProduceDifferentAddresses(t *testing.T) { + kr := newEVMKeyring(t) + mn, err := GenerateMnemonic() + require.NoError(t, err) + + // Create legacy key (coin type 118). + legacyRec, err := kr.NewAccount("legacy", mn, "", "m/44'/118'/0'/0/0", hd.Secp256k1) + require.NoError(t, err) + legacyAddr, err := legacyRec.GetAddress() + require.NoError(t, err) + + // Create EVM key (coin type 60) with same mnemonic. + evmRec, err := kr.NewAccount("evm", mn, "", "m/44'/60'/0'/0/0", evmhd.EthSecp256k1) + require.NoError(t, err) + evmAddr, err := evmRec.GetAddress() + require.NoError(t, err) + + assert.NotEqual(t, legacyAddr.String(), evmAddr.String(), + "same mnemonic with different coin types should produce different addresses") + + // Verify key types. + legacyPub, _ := legacyRec.GetPubKey() + _, isLegacy := legacyPub.(*secp256k1.PubKey) + assert.True(t, isLegacy) + + evmPub, _ := evmRec.GetPubKey() + _, isEVM := evmPub.(*ethsecp256k1.PubKey) + assert.True(t, isEVM) +} + +func TestSignBytes_WithEVMKey(t *testing.T) { + kr := newEVMKeyring(t) + _, _, err := CreateNewAccount(kr, "signer") + require.NoError(t, err) + + msg := []byte("hello world") + sig, err := SignBytes(kr, "signer", msg) + require.NoError(t, err) + assert.NotEmpty(t, sig, "signature should not be empty") +} + +func TestGetAddress_WithEVMKey(t *testing.T) { + kr := newEVMKeyring(t) + _, _, err := CreateNewAccount(kr, "test") + require.NoError(t, err) + + addr, err := GetAddress(kr, "test") + require.NoError(t, err) + assert.NotEmpty(t, addr.String()) +} + +func TestInitSDKConfig_IsIdempotent(t *testing.T) { + InitSDKConfig() + InitSDKConfig() + + cfg := sdk.GetConfig() + assert.Equal(t, AccountAddressPrefix, cfg.GetBech32AccountAddrPrefix()) + assert.Equal(t, AccountAddressPrefix+"pub", cfg.GetBech32AccountPubPrefix()) + assert.Equal(t, AccountAddressPrefix+"valoper", cfg.GetBech32ValidatorAddrPrefix()) + assert.Equal(t, AccountAddressPrefix+"valoperpub", cfg.GetBech32ValidatorPubPrefix()) + assert.Equal(t, AccountAddressPrefix+"valcons", cfg.GetBech32ConsensusAddrPrefix()) + assert.Equal(t, AccountAddressPrefix+"valconspub", cfg.GetBech32ConsensusPubPrefix()) +} + +func TestInitSDKConfig_SealedConfigDoesNotPanic(t *testing.T) { + if os.Getenv("SUPERNODE_TEST_SEALED_CONFIG") == "1" { + sdk.GetConfig().Seal() + InitSDKConfig() + return + } + + cmd := exec.Command(os.Args[0], "-test.run=TestInitSDKConfig_SealedConfigDoesNotPanic") + cmd.Env = append(os.Environ(), "SUPERNODE_TEST_SEALED_CONFIG=1") + out, err := cmd.CombinedOutput() + require.NoError(t, err, "subprocess should succeed without panic: %s", string(out)) +} diff --git a/pkg/lumera/client.go b/pkg/lumera/client.go index be5cd9bf..58a0dbb4 100644 --- a/pkg/lumera/client.go +++ b/pkg/lumera/client.go @@ -14,6 +14,7 @@ import ( "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode_msg" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/tx" + "google.golang.org/grpc" ) type lumeraClient struct { @@ -188,6 +189,10 @@ func (c *lumeraClient) Node() node.Module { return c.nodeMod } +func (c *lumeraClient) Conn() *grpc.ClientConn { + return c.conn.GetConn() +} + func (c *lumeraClient) Close() error { if c.conn != nil { return c.conn.Close() diff --git a/pkg/lumera/codec/encoding.go b/pkg/lumera/codec/encoding.go index 0d295241..0df1dc13 100644 --- a/pkg/lumera/codec/encoding.go +++ b/pkg/lumera/codec/encoding.go @@ -4,13 +4,16 @@ import ( "sync" actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types" + evmigrationtypes "github.com/LumeraProtocol/lumera/x/evmigration/types" sntypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + evmcryptocodec "github.com/cosmos/evm/crypto/codec" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" ) // EncodingConfig specifies the concrete encoding types to use for Lumera client @@ -48,8 +51,11 @@ func NewEncodingConfig() EncodingConfig { // RegisterInterfaces registers all interface types with the interface registry func RegisterInterfaces(registry codectypes.InterfaceRegistry) { cryptocodec.RegisterInterfaces(registry) + evmcryptocodec.RegisterInterfaces(registry) authtypes.RegisterInterfaces(registry) + vestingtypes.RegisterInterfaces(registry) actiontypes.RegisterInterfaces(registry) + evmigrationtypes.RegisterInterfaces(registry) sntypes.RegisterInterfaces(registry) } diff --git a/pkg/lumera/codec/encoding_test.go b/pkg/lumera/codec/encoding_test.go new file mode 100644 index 00000000..78112ee3 --- /dev/null +++ b/pkg/lumera/codec/encoding_test.go @@ -0,0 +1,33 @@ +package codec + +import ( + "testing" + "time" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/stretchr/testify/require" +) + +func TestEncodingConfigUnpacksDelayedVestingAccount(t *testing.T) { + cfg := GetEncodingConfig() + + addr := sdk.AccAddress([]byte("delayed-vesting-addr")).String() + base := authtypes.NewBaseAccountWithAddress(sdk.MustAccAddressFromBech32(addr)) + coins := sdk.NewCoins(sdk.NewInt64Coin("ulume", 1)) + bva, err := vestingtypes.NewBaseVestingAccount(base, coins, time.Now().Unix()) + require.NoError(t, err) + delayed := vestingtypes.NewDelayedVestingAccountRaw(bva) + + anyAcc, err := codectypes.NewAnyWithValue(delayed) + require.NoError(t, err) + + var unpacked sdk.AccountI + err = cfg.InterfaceRegistry.UnpackAny(anyAcc, &unpacked) + require.NoError(t, err) + + _, ok := unpacked.(*vestingtypes.DelayedVestingAccount) + require.True(t, ok) +} diff --git a/pkg/lumera/interface.go b/pkg/lumera/interface.go index f660e9c2..a31dabba 100644 --- a/pkg/lumera/interface.go +++ b/pkg/lumera/interface.go @@ -14,6 +14,7 @@ import ( "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode_msg" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/tx" + "google.golang.org/grpc" ) // Client defines the main interface for interacting with Lumera blockchain @@ -29,6 +30,9 @@ type Client interface { Tx() tx.Module Node() node.Module + // Conn returns the underlying gRPC connection for direct queries. + Conn() *grpc.ClientConn + Close() error } diff --git a/pkg/lumera/lumera_mock.go b/pkg/lumera/lumera_mock.go index 95efcfbf..68e1277b 100644 --- a/pkg/lumera/lumera_mock.go +++ b/pkg/lumera/lumera_mock.go @@ -23,6 +23,7 @@ import ( supernode_msg "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode_msg" tx "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/tx" gomock "go.uber.org/mock/gomock" + grpc "google.golang.org/grpc" ) // MockClient is a mock of Client interface. @@ -133,6 +134,20 @@ func (mr *MockClientMockRecorder) Bank() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bank", reflect.TypeOf((*MockClient)(nil).Bank)) } +// Conn mocks base method. +func (m *MockClient) Conn() *grpc.ClientConn { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Conn") + ret0, _ := ret[0].(*grpc.ClientConn) + return ret0 +} + +// Conn indicates an expected call of Conn. +func (mr *MockClientMockRecorder) Conn() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Conn", reflect.TypeOf((*MockClient)(nil).Conn)) +} + // Close mocks base method. func (m *MockClient) Close() error { m.ctrl.T.Helper() diff --git a/pkg/lumera/modules/bank/bank_mock.go b/pkg/lumera/modules/bank/bank_mock.go index cfbfb50f..95737667 100644 --- a/pkg/lumera/modules/bank/bank_mock.go +++ b/pkg/lumera/modules/bank/bank_mock.go @@ -55,3 +55,18 @@ func (mr *MockModuleMockRecorder) Balance(ctx, address, denom any) *gomock.Call mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Balance", reflect.TypeOf((*MockModule)(nil).Balance), ctx, address, denom) } + +// SpendableBalanceByDenom mocks base method. +func (m *MockModule) SpendableBalanceByDenom(ctx context.Context, address, denom string) (*types.QuerySpendableBalanceByDenomResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SpendableBalanceByDenom", ctx, address, denom) + ret0, _ := ret[0].(*types.QuerySpendableBalanceByDenomResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SpendableBalanceByDenom indicates an expected call of SpendableBalanceByDenom. +func (mr *MockModuleMockRecorder) SpendableBalanceByDenom(ctx, address, denom any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpendableBalanceByDenom", reflect.TypeOf((*MockModule)(nil).SpendableBalanceByDenom), ctx, address, denom) +} diff --git a/pkg/lumera/modules/bank/impl.go b/pkg/lumera/modules/bank/impl.go index 157eb97f..22251568 100644 --- a/pkg/lumera/modules/bank/impl.go +++ b/pkg/lumera/modules/bank/impl.go @@ -28,3 +28,16 @@ func (m *module) Balance(ctx context.Context, address string, denom string) (*ba } return m.client.Balance(ctx, &banktypes.QueryBalanceRequest{Address: address, Denom: denom}) } + +func (m *module) SpendableBalanceByDenom(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) { + if address == "" { + return nil, fmt.Errorf("address cannot be empty") + } + if denom == "" { + return nil, fmt.Errorf("denom cannot be empty") + } + return m.client.SpendableBalanceByDenom(ctx, &banktypes.QuerySpendableBalanceByDenomRequest{ + Address: address, + Denom: denom, + }) +} diff --git a/pkg/lumera/modules/bank/interface.go b/pkg/lumera/modules/bank/interface.go index 84dd11fd..ea620739 100644 --- a/pkg/lumera/modules/bank/interface.go +++ b/pkg/lumera/modules/bank/interface.go @@ -12,6 +12,8 @@ import ( type Module interface { // Balance returns the balance for a specific denom at an address. Balance(ctx context.Context, address string, denom string) (*banktypes.QueryBalanceResponse, error) + // SpendableBalanceByDenom returns the spendable balance for a specific denom at an address. + SpendableBalanceByDenom(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) } // NewModule constructs a bank Module backed by the given gRPC connection. diff --git a/pkg/testutil/lumera.go b/pkg/testutil/lumera.go index d7bd1212..c7bff8c7 100644 --- a/pkg/testutil/lumera.go +++ b/pkg/testutil/lumera.go @@ -20,6 +20,7 @@ import ( sdkmath "cosmossdk.io/math" cmtservice "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" + "google.golang.org/grpc" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdktypes "github.com/cosmos/cosmos-sdk/types" sdktx "github.com/cosmos/cosmos-sdk/types/tx" @@ -119,6 +120,11 @@ func (c *MockLumeraClient) Node() node.Module { return c.nodeMod } +// Conn returns nil for the mock (no real gRPC connection in tests). +func (c *MockLumeraClient) Conn() *grpc.ClientConn { + return nil +} + // Close closes all connections func (c *MockLumeraClient) Close() error { return nil @@ -133,6 +139,12 @@ func (m *MockBankModule) Balance(ctx context.Context, address string, denom stri return &banktypes.QueryBalanceResponse{Balance: &sdktypes.Coin{Denom: denom, Amount: sdkmath.NewInt(1_000_000)}}, nil } +func (m *MockBankModule) SpendableBalanceByDenom(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) { + return &banktypes.QuerySpendableBalanceByDenomResponse{ + Balance: &sdktypes.Coin{Denom: denom, Amount: sdkmath.NewInt(1_000_000)}, + }, nil +} + // MockAuthModule implements the auth.Module interface for testing type MockAuthModule struct{} diff --git a/sdk/adapters/lumera/adapter.go b/sdk/adapters/lumera/adapter.go index 0e41c77e..24457323 100644 --- a/sdk/adapters/lumera/adapter.go +++ b/sdk/adapters/lumera/adapter.go @@ -49,6 +49,8 @@ type Client interface { QueryTxsByEvents(ctx context.Context, query string, page, limit uint64) (*sdktx.GetTxsEventResponse, error) // GetBalance returns the bank balance for the given address and denom. GetBalance(ctx context.Context, address string, denom string) (*banktypes.QueryBalanceResponse, error) + // GetSpendableBalance returns the spendable bank balance for the given address and denom. + GetSpendableBalance(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) // GetActionParams returns the action module parameters. GetActionParams(ctx context.Context) (*actiontypes.QueryParamsResponse, error) // GetActionFee returns the fee amount for a given data size (in KB) for RequestAction. @@ -394,6 +396,21 @@ func (a *Adapter) GetBalance(ctx context.Context, address string, denom string) return resp, nil } +func (a *Adapter) GetSpendableBalance(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) { + a.logger.Debug(ctx, "Querying spendable bank balance", "address", address, "denom", denom) + resp, err := a.client.Bank().SpendableBalanceByDenom(ctx, address, denom) + if err != nil { + a.logger.Error(ctx, "Failed to query spendable bank balance", "address", address, "denom", denom, "error", err) + return nil, fmt.Errorf("failed to query spendable bank balance: %w", err) + } + if resp == nil || resp.Balance == nil { + a.logger.Error(ctx, "Nil spendable balance response", "address", address, "denom", denom) + return nil, fmt.Errorf("nil spendable balance response for %s %s", address, denom) + } + a.logger.Debug(ctx, "Successfully fetched spendable bank balance", "amount", resp.Balance.Amount.String(), "denom", resp.Balance.Denom) + return resp, nil +} + // SubmitCascadeClientFailureEvidence submits client-observed cascade failure evidence to x/audit. func (a *Adapter) SubmitCascadeClientFailureEvidence( ctx context.Context, diff --git a/sdk/task/helpers.go b/sdk/task/helpers.go index 3e2a4ff3..afd2b8bd 100644 --- a/sdk/task/helpers.go +++ b/sdk/task/helpers.go @@ -96,8 +96,17 @@ func (m *ManagerImpl) validateSignature(ctx context.Context, action lumera.Actio return nil } - // If ICA validation wasn't attempted earlier, try it as a fallback. - if icaErr == nil { + // Only try ICA fallback for explicit ICA config or when the creator account is actually an ICA. + shouldTryICA := strings.TrimSpace(m.config.Account.ICAOwnerHRP) != "" || strings.TrimSpace(m.config.Account.ICAOwnerKeyName) != "" + if !shouldTryICA { + var err error + shouldTryICA, err = m.actionCreatorIsICA(ctx, action.Creator) + if err != nil { + m.logger.Debug(ctx, "ICA fallback eligibility check failed", "actionID", action.ID, "error", err) + } + } + + if icaErr == nil && shouldTryICA { icaErr = m.validateICASignature(ctx, action, dataHashB64, signature) if icaErr == nil { return nil diff --git a/sdk/task/ica_signature.go b/sdk/task/ica_signature.go index 1994975a..7992b66e 100644 --- a/sdk/task/ica_signature.go +++ b/sdk/task/ica_signature.go @@ -126,6 +126,18 @@ func (m *ManagerImpl) getICAOwnerAndAppPubkeyFromChain(ctx context.Context, acti return icaAccount.AccountOwner, appPubkey, nil } +func (m *ManagerImpl) actionCreatorIsICA(ctx context.Context, creator string) (bool, error) { + if creator == "" { + return false, nil + } + account, err := m.lumeraClient.AccountByAddress(ctx, creator) + if err != nil { + return false, fmt.Errorf("query account: %w", err) + } + _, ok := account.(*icatypes.InterchainAccount) + return ok, nil +} + func findRequestActionAppPubkey(ctx context.Context, client lumera.Client, actionID string, creator string) ([]byte, error) { if actionID == "" { return nil, fmt.Errorf("action id is empty") diff --git a/sdk/task/ica_signature_test.go b/sdk/task/ica_signature_test.go index 9d57a915..f7051bb9 100644 --- a/sdk/task/ica_signature_test.go +++ b/sdk/task/ica_signature_test.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "fmt" "testing" + "time" actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types" sntypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types" @@ -18,6 +19,7 @@ import ( sdktx "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" icatypes "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/types" "github.com/stretchr/testify/require" @@ -28,6 +30,7 @@ type fakeLumeraClient struct { queryTxsByEvents func(ctx context.Context, query string, page, limit uint64) (*sdktx.GetTxsEventResponse, error) decodeCascadeMetadata func(ctx context.Context, action lumera.Action) (actiontypes.CascadeMetadata, error) verifySignature func(ctx context.Context, accountAddr string, data []byte, signature []byte) error + getSpendableBalance func(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) } func (f *fakeLumeraClient) AccountInfoByAddress(context.Context, string) (*authtypes.QueryAccountInfoResponse, error) { @@ -82,6 +85,56 @@ func (f *fakeLumeraClient) GetBalance(context.Context, string, string) (*banktyp return nil, nil } +func (f *fakeLumeraClient) GetSpendableBalance(ctx context.Context, address string, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) { + if f.getSpendableBalance == nil { + return nil, nil + } + return f.getSpendableBalance(ctx, address, denom) +} + +func newDelayedVestingAccount(t *testing.T, addr string) sdk.AccountI { + t.Helper() + base := authtypes.NewBaseAccountWithAddress(sdk.MustAccAddressFromBech32(addr)) + bva, err := vestingtypes.NewBaseVestingAccount(base, sdk.NewCoins(sdk.NewInt64Coin("ulume", 1)), time.Now().Unix()) + require.NoError(t, err) + return vestingtypes.NewDelayedVestingAccountRaw(bva) +} + +func TestValidateSignature_AllowsDelayedVestingCreator(t *testing.T) { + creator := sdk.AccAddress([]byte("delayed-vesting-creator")).String() + icaQueried := false + key := secp256k1.GenPrivKey() + sig, err := key.Sign([]byte("payload-b64")) + require.NoError(t, err) + + fake := &fakeLumeraClient{ + accountByAddress: func(ctx context.Context, addr string) (sdk.AccountI, error) { + return newDelayedVestingAccount(t, addr), nil + }, + queryTxsByEvents: func(ctx context.Context, query string, page, limit uint64) (*sdktx.GetTxsEventResponse, error) { + icaQueried = true + return nil, fmt.Errorf("unexpected ICA query") + }, + decodeCascadeMetadata: func(ctx context.Context, action lumera.Action) (actiontypes.CascadeMetadata, error) { + return actiontypes.CascadeMetadata{DataHash: "payload-b64"}, nil + }, + verifySignature: func(ctx context.Context, accountAddr string, data []byte, signature []byte) error { + return nil + }, + } + + cfg := config.NewConfig(config.AccountConfig{}, config.LumeraConfig{}) + m := &ManagerImpl{ + lumeraClient: fake, + config: cfg, + logger: log.NewNoopLogger(), + } + + err = m.validateSignature(context.Background(), lumera.Action{Creator: creator, ID: "action-vesting"}, base64.StdEncoding.EncodeToString(sig)) + require.NoError(t, err) + require.False(t, icaQueried) +} + func (f *fakeLumeraClient) GetActionParams(context.Context) (*actiontypes.QueryParamsResponse, error) { return nil, nil } @@ -233,3 +286,39 @@ func TestValidateSignatureFallsBackToICA(t *testing.T) { err = m.validateSignature(context.Background(), lumera.Action{Creator: creator, ID: "action-1"}, sigB64) require.NoError(t, err) } + +func TestValidateSignatureDoesNotTryICAForNonICAAccount(t *testing.T) { + creator := sdk.AccAddress([]byte("base-account-creator")).String() + dataHash := "payload-b64" + key := secp256k1.GenPrivKey() + sig, err := key.Sign([]byte(dataHash)) + require.NoError(t, err) + + icaQueried := false + fake := &fakeLumeraClient{ + accountByAddress: func(ctx context.Context, addr string) (sdk.AccountI, error) { + return authtypes.NewBaseAccountWithAddress(sdk.MustAccAddressFromBech32(addr)), nil + }, + queryTxsByEvents: func(ctx context.Context, query string, page, limit uint64) (*sdktx.GetTxsEventResponse, error) { + icaQueried = true + return nil, fmt.Errorf("unexpected ICA query") + }, + decodeCascadeMetadata: func(ctx context.Context, action lumera.Action) (actiontypes.CascadeMetadata, error) { + return actiontypes.CascadeMetadata{DataHash: dataHash}, nil + }, + verifySignature: func(ctx context.Context, accountAddr string, data []byte, signature []byte) error { + return fmt.Errorf("invalid signature") + }, + } + + cfg := config.NewConfig(config.AccountConfig{}, config.LumeraConfig{}) + m := &ManagerImpl{ + lumeraClient: fake, + config: cfg, + logger: log.NewNoopLogger(), + } + + err = m.validateSignature(context.Background(), lumera.Action{Creator: creator, ID: "action-1"}, base64.StdEncoding.EncodeToString(sig)) + require.Error(t, err) + require.False(t, icaQueried) +} diff --git a/sdk/task/spendable_balance_test.go b/sdk/task/spendable_balance_test.go new file mode 100644 index 00000000..139360da --- /dev/null +++ b/sdk/task/spendable_balance_test.go @@ -0,0 +1,39 @@ +package task + +import ( + "context" + "testing" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" +) + +func TestHasMinimumSpendableBalance_AllowsVestingAccountWithUnlockedFunds(t *testing.T) { + fake := &fakeLumeraClient{ + getSpendableBalance: func(context.Context, string, string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) { + return &banktypes.QuerySpendableBalanceByDenomResponse{ + Balance: &types.Coin{Denom: "ulume", Amount: sdkmath.NewInt(1_500_000)}, + }, nil + }, + } + + ok, reason := hasMinimumSpendableBalance(context.Background(), fake, "lumera1vestingwithspendable", "ulume", sdkmath.NewInt(minEligibleBalanceULUME)) + require.True(t, ok) + require.Empty(t, reason) +} + +func TestHasMinimumSpendableBalance_RejectsVestingAccountWithoutUnlockedFunds(t *testing.T) { + fake := &fakeLumeraClient{ + getSpendableBalance: func(context.Context, string, string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) { + return &banktypes.QuerySpendableBalanceByDenomResponse{ + Balance: &types.Coin{Denom: "ulume", Amount: sdkmath.ZeroInt()}, + }, nil + }, + } + + ok, reason := hasMinimumSpendableBalance(context.Background(), fake, "lumera1vestinglockedonly", "ulume", sdkmath.NewInt(minEligibleBalanceULUME)) + require.False(t, ok) + require.Contains(t, reason, "insufficient spendable balance") +} diff --git a/sdk/task/task.go b/sdk/task/task.go index 671ca689..7d43ef8e 100644 --- a/sdk/task/task.go +++ b/sdk/task/task.go @@ -103,12 +103,27 @@ func (t *BaseTask) orderByXORDistance(sns lumera.Supernodes) lumera.Supernodes { return orderSupernodesByDeterministicDistance(seed, sns) } +func hasMinimumSpendableBalance(ctx context.Context, client lumera.Client, address string, denom string, min sdkmath.Int) (bool, string) { + bal, err := client.GetSpendableBalance(ctx, address, denom) + if err != nil { + return false, fmt.Sprintf("spendable balance check failed: %v", err) + } + if bal == nil || bal.Balance == nil { + return false, "spendable balance info unavailable" + } + if bal.Balance.Amount.LT(min) { + actualLUME := bal.Balance.Amount.Quo(sdkmath.NewInt(1_000_000)) + return false, fmt.Sprintf("insufficient spendable balance: %s LUME (need >= 1 LUME)", actualLUME.String()) + } + return true, "" +} + // filterEligibleSupernodesParallel // Fast, bounded-concurrency discovery that keeps only nodes that pass: // // (1) gRPC Health SERVING // (2) Peers > 1 (via Status API; single-line gate for basic network liveness) -// (3) On-chain balance >= 1 LUME (in ulume) +// (3) On-chain spendable balance >= 1 LUME (in ulume) // // Strategy: // - Spawn at most prefilterParallelism goroutines (bounded fan-out). @@ -214,26 +229,17 @@ func (t *BaseTask) filterEligibleSupernodesParallel(parent context.Context, sns res.client = client }() - // Step 1.2.2 — Balance probe (chain) — independent of gRPC dial + // Step 1.2.2 — Spendable-balance probe (chain) — independent of gRPC dial go func() { res := balanceResult{ok: false} defer func() { balanceCh <- res }() - bal, err := t.client.GetBalance(probeCtx, sn.CosmosAddress, denom) - if err == nil && bal != nil && bal.Balance != nil && !bal.Balance.Amount.LT(min) { + ok, reason := hasMinimumSpendableBalance(probeCtx, t.client, sn.CosmosAddress, denom, min) + if ok { res.ok = true return } - - // Insufficient or error → ineligible; cancel sibling - if err != nil { - res.reason = fmt.Sprintf("balance check failed: %v", err) - } else if bal == nil || bal.Balance == nil { - res.reason = "balance info unavailable" - } else { - actualLUME := bal.Balance.Amount.Quo(sdkmath.NewInt(1_000_000)) - res.reason = fmt.Sprintf("insufficient balance: %s LUME (need >= 1 LUME)", actualLUME.String()) - } + res.reason = reason cancel() }() diff --git a/sn-manager/go.mod b/sn-manager/go.mod index 484d9429..b5345a3c 100644 --- a/sn-manager/go.mod +++ b/sn-manager/go.mod @@ -1,8 +1,9 @@ module github.com/LumeraProtocol/supernode/v2/sn-manager -go 1.25.5 +go 1.26.1 replace ( + github.com/LumeraProtocol/lumera => ../../lumera github.com/LumeraProtocol/supernode/v2 => ../ github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 @@ -18,81 +19,6 @@ require ( ) require ( - cosmossdk.io/api v0.9.2 // indirect - cosmossdk.io/collections v1.3.1 // indirect - cosmossdk.io/core v0.11.3 // indirect - cosmossdk.io/depinject v1.2.1 // indirect - cosmossdk.io/errors v1.0.2 // indirect - cosmossdk.io/log v1.6.1 // indirect - cosmossdk.io/math v1.5.3 // indirect - cosmossdk.io/schema v1.1.0 // indirect - cosmossdk.io/store v1.1.2 // indirect - cosmossdk.io/x/tx v0.14.0 // indirect - filippo.io/edwards25519 v1.1.0 // indirect - github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.2 // indirect - github.com/DataDog/datadog-go v4.8.3+incompatible // indirect - github.com/DataDog/zstd v1.5.7 // indirect - github.com/LumeraProtocol/lumera v1.11.0-rc // indirect - github.com/Masterminds/semver/v3 v3.3.1 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.2.0 // indirect - github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.14.2 // indirect - github.com/bytedance/sonic/loader v0.4.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudwego/base64x v0.1.6 // indirect - github.com/cockroachdb/errors v1.12.0 // indirect - github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a // indirect - github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect - github.com/cockroachdb/pebble v1.1.5 // indirect - github.com/cockroachdb/redact v1.1.6 // indirect - github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.20 // indirect - github.com/cometbft/cometbft-db v0.14.1 // indirect - github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-db v1.1.3 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect - github.com/cosmos/cosmos-sdk v0.53.5 // indirect - github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.7.2 // indirect - github.com/cosmos/iavl v1.2.6 // indirect - github.com/cosmos/ics23/go v0.11.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.16.0 // indirect - github.com/danieljoos/wincred v1.2.2 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect - github.com/desertbit/timer v1.0.1 // indirect - github.com/dgraph-io/badger/v4 v4.2.0 // indirect - github.com/dgraph-io/ristretto v0.2.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.7.0 // indirect - github.com/emicklei/dot v1.6.2 // indirect - github.com/fatih/color v1.18.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/getsentry/sentry-go v0.35.0 // indirect - github.com/go-kit/kit v0.13.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // 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/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect - github.com/google/btree v1.1.3 // indirect - github.com/google/flatbuffers v24.3.25+incompatible // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/gorilla/handlers v1.5.2 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.3 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect @@ -100,11 +26,11 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/spf13/pflag v1.0.10 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/grpc v1.77.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.2 // indirect ) diff --git a/sn-manager/go.sum b/sn-manager/go.sum index 1d0b329b..11186ce8 100644 --- a/sn-manager/go.sum +++ b/sn-manager/go.sum @@ -1,31 +1,9 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -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.61.6 h1:wa1rY/mZi8OYnf0f6a02N7o3vBockOfL3P37hSH0XtY= -github.com/CosmWasm/wasmd v0.61.6/go.mod h1:Wg2gfY2qrjjFY8UvpkTCRdy8t67qebOQn7UvRiGRzDw= -github.com/CosmWasm/wasmvm/v3 v3.0.2 h1:+MLkOX+IdklITLqfG26PCFv5OXdZvNb8z5Wq5JFXTRM= -github.com/CosmWasm/wasmvm/v3 v3.0.2/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= -github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.11.0-rc h1:ISJLUhjihuOterLMHpgGWpMZmybR1vmQLNgmSHkc1WA= -github.com/LumeraProtocol/lumera v1.11.0-rc/go.mod h1:p2sZZG3bLzSBdaW883qjuU3DXXY4NJzTTwLywr8uI0w= -github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= -github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +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/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= @@ -81,24 +59,24 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -108,30 +86,30 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go new file mode 100644 index 00000000..f6a29016 --- /dev/null +++ b/supernode/cmd/evmigration.go @@ -0,0 +1,529 @@ +package cmd + +import ( + "context" + "crypto/sha256" + "fmt" + "path/filepath" + "strings" + "time" + + upgradetypes "cosmossdk.io/x/upgrade/types" + evmigrationtypes "github.com/LumeraProtocol/lumera/x/evmigration/types" + "github.com/LumeraProtocol/supernode/v2/pkg/logtrace" + lumeracodec "github.com/LumeraProtocol/supernode/v2/pkg/lumera/codec" + "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode" + snConfig "github.com/LumeraProtocol/supernode/v2/supernode/config" + cKeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "google.golang.org/grpc" +) + +const ( + // evmModuleName is the name of the EVM module in the chain's module version map. + evmModuleName = "evm" +) + +func legacyKeyMigrationInstructions(keyName string) string { + return fmt.Sprintf( + "Lumera is running with the EVM module enabled, but supernode.key_name=%q still points to a legacy secp256k1 key (coin type 118).\n\n"+ + "To continue:\n"+ + " 1. Derive a new EVM key from the same mnemonic:\n"+ + " supernode keys recover --mnemonic \"your twelve or twenty four words ...\"\n"+ + " 2. Add the new key name to config.yml under the supernode section:\n"+ + " key_name: %s\n"+ + " evm_key_name: \n"+ + " 3. Restart supernode so the automatic migration can move the on-chain account to the new EVM address.\n\n"+ + "See docs/evm-migration.md for the full migration procedure.", + keyName, + keyName, + ) +} + +func validateLegacyMigrationSetup(kr cKeyring.Keyring, keyName, evmKeyName string) (bool, error) { + legacy, err := isLegacyKey(kr, keyName) + if err != nil { + return false, err + } + if !legacy { + return false, nil + } + + evmKeyName = strings.TrimSpace(evmKeyName) + if evmKeyName == "" { + return true, fmt.Errorf("%s", legacyKeyMigrationInstructions(keyName)) + } + + isEVM, err := isEthSecp256k1Key(kr, evmKeyName) + if err != nil { + return true, fmt.Errorf("evm_key_name %q: %w\n\n%s", evmKeyName, err, legacyKeyMigrationInstructions(keyName)) + } + if !isEVM { + return true, fmt.Errorf( + "evm_key_name %q is not an eth_secp256k1 key.\n\n%s", + evmKeyName, + legacyKeyMigrationInstructions(keyName), + ) + } + + return true, nil +} + +// requireEVMChain verifies that the connected Lumera chain has the EVM module +// active. If the module is absent, this supernode binary is incompatible and +// must not proceed. +func requireEVMChain(ctx context.Context, conn *grpc.ClientConn) error { + client := upgradetypes.NewQueryClient(conn) + resp, err := client.ModuleVersions(ctx, &upgradetypes.QueryModuleVersionsRequest{ + ModuleName: evmModuleName, + }) + if err != nil { + return fmt.Errorf("failed to query chain module versions: %w", err) + } + if len(resp.ModuleVersions) == 0 { + return fmt.Errorf( + "connected Lumera chain does not have EVM support (module %q not found). "+ + "This supernode binary requires an EVM-enabled Lumera chain. "+ + "Please upgrade your Lumera node or connect to an EVM-enabled chain", + evmModuleName, + ) + } + + logtrace.Info(ctx, "EVM module detected on chain", logtrace.Fields{ + "module": evmModuleName, + "version": resp.ModuleVersions[0].Version, + }) + return nil +} + +// isLegacyKey returns true if the key stored in the keyring under keyName uses +// the pre-EVM secp256k1 algorithm (coin type 118) rather than the EVM-compatible +// eth_secp256k1 (coin type 60). +func isLegacyKey(kr cKeyring.Keyring, keyName string) (bool, error) { + rec, err := kr.Key(keyName) + if err != nil { + return false, fmt.Errorf("key %q not found in keyring: %w", keyName, err) + } + pubKey, err := rec.GetPubKey() + if err != nil { + return false, fmt.Errorf("failed to get public key for %q: %w", keyName, err) + } + _, isSecp := pubKey.(*secp256k1.PubKey) + return isSecp, nil +} + +// isEthSecp256k1Key returns true if the key stored in the keyring under keyName +// uses the EVM-compatible eth_secp256k1 algorithm. +func isEthSecp256k1Key(kr cKeyring.Keyring, keyName string) (bool, error) { + legacy, err := isLegacyKey(kr, keyName) + if err != nil { + return false, err + } + return !legacy, nil +} + +// migrationChainClient abstracts chain interactions needed by the migration +// flow, enabling unit tests without a live gRPC connection. +type migrationChainClient interface { + MigrationRecord(ctx context.Context, legacyAddr string) (*evmigrationtypes.QueryMigrationRecordResponse, error) + MigrationEstimate(ctx context.Context, legacyAddr string) (*evmigrationtypes.QueryMigrationEstimateResponse, error) + BroadcastMigrationTx(ctx context.Context, msg sdk.Msg) error +} + +// grpcMigrationClient implements migrationChainClient using a real gRPC connection. +type grpcMigrationClient struct { + conn *grpc.ClientConn +} + +func (g *grpcMigrationClient) MigrationRecord(ctx context.Context, legacyAddr string) (*evmigrationtypes.QueryMigrationRecordResponse, error) { + return evmigrationtypes.NewQueryClient(g.conn).MigrationRecord(ctx, &evmigrationtypes.QueryMigrationRecordRequest{ + LegacyAddress: legacyAddr, + }) +} + +func (g *grpcMigrationClient) MigrationEstimate(ctx context.Context, legacyAddr string) (*evmigrationtypes.QueryMigrationEstimateResponse, error) { + return evmigrationtypes.NewQueryClient(g.conn).MigrationEstimate(ctx, &evmigrationtypes.QueryMigrationEstimateRequest{ + LegacyAddress: legacyAddr, + }) +} + +func (g *grpcMigrationClient) BroadcastMigrationTx(ctx context.Context, msg sdk.Msg) error { + return broadcastMigrationTx(ctx, g.conn, msg) +} + +// ensureLegacyAccountMigrated detects whether the keyring contains a legacy +// secp256k1 key under keyName. If so, it uses the new EVM key (evmKeyName) +// already imported in the keyring to perform dual-signed migration. +// +// The function is designed to be rerunnable: if a previous run partially +// completed (e.g. tx was broadcast but keyring cleanup failed), re-running +// will detect the state and resume from where it left off. +// +// Steps: +// 1. Validates evmKeyName exists and is eth_secp256k1 +// 2. Checks if the account was already migrated on-chain (MigrationRecord query) +// 3. Runs MigrationEstimate to pre-check whether migration would succeed +// 4. Signs legacy proof with the legacy key, new proof with the EVM key +// 5. Broadcasts MsgClaimLegacyAccount or MsgMigrateValidator +// 6. Verifies the new address is registered as supernode on-chain +// 7. Updates config (identity → new address, clears evm_key_name) and saves +// 8. Deletes the old legacy key (EVM key stays under its name; config key_name updated) +func ensureLegacyAccountMigrated( + ctx context.Context, + kr cKeyring.Keyring, + cfg *snConfig.Config, + chainClient migrationChainClient, + snModule supernode.Module, +) error { + keyName := cfg.SupernodeConfig.KeyName + evmKeyName := cfg.SupernodeConfig.EVMKeyName + + legacy, err := validateLegacyMigrationSetup(kr, keyName, evmKeyName) + if err != nil { + return err + } + if !legacy { + logtrace.Debug(ctx, "Key uses eth_secp256k1, no migration needed", logtrace.Fields{"key": keyName}) + return nil + } + + // Get legacy key info. + legacyRec, err := kr.Key(keyName) + if err != nil { + return fmt.Errorf("failed to read legacy key %q: %w", keyName, err) + } + legacyPubKey, err := legacyRec.GetPubKey() + if err != nil { + return fmt.Errorf("failed to get public key for %q: %w", keyName, err) + } + legacyAddr, err := legacyRec.GetAddress() + if err != nil { + return fmt.Errorf("failed to get address from key %q: %w", keyName, err) + } + + // Get new EVM key info. + newRec, err := kr.Key(evmKeyName) + if err != nil { + return fmt.Errorf("failed to read EVM key %q: %w", evmKeyName, err) + } + newPubKey, err := newRec.GetPubKey() + if err != nil { + return fmt.Errorf("failed to get public key for %q: %w", evmKeyName, err) + } + newAddr := sdk.AccAddress(newPubKey.Address()) + + if legacyAddr.Equals(newAddr) { + return fmt.Errorf( + "legacy address equals new address %s — this should not happen with different coin types", + legacyAddr.String(), + ) + } + + logtrace.Warn(ctx, "Legacy secp256k1 key detected — EVM account migration required", logtrace.Fields{ + "key": keyName, + "evm_key": evmKeyName, + "legacy_address": legacyAddr.String(), + "new_address": newAddr.String(), + }) + + // Check if the account was already migrated on-chain (handles rerun after + // a previous broadcast succeeded but local cleanup failed). + alreadyMigrated := false + + recordResp, err := chainClient.MigrationRecord(ctx, legacyAddr.String()) + if err != nil { + logtrace.Warn(ctx, "Could not query migration record (will attempt migration anyway)", logtrace.Fields{ + "legacy_address": legacyAddr.String(), + "error": err.Error(), + }) + } else if recordResp.Record != nil { + // Verify on-chain new address matches our locally configured EVM key. + if recordResp.Record.NewAddress != newAddr.String() { + return fmt.Errorf( + "migration record exists on-chain but new address mismatch: "+ + "on-chain=%s, local evm_key=%s (address=%s). "+ + "Check that evm_key_name in config matches the key used for the original migration", + recordResp.Record.NewAddress, evmKeyName, newAddr.String(), + ) + } + alreadyMigrated = true + logtrace.Info(ctx, "Account already migrated on-chain, skipping broadcast", logtrace.Fields{ + "legacy_address": legacyAddr.String(), + "new_address": recordResp.Record.NewAddress, + }) + } + + if !alreadyMigrated { + // Pre-flight: run MigrationEstimate to catch issues before broadcasting. + isValidator := false + estimateResp, err := chainClient.MigrationEstimate(ctx, legacyAddr.String()) + if err != nil { + return fmt.Errorf( + "failed to query migration estimate for %s: %w\n"+ + "Unable to determine whether this account requires MsgClaimLegacyAccount or MsgMigrateValidator. "+ + "Safe to retry — just restart the supernode.", + legacyAddr.String(), err, + ) + } else { + isValidator = estimateResp.IsValidator + logtrace.Info(ctx, "Migration estimate", logtrace.Fields{ + "legacy_address": legacyAddr.String(), + "would_succeed": estimateResp.WouldSucceed, + "rejection_reason": estimateResp.RejectionReason, + "is_validator": estimateResp.IsValidator, + "total_touched": estimateResp.TotalTouched, + }) + if !estimateResp.WouldSucceed { + return fmt.Errorf( + "migration estimate indicates migration would fail for %s: %s", + legacyAddr.String(), estimateResp.RejectionReason, + ) + } + } + + // Choose the correct payload kind based on whether the legacy account + // is a validator operator. The chain rejects MsgClaimLegacyAccount for + // validators and requires MsgMigrateValidator instead. + payloadKind := "claim" + if isValidator { + payloadKind = "validator" + } + + // Build the canonical migration payload. + payload := []byte(fmt.Sprintf("lumera-evm-migration:%s:%s:%s", payloadKind, legacyAddr.String(), newAddr.String())) + + // Sign with legacy key from keyring. + // secp256k1.Sign(msg) internally computes SHA256(msg), and the chain verifier + // does SHA256(payload) then VerifySignature(hash, sig) which also does SHA256. + // So we pass SHA256(payload) to the keyring, giving us Sign(SHA256(payload)) + // which produces a signature over SHA256(SHA256(payload)) — matching the verifier. + hash := sha256.Sum256(payload) + legacySig, _, err := kr.Sign(keyName, hash[:], signingtypes.SignMode_SIGN_MODE_DIRECT) + if err != nil { + return fmt.Errorf("failed to sign migration payload with legacy key: %w", err) + } + + // Sign with new EVM key from keyring (eth_secp256k1 signs raw payload; + // internally uses Keccak-256). + newSig, _, err := kr.Sign(evmKeyName, payload, signingtypes.SignMode_SIGN_MODE_DIRECT) + if err != nil { + return fmt.Errorf("failed to sign migration payload with EVM key: %w", err) + } + + // Build the appropriate message type. + var msg sdk.Msg + if isValidator { + msg = &evmigrationtypes.MsgMigrateValidator{ + NewAddress: newAddr.String(), + LegacyAddress: legacyAddr.String(), + LegacyPubKey: legacyPubKey.Bytes(), + LegacySignature: legacySig, + NewPubKey: newPubKey.Bytes(), + NewSignature: newSig, + } + logtrace.Info(ctx, "Validator account detected — using MsgMigrateValidator", logtrace.Fields{ + "legacy_address": legacyAddr.String(), + "new_address": newAddr.String(), + }) + } else { + msg = &evmigrationtypes.MsgClaimLegacyAccount{ + NewAddress: newAddr.String(), + LegacyAddress: legacyAddr.String(), + LegacyPubKey: legacyPubKey.Bytes(), + LegacySignature: legacySig, + NewPubKey: newPubKey.Bytes(), + NewSignature: newSig, + } + } + + if err := msg.(interface{ ValidateBasic() error }).ValidateBasic(); err != nil { + return fmt.Errorf("migration message validation failed: %w", err) + } + + if err := chainClient.BroadcastMigrationTx(ctx, msg); err != nil { + return fmt.Errorf( + "legacy account migration failed: %w\n\n"+ + "Common causes:\n"+ + " - Migration is disabled on-chain\n"+ + " - Legacy account does not exist on-chain\n"+ + " - Wrong mnemonic used to derive the EVM key\n\n"+ + "This operation is safe to retry — just restart the supernode.", + err, + ) + } + + logtrace.Info(ctx, "Legacy account migration tx broadcast successfully", logtrace.Fields{ + "legacy_address": legacyAddr.String(), + "new_address": newAddr.String(), + "is_validator": isValidator, + }) + } + + // Verify the new address is registered as a supernode on-chain. + sn, err := snModule.GetSupernodeBySupernodeAddress(ctx, newAddr.String()) + if err != nil { + logtrace.Warn(ctx, "Could not verify supernode registration for new address (non-fatal)", logtrace.Fields{ + "new_address": newAddr.String(), + "error": err.Error(), + }) + } else if sn != nil { + logtrace.Info(ctx, "New address confirmed as registered supernode", logtrace.Fields{ + "new_address": newAddr.String(), + "supernode_account": sn.SupernodeAccount, + }) + } + + // Update config: key_name → evm key, identity → new address, clear evm_key_name. + cfg.SupernodeConfig.KeyName = evmKeyName + cfg.SupernodeConfig.Identity = newAddr.String() + cfg.SupernodeConfig.EVMKeyName = "" + + cfgFile := filepath.Join(cfg.BaseDir, DefaultConfigFile) + if err := snConfig.SaveConfig(cfg, cfgFile); err != nil { + return fmt.Errorf( + "migration complete but failed to save updated config: %w\n"+ + "Please manually update config.yaml:\n"+ + " - Set key_name to %s\n"+ + " - Set identity to %s\n"+ + " - Remove evm_key_name", + err, evmKeyName, newAddr.String(), + ) + } + + // Delete the old legacy key only after the updated config is safely on disk. + // If config persistence fails, keeping the legacy key allows the next startup + // to resume from the on-chain migration record and complete local cleanup. + if err := kr.Delete(keyName); err != nil { + return fmt.Errorf( + "migration complete and config updated, but failed to delete legacy key %q: %w\n"+ + "Please manually remove the old key.\n"+ + "Safe to retry — just restart the supernode.", + keyName, err, + ) + } + + logtrace.Info(ctx, "EVM migration complete — legacy key removed, config updated", logtrace.Fields{ + "key_name": evmKeyName, + "legacy_address": legacyAddr.String(), + "new_address": newAddr.String(), + }) + return nil +} + +const ( + // txConfirmPollInterval is how often we poll for tx inclusion. + txConfirmPollInterval = 2 * time.Second + // txConfirmTimeout is the maximum time to wait for tx inclusion in a block. + txConfirmTimeout = 60 * time.Second +) + +// broadcastMigrationTx builds an unsigned Cosmos tx containing the migration +// message, simulates gas, broadcasts it via SYNC mode, and then polls until +// the tx is confirmed in a block (DeliverTx). This ensures we only mutate +// local state (keyring, config) after the chain has committed the migration. +func broadcastMigrationTx(ctx context.Context, conn *grpc.ClientConn, msg sdk.Msg) error { + encCfg := lumeracodec.GetEncodingConfig() + + txBuilder := encCfg.TxConfig.NewTxBuilder() + if err := txBuilder.SetMsgs(msg); err != nil { + return fmt.Errorf("failed to set message on tx builder: %w", err) + } + + // Simulate to get gas estimate. Migration txs are fee-exempt on chain, but + // we still need a valid gas limit. + txBytes, err := encCfg.TxConfig.TxEncoder()(txBuilder.GetTx()) + if err != nil { + return fmt.Errorf("failed to encode tx for simulation: %w", err) + } + + txClient := sdktx.NewServiceClient(conn) + simRes, err := txClient.Simulate(ctx, &sdktx.SimulateRequest{TxBytes: txBytes}) + if err != nil { + return fmt.Errorf("simulation failed: %w", err) + } + + // Apply gas adjustment. + gasLimit := uint64(float64(simRes.GasInfo.GasUsed) * 1.5) + txBuilder.SetGasLimit(gasLimit) + + // Re-encode with gas limit set. + txBytes, err = encCfg.TxConfig.TxEncoder()(txBuilder.GetTx()) + if err != nil { + return fmt.Errorf("failed to encode tx for broadcast: %w", err) + } + + // Broadcast with SYNC mode (waits for CheckTx only). + resp, err := txClient.BroadcastTx(ctx, &sdktx.BroadcastTxRequest{ + TxBytes: txBytes, + Mode: sdktx.BroadcastMode_BROADCAST_MODE_SYNC, + }) + if err != nil { + return fmt.Errorf("broadcast error: %w", err) + } + if resp.TxResponse != nil && resp.TxResponse.Code != 0 { + return fmt.Errorf( + "tx rejected at CheckTx: code=%d codespace=%s raw_log=%s", + resp.TxResponse.Code, + resp.TxResponse.Codespace, + resp.TxResponse.RawLog, + ) + } + + txHash := resp.TxResponse.TxHash + logtrace.Info(ctx, "Migration tx passed CheckTx, waiting for block confirmation", logtrace.Fields{ + "tx_hash": txHash, + }) + + // Poll for tx inclusion in a block (DeliverTx confirmation). + if err := waitForTxConfirmation(ctx, txClient, txHash); err != nil { + return fmt.Errorf("migration tx %s was not confirmed: %w", txHash, err) + } + + logtrace.Info(ctx, "Migration tx confirmed in block", logtrace.Fields{ + "tx_hash": txHash, + }) + return nil +} + +// waitForTxConfirmation polls GetTx until the transaction is included in a +// block or the timeout is reached. +func waitForTxConfirmation(ctx context.Context, txClient sdktx.ServiceClient, txHash string) error { + deadline := time.After(txConfirmTimeout) + ticker := time.NewTicker(txConfirmPollInterval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return fmt.Errorf("context cancelled while waiting for tx confirmation: %w", ctx.Err()) + case <-deadline: + return fmt.Errorf("timed out after %s waiting for tx %s to be included in a block", txConfirmTimeout, txHash) + case <-ticker.C: + txResp, err := txClient.GetTx(ctx, &sdktx.GetTxRequest{Hash: txHash}) + if err != nil { + // Tx not yet indexed — keep polling. + logtrace.Debug(ctx, "Tx not yet found, polling...", logtrace.Fields{ + "tx_hash": txHash, + "error": err.Error(), + }) + continue + } + if txResp.TxResponse == nil { + continue + } + // Tx is in a block — check DeliverTx result. + if txResp.TxResponse.Code != 0 { + return fmt.Errorf( + "tx failed in block execution (DeliverTx): code=%d codespace=%s raw_log=%s", + txResp.TxResponse.Code, + txResp.TxResponse.Codespace, + txResp.TxResponse.RawLog, + ) + } + return nil + } + } +} diff --git a/supernode/cmd/evmigration_test.go b/supernode/cmd/evmigration_test.go new file mode 100644 index 00000000..78ccb97c --- /dev/null +++ b/supernode/cmd/evmigration_test.go @@ -0,0 +1,1071 @@ +package cmd + +import ( + "context" + "fmt" + "os" + "path/filepath" + "testing" + "time" + + evmigrationtypes "github.com/LumeraProtocol/lumera/x/evmigration/types" + supernodeTypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types" + "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode" + snConfig "github.com/LumeraProtocol/supernode/v2/supernode/config" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/hd" + sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" + evmcryptocodec "github.com/cosmos/evm/crypto/codec" + evmhd "github.com/cosmos/evm/crypto/hd" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" +) + +// newTestKeyring creates an in-memory keyring that supports both legacy secp256k1 +// and EVM eth_secp256k1 key algorithms. +func newTestKeyring(t *testing.T) sdkkeyring.Keyring { + t.Helper() + reg := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(reg) + evmcryptocodec.RegisterInterfaces(reg) + cdc := codec.NewProtoCodec(reg) + return sdkkeyring.NewInMemory(cdc, evmhd.EthSecp256k1Option()) +} + +// addLegacyKey creates a secp256k1 key (coin type 118) in the keyring. +func addLegacyKey(t *testing.T, kr sdkkeyring.Keyring, name string) { + t.Helper() + _, _, err := kr.NewMnemonic(name, sdkkeyring.English, "m/44'/118'/0'/0/0", "", hd.Secp256k1) + require.NoError(t, err, "failed to create legacy key %q", name) +} + +// addEVMKey creates an eth_secp256k1 key (coin type 60) in the keyring. +func addEVMKey(t *testing.T, kr sdkkeyring.Keyring, name string) { + t.Helper() + _, _, err := kr.NewMnemonic(name, sdkkeyring.English, "m/44'/60'/0'/0/0", "", evmhd.EthSecp256k1) + require.NoError(t, err, "failed to create EVM key %q", name) +} + +// evmKeyAddr returns the bech32 address of the EVM key in the keyring. +func evmKeyAddr(t *testing.T, kr sdkkeyring.Keyring, name string) string { + t.Helper() + rec, err := kr.Key(name) + require.NoError(t, err) + pub, err := rec.GetPubKey() + require.NoError(t, err) + return sdk.AccAddress(pub.Address()).String() +} + +// --- isLegacyKey / isEthSecp256k1Key tests --- + +func TestIsLegacyKey_WithSecp256k1(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "legacy") + + legacy, err := isLegacyKey(kr, "legacy") + require.NoError(t, err) + assert.True(t, legacy, "secp256k1 key should be detected as legacy") +} + +func TestIsLegacyKey_WithEthSecp256k1(t *testing.T) { + kr := newTestKeyring(t) + addEVMKey(t, kr, "evm") + + legacy, err := isLegacyKey(kr, "evm") + require.NoError(t, err) + assert.False(t, legacy, "eth_secp256k1 key should not be detected as legacy") +} + +func TestIsLegacyKey_KeyNotFound(t *testing.T) { + kr := newTestKeyring(t) + + _, err := isLegacyKey(kr, "nonexistent") + require.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestIsEthSecp256k1Key_WithEVMKey(t *testing.T) { + kr := newTestKeyring(t) + addEVMKey(t, kr, "evm") + + isEVM, err := isEthSecp256k1Key(kr, "evm") + require.NoError(t, err) + assert.True(t, isEVM) +} + +func TestIsEthSecp256k1Key_WithLegacyKey(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "legacy") + + isEVM, err := isEthSecp256k1Key(kr, "legacy") + require.NoError(t, err) + assert.False(t, isEVM) +} + +func TestValidateLegacyMigrationSetup_NoMigrationNeeded(t *testing.T) { + kr := newTestKeyring(t) + addEVMKey(t, kr, "mykey") + + legacy, err := validateLegacyMigrationSetup(kr, "mykey", "") + require.NoError(t, err) + assert.False(t, legacy) +} + +func TestValidateLegacyMigrationSetup_LegacyKeyWithoutEVMKeyName(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + + legacy, err := validateLegacyMigrationSetup(kr, "mykey", "") + require.Error(t, err) + assert.True(t, legacy) + assert.Contains(t, err.Error(), "supernode.key_name=\"mykey\"") + assert.Contains(t, err.Error(), "supernode keys recover --mnemonic") + assert.Contains(t, err.Error(), "evm_key_name: ") + assert.Contains(t, err.Error(), "docs/evm-migration.md") +} + +func TestValidateLegacyMigrationSetup_EVMKeyWrongType(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addLegacyKey(t, kr, "also-legacy") + + legacy, err := validateLegacyMigrationSetup(kr, "mykey", "also-legacy") + require.Error(t, err) + assert.True(t, legacy) + assert.Contains(t, err.Error(), "not an eth_secp256k1 key") + assert.Contains(t, err.Error(), "same mnemonic") +} + +// --- test doubles --- + +// fakeSuperNodeModule is a test stub for the supernode.Module interface. +type fakeSuperNodeModule struct { + getSupernode func(ctx context.Context, addr string) (*supernodeTypes.SuperNode, error) +} + +func (f *fakeSuperNodeModule) GetTopSuperNodesForBlock(ctx context.Context, req *supernodeTypes.QueryGetTopSuperNodesForBlockRequest) (*supernodeTypes.QueryGetTopSuperNodesForBlockResponse, error) { + return nil, nil +} + +func (f *fakeSuperNodeModule) GetSuperNode(ctx context.Context, address string) (*supernodeTypes.QueryGetSuperNodeResponse, error) { + return nil, nil +} + +func (f *fakeSuperNodeModule) GetSupernodeBySupernodeAddress(ctx context.Context, address string) (*supernodeTypes.SuperNode, error) { + if f.getSupernode != nil { + return f.getSupernode(ctx, address) + } + return &supernodeTypes.SuperNode{SupernodeAccount: address}, nil +} + +func (f *fakeSuperNodeModule) GetSupernodeWithLatestAddress(ctx context.Context, address string) (*supernode.SuperNodeInfo, error) { + return nil, nil +} + +func (f *fakeSuperNodeModule) GetParams(ctx context.Context) (*supernodeTypes.QueryParamsResponse, error) { + return nil, nil +} + +func (f *fakeSuperNodeModule) ListSuperNodes(ctx context.Context) (*supernodeTypes.QueryListSuperNodesResponse, error) { + return nil, nil +} + +// fakeMigrationClient implements migrationChainClient for testing. +type fakeMigrationClient struct { + recordResp *evmigrationtypes.QueryMigrationRecordResponse + recordErr error + estimateResp *evmigrationtypes.QueryMigrationEstimateResponse + estimateErr error + broadcastErr error + broadcastedMsg sdk.Msg // captures the message passed to BroadcastMigrationTx +} + +func (f *fakeMigrationClient) MigrationRecord(_ context.Context, _ string) (*evmigrationtypes.QueryMigrationRecordResponse, error) { + return f.recordResp, f.recordErr +} + +func (f *fakeMigrationClient) MigrationEstimate(_ context.Context, _ string) (*evmigrationtypes.QueryMigrationEstimateResponse, error) { + return f.estimateResp, f.estimateErr +} + +func (f *fakeMigrationClient) BroadcastMigrationTx(_ context.Context, msg sdk.Msg) error { + f.broadcastedMsg = msg + return f.broadcastErr +} + +// newMigrationCfg creates a config with tmpDir for tests that need config persistence. +func newMigrationCfg(t *testing.T, keyName, evmKeyName string) *snConfig.Config { + t.Helper() + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = keyName + cfg.SupernodeConfig.EVMKeyName = evmKeyName + cfg.BaseDir = t.TempDir() + return cfg +} + +// --- ensureLegacyAccountMigrated: early-return / validation tests --- + +func TestEnsureLegacyAccountMigrated_NoMigrationNeeded(t *testing.T) { + kr := newTestKeyring(t) + addEVMKey(t, kr, "mykey") + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "mykey" + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, nil, nil) + require.NoError(t, err, "should return nil when key is already EVM") +} + +func TestEnsureLegacyAccountMigrated_LegacyKeyNoEVMKeyName(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "mykey" + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, nil, nil) + require.Error(t, err) + assert.Contains(t, err.Error(), "supernode.key_name=\"mykey\"") + assert.Contains(t, err.Error(), "same mnemonic") + assert.Contains(t, err.Error(), "supernode keys recover --mnemonic") + assert.Contains(t, err.Error(), "evm_key_name: ") +} + +func TestEnsureLegacyAccountMigrated_EVMKeyNotFound(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "mykey" + cfg.SupernodeConfig.EVMKeyName = "nonexistent" + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, nil, nil) + require.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestEnsureLegacyAccountMigrated_EVMKeyWrongType(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addLegacyKey(t, kr, "also-legacy") + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "mykey" + cfg.SupernodeConfig.EVMKeyName = "also-legacy" + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, nil, nil) + require.Error(t, err) + assert.Contains(t, err.Error(), "not an eth_secp256k1 key") + assert.Contains(t, err.Error(), "same mnemonic") +} + +func TestEnsureLegacyAccountMigrated_AddressCollision(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + legacyRec, err := kr.Key("mykey") + require.NoError(t, err) + legacyAddr, err := legacyRec.GetAddress() + require.NoError(t, err) + + evmRec, err := kr.Key("evm-key") + require.NoError(t, err) + evmPubKey, err := evmRec.GetPubKey() + require.NoError(t, err) + + assert.NotEqual(t, legacyAddr.String(), fmt.Sprintf("%x", evmPubKey.Address()), + "keys with different coin types should produce different addresses") +} + +func TestEnsureLegacyAccountMigrated_Idempotent_AlreadyEVM(t *testing.T) { + kr := newTestKeyring(t) + addEVMKey(t, kr, "mykey") + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "mykey" + cfg.SupernodeConfig.EVMKeyName = "some-unused-evm-key" + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, nil, nil) + require.NoError(t, err) +} + +func TestEnsureLegacyAccountMigrated_KeyNameNotFound(t *testing.T) { + kr := newTestKeyring(t) + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "missing" + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, nil, nil) + require.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +// --- already-migrated (MigrationRecord) tests --- + +func TestEnsureLegacyAccountMigrated_AlreadyMigrated_MatchingAddress(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{ + Record: &evmigrationtypes.MigrationRecord{ + NewAddress: newAddr, + }, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + // Legacy key should be deleted, config updated. + _, err = kr.Key("mykey") + assert.Error(t, err, "legacy key should be deleted") + assert.Equal(t, "evm-key", cfg.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, cfg.SupernodeConfig.Identity) + assert.Empty(t, cfg.SupernodeConfig.EVMKeyName) +} + +func TestEnsureLegacyAccountMigrated_AlreadyMigrated_MismatchedAddress(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{ + Record: &evmigrationtypes.MigrationRecord{ + NewAddress: "lumera1wrongaddressxyz", + }, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "new address mismatch") + assert.Contains(t, err.Error(), "lumera1wrongaddressxyz") + + // Legacy key should NOT be deleted on mismatch. + _, err = kr.Key("mykey") + assert.NoError(t, err, "legacy key should still exist after mismatch error") +} + +func TestEnsureLegacyAccountMigrated_MigrationRecordQueryError_ProceedsToMigrate(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordErr: fmt.Errorf("network timeout"), + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + // Should have broadcast a MsgClaimLegacyAccount (non-validator default). + require.NotNil(t, mc.broadcastedMsg) + _, isClaim := mc.broadcastedMsg.(*evmigrationtypes.MsgClaimLegacyAccount) + assert.True(t, isClaim, "should broadcast MsgClaimLegacyAccount") + + assert.Equal(t, newAddr, cfg.SupernodeConfig.Identity) +} + +// --- validator migration tests --- + +func TestEnsureLegacyAccountMigrated_ValidatorUsesMsgMigrateValidator(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, // no record + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + IsValidator: true, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + require.NotNil(t, mc.broadcastedMsg) + valMsg, isVal := mc.broadcastedMsg.(*evmigrationtypes.MsgMigrateValidator) + assert.True(t, isVal, "should broadcast MsgMigrateValidator for validator accounts") + assert.Equal(t, newAddr, valMsg.NewAddress) +} + +func TestEnsureLegacyAccountMigrated_NonValidatorUsesMsgClaimLegacyAccount(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + IsValidator: false, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + require.NotNil(t, mc.broadcastedMsg) + _, isClaim := mc.broadcastedMsg.(*evmigrationtypes.MsgClaimLegacyAccount) + assert.True(t, isClaim, "should broadcast MsgClaimLegacyAccount for non-validator accounts") +} + +func TestEnsureLegacyAccountMigrated_EstimateErrorFailsClosed(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateErr: fmt.Errorf("estimate query not available"), + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to query migration estimate") + assert.Nil(t, mc.broadcastedMsg, "should not broadcast when migration type cannot be determined") +} + +func TestEnsureLegacyAccountMigrated_EstimateWouldNotSucceed(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: false, + RejectionReason: "migration is disabled", + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "migration is disabled") + + // No broadcast should have occurred. + assert.Nil(t, mc.broadcastedMsg) +} + +// --- broadcast failure tests --- + +func TestEnsureLegacyAccountMigrated_BroadcastFails(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + broadcastErr: fmt.Errorf("DeliverTx failed: code=7"), + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "legacy account migration failed") + assert.Contains(t, err.Error(), "DeliverTx failed") + + // Legacy key should NOT be deleted when broadcast fails. + _, err = kr.Key("mykey") + assert.NoError(t, err, "legacy key should still exist after broadcast failure") +} + +// --- config save failure before key deletion --- + +func TestEnsureLegacyAccountMigrated_ConfigSaveFailsBeforeKeyDelete(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + // Point BaseDir to a non-writable path to force SaveConfig to fail. + cfg.BaseDir = "/proc/nonexistent" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to save updated config") + assert.Contains(t, err.Error(), newAddr) + + // Legacy key should still exist so the next startup can resume cleanup + // from the on-chain migration record. + _, err = kr.Key("mykey") + assert.NoError(t, err, "legacy key should remain when config save fails") +} + +// --- full happy-path end-to-end test --- + +func TestEnsureLegacyAccountMigrated_FullHappyPath(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + cfg.SupernodeConfig.Identity = "lumera1oldaddr" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + // Broadcast happened. + require.NotNil(t, mc.broadcastedMsg) + + // Legacy key deleted. + _, err = kr.Key("mykey") + assert.Error(t, err, "legacy key should be deleted") + + // EVM key still accessible. + _, err = kr.Key("evm-key") + assert.NoError(t, err, "EVM key should still exist") + + // Config updated. + assert.Equal(t, "evm-key", cfg.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, cfg.SupernodeConfig.Identity) + assert.Empty(t, cfg.SupernodeConfig.EVMKeyName) + + // Config persisted to disk. + cfgFile := filepath.Join(cfg.BaseDir, DefaultConfigFile) + loaded, err := snConfig.LoadConfig(cfgFile, cfg.BaseDir) + require.NoError(t, err) + assert.Equal(t, "evm-key", loaded.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, loaded.SupernodeConfig.Identity) + assert.Empty(t, loaded.SupernodeConfig.EVMKeyName) +} + +// --- keyring and config helper tests --- + +func TestEnsureLegacyAccountMigrated_ValidationPassesBeforeNetwork(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + legacyRec, err := kr.Key("mykey") + require.NoError(t, err) + legacyAddr, err := legacyRec.GetAddress() + require.NoError(t, err) + + evmRec, err := kr.Key("evm-key") + require.NoError(t, err) + evmPubKey, err := evmRec.GetPubKey() + require.NoError(t, err) + evmAddr := sdk.AccAddress(evmPubKey.Address()) + + assert.NotEqual(t, legacyAddr.String(), evmAddr.String(), + "legacy and EVM keys should produce different addresses") + + _, errLegacy := kr.Key("mykey") + assert.NoError(t, errLegacy) + _, errEVM := kr.Key("evm-key") + assert.NoError(t, errEVM) +} + +func TestKeyDeleteAfterMigration(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "old-key") + addEVMKey(t, kr, "new-key") + + evmRec, err := kr.Key("new-key") + require.NoError(t, err) + evmAddr, err := evmRec.GetAddress() + require.NoError(t, err) + + require.NoError(t, kr.Delete("old-key")) + + _, err = kr.Key("old-key") + assert.Error(t, err, "legacy key should be deleted") + + rec, err := kr.Key("new-key") + require.NoError(t, err) + addr, err := rec.GetAddress() + require.NoError(t, err) + assert.Equal(t, evmAddr.String(), addr.String()) + + isEVM, err := isEthSecp256k1Key(kr, "new-key") + require.NoError(t, err) + assert.True(t, isEVM, "EVM key should remain eth_secp256k1") +} + +func TestConfigUpdateAfterMigration(t *testing.T) { + tmpDir := t.TempDir() + + cfg := &snConfig.Config{ + SupernodeConfig: snConfig.SupernodeConfig{ + KeyName: "mykey", + Identity: "lumera1oldaddr", + EVMKeyName: "evm-key", + }, + } + cfg.BaseDir = tmpDir + + newAddr := "lumera1newaddr" + cfg.SupernodeConfig.KeyName = "evm-key" + cfg.SupernodeConfig.Identity = newAddr + cfg.SupernodeConfig.EVMKeyName = "" + + cfgFile := filepath.Join(tmpDir, DefaultConfigFile) + err := snConfig.SaveConfig(cfg, cfgFile) + require.NoError(t, err) + + loaded, err := snConfig.LoadConfig(cfgFile, tmpDir) + require.NoError(t, err) + assert.Equal(t, newAddr, loaded.SupernodeConfig.Identity) + assert.Empty(t, loaded.SupernodeConfig.EVMKeyName) + assert.Equal(t, "evm-key", loaded.SupernodeConfig.KeyName) +} + +func TestConfigSaveCreatesFile(t *testing.T) { + tmpDir := t.TempDir() + cfgFile := filepath.Join(tmpDir, "subdir", DefaultConfigFile) + + cfg := &snConfig.Config{} + cfg.SupernodeConfig.KeyName = "test" + cfg.SupernodeConfig.Identity = "lumera1test" + + err := snConfig.SaveConfig(cfg, cfgFile) + require.NoError(t, err) + + _, err = os.Stat(cfgFile) + require.NoError(t, err, "config file should exist after save") +} + +// --- fakeTxServiceClient mocks sdktx.ServiceClient for waitForTxConfirmation tests --- + +type fakeTxServiceClient struct { + getTxResponses []getTxResult // sequential responses; cycles the last one + getTxCallCount int +} + +type getTxResult struct { + resp *sdktx.GetTxResponse + err error +} + +func (f *fakeTxServiceClient) GetTx(_ context.Context, _ *sdktx.GetTxRequest, _ ...grpc.CallOption) (*sdktx.GetTxResponse, error) { + idx := f.getTxCallCount + if idx >= len(f.getTxResponses) { + idx = len(f.getTxResponses) - 1 + } + f.getTxCallCount++ + r := f.getTxResponses[idx] + return r.resp, r.err +} + +// Unused methods — satisfy the interface. +func (f *fakeTxServiceClient) Simulate(_ context.Context, _ *sdktx.SimulateRequest, _ ...grpc.CallOption) (*sdktx.SimulateResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) BroadcastTx(_ context.Context, _ *sdktx.BroadcastTxRequest, _ ...grpc.CallOption) (*sdktx.BroadcastTxResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) GetTxsEvent(_ context.Context, _ *sdktx.GetTxsEventRequest, _ ...grpc.CallOption) (*sdktx.GetTxsEventResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) GetBlockWithTxs(_ context.Context, _ *sdktx.GetBlockWithTxsRequest, _ ...grpc.CallOption) (*sdktx.GetBlockWithTxsResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) TxDecode(_ context.Context, _ *sdktx.TxDecodeRequest, _ ...grpc.CallOption) (*sdktx.TxDecodeResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) TxEncode(_ context.Context, _ *sdktx.TxEncodeRequest, _ ...grpc.CallOption) (*sdktx.TxEncodeResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) TxEncodeAmino(_ context.Context, _ *sdktx.TxEncodeAminoRequest, _ ...grpc.CallOption) (*sdktx.TxEncodeAminoResponse, error) { + return nil, fmt.Errorf("not implemented") +} +func (f *fakeTxServiceClient) TxDecodeAmino(_ context.Context, _ *sdktx.TxDecodeAminoRequest, _ ...grpc.CallOption) (*sdktx.TxDecodeAminoResponse, error) { + return nil, fmt.Errorf("not implemented") +} + +// --- waitForTxConfirmation tests --- + +func TestWaitForTxConfirmation_Success(t *testing.T) { + mock := &fakeTxServiceClient{ + getTxResponses: []getTxResult{ + {err: fmt.Errorf("tx not found")}, // first poll: not yet indexed + {resp: &sdktx.GetTxResponse{TxResponse: nil}}, // second poll: no response yet + {resp: &sdktx.GetTxResponse{ // third poll: confirmed + TxResponse: &sdk.TxResponse{Code: 0, TxHash: "ABC123"}, + }}, + }, + } + + err := waitForTxConfirmation(context.Background(), mock, "ABC123") + require.NoError(t, err) + assert.GreaterOrEqual(t, mock.getTxCallCount, 3, "should have polled at least 3 times") +} + +func TestWaitForTxConfirmation_DeliverTxFailure(t *testing.T) { + mock := &fakeTxServiceClient{ + getTxResponses: []getTxResult{ + {resp: &sdktx.GetTxResponse{ + TxResponse: &sdk.TxResponse{ + Code: 7, + Codespace: "evmigration", + RawLog: "ErrUseValidatorMigration: use MsgMigrateValidator for validator accounts", + }, + }}, + }, + } + + err := waitForTxConfirmation(context.Background(), mock, "DEADBEEF") + require.Error(t, err) + assert.Contains(t, err.Error(), "DeliverTx") + assert.Contains(t, err.Error(), "code=7") + assert.Contains(t, err.Error(), "ErrUseValidatorMigration") +} + +func TestWaitForTxConfirmation_ContextCancelled(t *testing.T) { + // Mock that never returns success — cancellation should stop it. + mock := &fakeTxServiceClient{ + getTxResponses: []getTxResult{ + {err: fmt.Errorf("tx not found")}, + }, + } + + ctx, cancel := context.WithCancel(context.Background()) + cancel() // cancel immediately + + err := waitForTxConfirmation(ctx, mock, "CANCELLED") + require.Error(t, err) + assert.Contains(t, err.Error(), "context cancelled") +} + +func TestWaitForTxConfirmation_Timeout(t *testing.T) { + // Temporarily override the timeout constants for a fast test. + // We can't change the package-level consts, but we can use a short + // context deadline that expires before the internal timeout. + mock := &fakeTxServiceClient{ + getTxResponses: []getTxResult{ + {err: fmt.Errorf("tx not found")}, + }, + } + + ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + defer cancel() + + err := waitForTxConfirmation(ctx, mock, "TIMEOUT") + require.Error(t, err) + // Either the context deadline or the internal timeout fires. + assert.True(t, + contains(err.Error(), "context cancelled") || contains(err.Error(), "timed out"), + "expected timeout or cancellation error, got: %s", err.Error(), + ) +} + +func contains(s, substr string) bool { + return len(s) >= len(substr) && (s == substr || len(s) > 0 && findSubstr(s, substr)) +} + +func findSubstr(s, substr string) bool { + for i := 0; i <= len(s)-len(substr); i++ { + if s[i:i+len(substr)] == substr { + return true + } + } + return false +} + +// --- validator full happy-path test --- + +func TestEnsureLegacyAccountMigrated_ValidatorFullHappyPath(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "val-key") + addEVMKey(t, kr, "val-evm-key") + + newAddr := evmKeyAddr(t, kr, "val-evm-key") + cfg := newMigrationCfg(t, "val-key", "val-evm-key") + cfg.SupernodeConfig.Identity = "lumera1oldvalidator" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + IsValidator: true, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + // Correct message type. + valMsg, isVal := mc.broadcastedMsg.(*evmigrationtypes.MsgMigrateValidator) + require.True(t, isVal, "should use MsgMigrateValidator for validator") + assert.Equal(t, newAddr, valMsg.NewAddress) + assert.NotEmpty(t, valMsg.LegacySignature) + assert.NotEmpty(t, valMsg.NewSignature) + assert.NotEmpty(t, valMsg.LegacyPubKey) + assert.NotEmpty(t, valMsg.NewPubKey) + + // Legacy key deleted. + _, err = kr.Key("val-key") + assert.Error(t, err, "legacy key should be deleted") + + // Config updated. + assert.Equal(t, "val-evm-key", cfg.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, cfg.SupernodeConfig.Identity) + assert.Empty(t, cfg.SupernodeConfig.EVMKeyName) + + // Config persisted. + cfgFile := filepath.Join(cfg.BaseDir, DefaultConfigFile) + loaded, err := snConfig.LoadConfig(cfgFile, cfg.BaseDir) + require.NoError(t, err) + assert.Equal(t, "val-evm-key", loaded.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, loaded.SupernodeConfig.Identity) +} + +// --- supernode verification (non-fatal) tests --- + +func TestEnsureLegacyAccountMigrated_SupernodeVerificationFails_NonFatal(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + snMod := &fakeSuperNodeModule{ + getSupernode: func(_ context.Context, _ string) (*supernodeTypes.SuperNode, error) { + return nil, fmt.Errorf("supernode not found on-chain") + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, snMod) + require.NoError(t, err, "supernode verification failure should be non-fatal") + + // Migration still completed. + assert.Equal(t, newAddr, cfg.SupernodeConfig.Identity) + _, err = kr.Key("mykey") + assert.Error(t, err, "legacy key should still be deleted") +} + +func TestEnsureLegacyAccountMigrated_SupernodeVerificationReturnsNil_NonFatal(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + snMod := &fakeSuperNodeModule{ + getSupernode: func(_ context.Context, _ string) (*supernodeTypes.SuperNode, error) { + return nil, nil // not found, no error + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, snMod) + require.NoError(t, err, "nil supernode result should be non-fatal") +} + +// --- already-migrated: config persistence verified --- + +func TestEnsureLegacyAccountMigrated_AlreadyMigrated_ConfigPersisted(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + cfg.SupernodeConfig.Identity = "lumera1oldaddr" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{ + Record: &evmigrationtypes.MigrationRecord{ + NewAddress: newAddr, + }, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + // No broadcast should have occurred. + assert.Nil(t, mc.broadcastedMsg, "already-migrated should skip broadcast") + + // Config file should be saved to disk. + cfgFile := filepath.Join(cfg.BaseDir, DefaultConfigFile) + loaded, err := snConfig.LoadConfig(cfgFile, cfg.BaseDir) + require.NoError(t, err) + assert.Equal(t, "evm-key", loaded.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, loaded.SupernodeConfig.Identity) + assert.Empty(t, loaded.SupernodeConfig.EVMKeyName) +} + +// --- broadcast failure preserves full state --- + +func TestEnsureLegacyAccountMigrated_BroadcastFails_PreservesFullState(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + cfg.SupernodeConfig.Identity = "lumera1original" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + broadcastErr: fmt.Errorf("tx failed in block execution (DeliverTx): code=7 codespace=evmigration"), + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "DeliverTx") + + // Everything should be preserved — no local state mutation on broadcast failure. + _, err = kr.Key("mykey") + assert.NoError(t, err, "legacy key should NOT be deleted") + _, err = kr.Key("evm-key") + assert.NoError(t, err, "EVM key should still exist") + assert.Equal(t, "mykey", cfg.SupernodeConfig.KeyName, "key_name should be unchanged") + assert.Equal(t, "lumera1original", cfg.SupernodeConfig.Identity, "identity should be unchanged") + assert.Equal(t, "evm-key", cfg.SupernodeConfig.EVMKeyName, "evm_key_name should be unchanged") +} + +// --- migration record nil record field (empty response, not nil) --- + +func TestEnsureLegacyAccountMigrated_MigrationRecordNilRecord_ProceedsToMigrate(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{ + Record: nil, // response exists but record is nil + }, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + assert.NotNil(t, mc.broadcastedMsg, "should broadcast when Record is nil") +} + +// --- dual signing: verify the message contains valid signatures and correct addresses --- + +func TestEnsureLegacyAccountMigrated_MessageFieldsCorrect(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + legacyRec, err := kr.Key("mykey") + require.NoError(t, err) + legacyAddr, err := legacyRec.GetAddress() + require.NoError(t, err) + legacyPub, err := legacyRec.GetPubKey() + require.NoError(t, err) + + evmRec, err := kr.Key("evm-key") + require.NoError(t, err) + evmPub, err := evmRec.GetPubKey() + require.NoError(t, err) + newAddr := sdk.AccAddress(evmPub.Address()).String() + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + IsValidator: false, + }, + } + + err = ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + claimMsg, ok := mc.broadcastedMsg.(*evmigrationtypes.MsgClaimLegacyAccount) + require.True(t, ok) + + assert.Equal(t, legacyAddr.String(), claimMsg.LegacyAddress) + assert.Equal(t, newAddr, claimMsg.NewAddress) + assert.Equal(t, legacyPub.Bytes(), claimMsg.LegacyPubKey) + assert.Equal(t, evmPub.Bytes(), claimMsg.NewPubKey) + assert.NotEmpty(t, claimMsg.LegacySignature) + assert.NotEmpty(t, claimMsg.NewSignature) +} + +// --- estimate with both record query error and estimate error --- + +func TestEnsureLegacyAccountMigrated_BothQueriesFail_FailsClosed(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordErr: fmt.Errorf("record query unreachable"), + estimateErr: fmt.Errorf("estimate query unreachable"), + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to query migration estimate") + assert.Nil(t, mc.broadcastedMsg, "should not broadcast when both migration queries are unavailable") +} diff --git a/supernode/cmd/start.go b/supernode/cmd/start.go index be1c1c15..5a7f4e69 100644 --- a/supernode/cmd/start.go +++ b/supernode/cmd/start.go @@ -85,6 +85,18 @@ The supernode will connect to the Lumera network and begin participating in the logtrace.Fatal(ctx, "Failed to connect Lumera, please check your configuration", logtrace.Fields{"error": err.Error()}) } + // Verify the chain has EVM support — this binary is incompatible with pre-EVM chains. + if err := requireEVMChain(ctx, lumeraClient.Conn()); err != nil { + logtrace.Fatal(ctx, "EVM chain check failed", logtrace.Fields{"error": err.Error()}) + } + + // Fail fast with migration instructions if key_name still points to a + // legacy secp256k1 key without a valid evm_key_name, otherwise perform + // the automatic on-chain migration to the new EVM-compatible address. + if err := ensureLegacyAccountMigrated(ctx, kr, appConfig, &grpcMigrationClient{conn: lumeraClient.Conn()}, lumeraClient.SuperNode()); err != nil { + logtrace.Fatal(ctx, "Legacy account migration failed", logtrace.Fields{"error": err.Error()}) + } + // Reachability evidence store (used for open_ports inference). reachability.SetDefaultStore(reachability.NewStore()) // Epoch tracker: mark per-service inbound evidence per chain epoch (best-effort). diff --git a/supernode/config/config.go b/supernode/config/config.go index 92d0de7c..cb3831d6 100644 --- a/supernode/config/config.go +++ b/supernode/config/config.go @@ -19,6 +19,10 @@ type SupernodeConfig struct { IPAddress string `yaml:"ip_address,omitempty"` Port uint16 `yaml:"port"` GatewayPort uint16 `yaml:"gateway_port,omitempty"` + // EVMKeyName is the name of the new eth_secp256k1 key in the keyring, + // used during one-time legacy account migration. After migration, this + // key replaces the old key_name and this field can be removed from config. + EVMKeyName string `yaml:"evm_key_name,omitempty"` } type KeyringConfig struct { diff --git a/supernode/supernode_metrics/reachability_active_probing_test.go b/supernode/supernode_metrics/reachability_active_probing_test.go index 5f138fe9..65757e9d 100644 --- a/supernode/supernode_metrics/reachability_active_probing_test.go +++ b/supernode/supernode_metrics/reachability_active_probing_test.go @@ -24,6 +24,7 @@ import ( "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode_msg" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/tx" "github.com/LumeraProtocol/supernode/v2/pkg/reachability" + "google.golang.org/grpc" ) func TestBuildProbeCandidatesFilters(t *testing.T) { @@ -414,6 +415,7 @@ func (c *fakeLumeraClient) SuperNodeMsg() supernode_msg.Module { return nil } func (c *fakeLumeraClient) Bank() bank.Module { return nil } func (c *fakeLumeraClient) Tx() tx.Module { return nil } func (c *fakeLumeraClient) Node() node.Module { return c.nodeModule } +func (c *fakeLumeraClient) Conn() *grpc.ClientConn { return nil } func (c *fakeLumeraClient) Close() error { return nil } type fakeNodeModule struct { diff --git a/tests/integration/evmigration/evmigration_test.go b/tests/integration/evmigration/evmigration_test.go new file mode 100644 index 00000000..0d951e69 --- /dev/null +++ b/tests/integration/evmigration/evmigration_test.go @@ -0,0 +1,292 @@ +// Package evmigration provides integration tests for the EVM account migration flow. +// These tests exercise the full keyring lifecycle (legacy key detection → EVM key +// validation → key delete → config save) without a live chain. +package evmigration + +import ( + "crypto/sha256" + "os" + "path/filepath" + "testing" + + snConfig "github.com/LumeraProtocol/supernode/v2/supernode/config" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/hd" + sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + evmcryptocodec "github.com/cosmos/evm/crypto/codec" + "github.com/cosmos/evm/crypto/ethsecp256k1" + evmhd "github.com/cosmos/evm/crypto/hd" + "github.com/cosmos/go-bip39" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +// newTestKeyring creates an in-memory keyring supporting both key algorithms. +func newTestKeyring(t *testing.T) sdkkeyring.Keyring { + t.Helper() + reg := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(reg) + evmcryptocodec.RegisterInterfaces(reg) + cdc := codec.NewProtoCodec(reg) + return sdkkeyring.NewInMemory(cdc, evmhd.EthSecp256k1Option()) +} + +func generateMnemonic(t *testing.T) string { + t.Helper() + entropy, err := bip39.NewEntropy(256) + require.NoError(t, err) + mn, err := bip39.NewMnemonic(entropy) + require.NoError(t, err) + return mn +} + +// TestFullMigrationKeyringFlow tests the complete keyring migration lifecycle: +// 1. Start with a legacy secp256k1 key +// 2. Import an EVM key from the same mnemonic +// 3. Sign migration payload with both keys (dual signing) +// 4. Delete legacy key (EVM key stays under its name; config key_name is updated) +// 5. Verify the EVM key is accessible and legacy key is gone +func TestFullMigrationKeyringFlow(t *testing.T) { + kr := newTestKeyring(t) + mnemonic := generateMnemonic(t) + + // Step 1: Import legacy key (secp256k1, coin type 118). + legacyRec, err := kr.NewAccount("mykey", mnemonic, "", "m/44'/118'/0'/0/0", hd.Secp256k1) + require.NoError(t, err) + legacyAddr, err := legacyRec.GetAddress() + require.NoError(t, err) + legacyPubKey, err := legacyRec.GetPubKey() + require.NoError(t, err) + + _, isLegacy := legacyPubKey.(*secp256k1.PubKey) + require.True(t, isLegacy, "initial key should be secp256k1") + + // Step 2: Import EVM key (eth_secp256k1, coin type 60) from same mnemonic. + evmRec, err := kr.NewAccount("evm-key", mnemonic, "", "m/44'/60'/0'/0/0", evmhd.EthSecp256k1) + require.NoError(t, err) + evmPubKey, err := evmRec.GetPubKey() + require.NoError(t, err) + evmAddr := sdk.AccAddress(evmPubKey.Address()) + + _, isEVM := evmPubKey.(*ethsecp256k1.PubKey) + require.True(t, isEVM, "EVM key should be eth_secp256k1") + + // Addresses must differ. + require.NotEqual(t, legacyAddr.String(), evmAddr.String(), + "legacy and EVM keys should have different addresses") + + t.Logf("Legacy address: %s", legacyAddr.String()) + t.Logf("EVM address: %s", evmAddr.String()) + + // Step 3: Sign migration payload with both keys (simulating what + // ensureLegacyAccountMigrated does). + payload := []byte("lumera-evm-migration:claim:" + legacyAddr.String() + ":" + evmAddr.String()) + + // Legacy signing: SHA256(payload) → keyring.Sign (which does another SHA256 internally). + hash := sha256.Sum256(payload) + legacySig, _, err := kr.Sign("mykey", hash[:], signingtypes.SignMode_SIGN_MODE_DIRECT) + require.NoError(t, err) + require.NotEmpty(t, legacySig) + + // EVM signing: raw payload → keyring.Sign (eth_secp256k1 uses Keccak-256 internally). + evmSig, _, err := kr.Sign("evm-key", payload, signingtypes.SignMode_SIGN_MODE_DIRECT) + require.NoError(t, err) + require.NotEmpty(t, evmSig) + + // Verify legacy signature against the public key. + // The chain verifier does: VerifySignature(SHA256(payload), sig) which internally + // SHA256s again. We replicate that here. + verified := legacyPubKey.VerifySignature(hash[:], legacySig) + assert.True(t, verified, "legacy signature should verify") + + // Verify EVM signature. + verified = evmPubKey.VerifySignature(payload, evmSig) + assert.True(t, verified, "EVM signature should verify") + + // Step 4: Delete legacy key. EVM key stays under "evm-key"; + // config key_name would be updated to "evm-key" in the real flow. + require.NoError(t, kr.Delete("mykey")) + + // Step 5: Verify legacy key is gone, EVM key is accessible. + _, err = kr.Key("mykey") + assert.Error(t, err, "legacy key should be deleted") + + finalRec, err := kr.Key("evm-key") + require.NoError(t, err) + finalPubKey, err := finalRec.GetPubKey() + require.NoError(t, err) + + _, isEVMFinal := finalPubKey.(*ethsecp256k1.PubKey) + assert.True(t, isEVMFinal, "EVM key should still be eth_secp256k1") + + finalAddr, err := finalRec.GetAddress() + require.NoError(t, err) + assert.Equal(t, evmAddr.String(), finalAddr.String(), + "EVM key should have the same address") +} + +// TestConfigPersistenceAfterMigration verifies that identity and evm_key_name +// are correctly persisted/cleared in config.yaml after migration. +func TestConfigPersistenceAfterMigration(t *testing.T) { + tmpDir := t.TempDir() + + // Create initial config with legacy identity and evm_key_name set. + cfg := &snConfig.Config{ + SupernodeConfig: snConfig.SupernodeConfig{ + KeyName: "mykey", + Identity: "lumera1legacyaddr123", + Host: "127.0.0.1", + Port: 4444, + EVMKeyName: "evm-key", + }, + KeyringConfig: snConfig.KeyringConfig{ + Backend: "test", + Dir: "keyring", + }, + P2PConfig: snConfig.P2PConfig{ + Port: 4445, + DataDir: "data/p2p", + }, + LumeraClientConfig: snConfig.LumeraClientConfig{ + GRPCAddr: "localhost:9090", + ChainID: "lumera-testnet", + }, + RaptorQConfig: snConfig.RaptorQConfig{ + FilesDir: "data/raptorq", + }, + } + cfg.BaseDir = tmpDir + + cfgFile := filepath.Join(tmpDir, "config.yml") + require.NoError(t, snConfig.SaveConfig(cfg, cfgFile)) + + // Simulate migration: key_name → evm key, update identity, clear evm_key_name. + newAddr := "lumera1newevmaddr456" + cfg.SupernodeConfig.KeyName = "evm-key" + cfg.SupernodeConfig.Identity = newAddr + cfg.SupernodeConfig.EVMKeyName = "" + require.NoError(t, snConfig.SaveConfig(cfg, cfgFile)) + + // Reload config and verify. + loaded, err := snConfig.LoadConfig(cfgFile, tmpDir) + require.NoError(t, err) + + assert.Equal(t, "evm-key", loaded.SupernodeConfig.KeyName, + "key_name should be updated to EVM key name") + assert.Equal(t, newAddr, loaded.SupernodeConfig.Identity, + "identity should be updated to new EVM address") + assert.Empty(t, loaded.SupernodeConfig.EVMKeyName, + "evm_key_name should be cleared after migration") + assert.Equal(t, "lumera-testnet", loaded.LumeraClientConfig.ChainID, + "other config fields should be preserved") + + // Verify the raw YAML doesn't contain evm_key_name when it's empty + // (omitempty tag). + raw, err := os.ReadFile(cfgFile) + require.NoError(t, err) + var rawMap map[string]interface{} + require.NoError(t, yaml.Unmarshal(raw, &rawMap)) + + snSection, ok := rawMap["supernode"].(map[string]interface{}) + require.True(t, ok, "supernode section should exist in YAML") + _, hasEVMKeyName := snSection["evm_key_name"] + assert.False(t, hasEVMKeyName, + "evm_key_name should not appear in YAML when empty (omitempty)") +} + +// TestDualSigningProtocol verifies the exact signing protocol that the chain +// expects for MsgClaimLegacyAccount: +// - Legacy: Sign(SHA256(payload)) → chain verifies with VerifySignature(SHA256(payload), sig) +// - New: Sign(payload) → chain verifies with VerifySignature(payload, sig) +func TestDualSigningProtocol(t *testing.T) { + kr := newTestKeyring(t) + mn := generateMnemonic(t) + + // Create both key types. + legacyRec, err := kr.NewAccount("legacy", mn, "", "m/44'/118'/0'/0/0", hd.Secp256k1) + require.NoError(t, err) + legacyPubKey, err := legacyRec.GetPubKey() + require.NoError(t, err) + legacyAddr, err := legacyRec.GetAddress() + require.NoError(t, err) + + evmRec, err := kr.NewAccount("evm", mn, "", "m/44'/60'/0'/0/0", evmhd.EthSecp256k1) + require.NoError(t, err) + evmPubKey, err := evmRec.GetPubKey() + require.NoError(t, err) + evmAddr := sdk.AccAddress(evmPubKey.Address()) + + payload := []byte("lumera-evm-migration:claim:" + legacyAddr.String() + ":" + evmAddr.String()) + + // --- Legacy signature protocol --- + // The supernode passes SHA256(payload) to kr.Sign. + // secp256k1 internally SHA256s again: Sign(SHA256(SHA256(payload))). + // The chain verifier does: VerifySignature(SHA256(payload), sig) + // where VerifySignature internally SHA256s: verify(SHA256(SHA256(payload)), sig). + hash := sha256.Sum256(payload) + legacySig, _, err := kr.Sign("legacy", hash[:], signingtypes.SignMode_SIGN_MODE_DIRECT) + require.NoError(t, err) + + // Simulate chain-side verification: VerifySignature(SHA256(payload), sig). + assert.True(t, legacyPubKey.VerifySignature(hash[:], legacySig), + "legacy sig should verify with SHA256(payload) as message") + + // Signing raw payload should NOT verify with SHA256(payload). + wrongSig, _, err := kr.Sign("legacy", payload, signingtypes.SignMode_SIGN_MODE_DIRECT) + require.NoError(t, err) + assert.False(t, legacyPubKey.VerifySignature(hash[:], wrongSig), + "signing raw payload should not match SHA256(payload) verification") + + // --- EVM signature protocol --- + // The supernode passes raw payload to kr.Sign. + // eth_secp256k1 internally Keccak-256s: Sign(Keccak256(payload)). + // The chain verifier does: VerifySignature(payload, sig) + // where VerifySignature internally Keccak-256s: verify(Keccak256(payload), sig). + evmSig, _, err := kr.Sign("evm", payload, signingtypes.SignMode_SIGN_MODE_DIRECT) + require.NoError(t, err) + + assert.True(t, evmPubKey.VerifySignature(payload, evmSig), + "EVM sig should verify with raw payload") +} + +// TestMigrationIdempotency verifies that after migration, the legacy key is +// gone and the EVM key under its name passes "not legacy" checks. +func TestMigrationIdempotency(t *testing.T) { + kr := newTestKeyring(t) + mn := generateMnemonic(t) + + // Setup: legacy + EVM keys. + _, err := kr.NewAccount("mykey", mn, "", "m/44'/118'/0'/0/0", hd.Secp256k1) + require.NoError(t, err) + _, err = kr.NewAccount("evm-key", mn, "", "m/44'/60'/0'/0/0", evmhd.EthSecp256k1) + require.NoError(t, err) + + // Verify pre-migration state. + rec, _ := kr.Key("mykey") + pub, _ := rec.GetPubKey() + _, isLegacy := pub.(*secp256k1.PubKey) + require.True(t, isLegacy, "before migration, mykey should be secp256k1") + + // Simulate migration: delete legacy key, config key_name → "evm-key". + require.NoError(t, kr.Delete("mykey")) + + // Verify post-migration state: "evm-key" is now the active key. + rec, err = kr.Key("evm-key") + require.NoError(t, err) + pub, err = rec.GetPubKey() + require.NoError(t, err) + + _, isLegacy = pub.(*secp256k1.PubKey) + assert.False(t, isLegacy, "evm-key should NOT be secp256k1") + + _, isEVM := pub.(*ethsecp256k1.PubKey) + assert.True(t, isEVM, "evm-key should be eth_secp256k1") + + // A second migration check with key_name="evm-key" would see no legacy key → no-op. +} diff --git a/tests/system/go.mod b/tests/system/go.mod index c5daeaf7..48012c63 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -1,8 +1,9 @@ module github.com/LumeraProtocol/supernode/v2/tests/systemtests -go 1.25.5 +go 1.26.1 replace ( + github.com/LumeraProtocol/lumera => ../../../lumera github.com/LumeraProtocol/supernode/v2 => ../../ github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 @@ -11,46 +12,29 @@ replace ( require ( cosmossdk.io/math v1.5.3 - github.com/LumeraProtocol/lumera v1.11.0-rc + github.com/LumeraProtocol/lumera v1.11.0 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 - github.com/cometbft/cometbft v0.38.20 + github.com/cometbft/cometbft v0.38.21 + github.com/cosmos/cosmos-sdk v0.53.6 + github.com/cosmos/gogoproto v1.7.2 github.com/cosmos/ibc-go/v10 v10.5.0 - github.com/tidwall/gjson v1.14.2 + github.com/stretchr/testify v1.11.1 + github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b gopkg.in/yaml.v3 v3.0.1 ) -require ( - github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect - github.com/cosmos/cosmos-sdk v0.53.5 - github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.7.2 - github.com/cosmos/iavl v1.2.6 // indirect - github.com/dvsekhvalnov/jose2go v1.7.0 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.23.2 // indirect - github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/pflag v1.0.10 // indirect - github.com/stretchr/testify v1.11.1 - github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.77.0 // indirect -) - require ( cosmossdk.io/api v0.9.2 // indirect - cosmossdk.io/collections v1.3.1 // indirect + cosmossdk.io/collections v1.4.0 // indirect cosmossdk.io/core v0.11.3 // indirect cosmossdk.io/depinject v1.2.1 // indirect cosmossdk.io/errors v1.0.2 // indirect cosmossdk.io/log v1.6.1 // indirect cosmossdk.io/schema v1.1.0 // indirect cosmossdk.io/store v1.1.2 // indirect + cosmossdk.io/x/feegrant v0.2.0 // indirect cosmossdk.io/x/tx v0.14.0 // indirect cosmossdk.io/x/upgrade v0.2.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -63,8 +47,13 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.2.0 // indirect - github.com/bytedance/sonic v1.14.2 // indirect - github.com/bytedance/sonic/loader v0.4.0 // indirect + github.com/bits-and-blooms/bitset v1.24.3 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect + github.com/btcsuite/btcd/btcutil v1.1.6 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect @@ -76,11 +65,18 @@ require ( github.com/cockroachdb/redact v1.1.6 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft-db v0.14.1 // indirect + github.com/consensys/gnark-crypto v0.18.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.1.3 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/evm v0.6.0 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/iavl v1.2.6 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.16.0 // indirect + github.com/cosmos/ledger-cosmos-go v1.0.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/danieljoos/wincred v1.2.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect @@ -89,11 +85,15 @@ require ( github.com/dgraph-io/ristretto v0.2.0 // indirect github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect + github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/getsentry/sentry-go v0.35.0 // indirect + github.com/getsentry/sentry-go v0.42.0 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -103,6 +103,7 @@ require ( github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect @@ -110,8 +111,10 @@ require ( github.com/google/orderedcode v0.0.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect @@ -122,12 +125,13 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/holiman/uint256 v1.3.2 // indirect github.com/huandu/skiplist v1.2.1 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -142,10 +146,12 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // 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.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/cors v1.11.1 // indirect @@ -154,13 +160,19 @@ require ( github.com/sasha-s/go-deadlock v0.3.5 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/viper v1.21.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/supranational/blst v0.3.14 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.7.0 // indirect + github.com/tidwall/btree v1.8.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v1.0.1 // indirect @@ -169,17 +181,19 @@ require ( go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.17.0 // indirect - golang.org/x/crypto v0.47.0 // indirect - golang.org/x/net v0.48.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.49.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.2 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.2 // indirect diff --git a/tests/system/go.sum b/tests/system/go.sum index 3378ef5e..b5cac596 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -56,8 +56,8 @@ cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/client/v2 v2.0.0-beta.11 h1:iHbjDw/NuNz2OVaPmx0iE9eu2HrbX+WAv2u9guRcd6o= cosmossdk.io/client/v2 v2.0.0-beta.11/go.mod h1:ZmmxMUpALO2r1aG6fNOonE7f8I1g/WsafJgVAeQ0ffs= -cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= -cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= +cosmossdk.io/collections v1.4.0 h1:b373bkxCxKiRbapxZ42TRmcKJEnBVBebdQVk9I5IkkE= +cosmossdk.io/collections v1.4.0/go.mod h1:gxbieVY3tjbvWlkm3yOXf7sGyDrVi12haZH+sek6whw= cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= @@ -107,8 +107,6 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.11.0-rc h1:ISJLUhjihuOterLMHpgGWpMZmybR1vmQLNgmSHkc1WA= -github.com/LumeraProtocol/lumera v1.11.0-rc/go.mod h1:p2sZZG3bLzSBdaW883qjuU3DXXY4NJzTTwLywr8uI0w= github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4= github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= @@ -119,10 +117,13 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.6 h1:k1/zc2jNfeiZBA5aFTRy37jlBIuCkXCm0XmvpzCKI9I= github.com/adlio/schema v1.3.6/go.mod h1:qkxwLgPBd1FgLRHYVCmQT/rrBr3JH38J9LjmVzWNudg= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -154,12 +155,35 @@ github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE5 github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.24.3 h1:Bte86SlO3lwPQqww+7BE9ZuUCKIjfqnG5jtEyqA9y9Y= github.com/bits-and-blooms/bitset v1.24.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +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.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.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU= github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protoc-gen-validate v1.3.0 h1:0lq2b9qA1uzfVnMW6oFJepiVVihDOOzj+VuTGSX4EgE= github.com/bufbuild/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= @@ -199,8 +223,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-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= 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= @@ -221,10 +245,12 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1: github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coder/websocket v1.8.7 h1:jiep6gmlfP/yq2w1gBoubJEXL9gf8x3bp6lzzX8nJxE= github.com/coder/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -github.com/cometbft/cometbft v0.38.20 h1:i9v9rvh3Z4CZvGSWrByAOpiqNq5WLkat3r/tE/B49RU= -github.com/cometbft/cometbft v0.38.20/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= +github.com/cometbft/cometbft v0.38.21 h1:qcIJSH9LiwU5s6ZgKR5eRbsLNucbubfraDs5bzgjtOI= +github.com/cometbft/cometbft v0.38.21/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= github.com/cometbft/cometbft-db v0.14.1 h1:SxoamPghqICBAIcGpleHbmoPqy+crij/++eZz3DlerQ= github.com/cometbft/cometbft-db v0.14.1/go.mod h1:KHP1YghilyGV/xjD5DP3+2hyigWx0WTp9X+0Gnx0RxQ= +github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= +github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -237,8 +263,10 @@ github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOP github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= 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.53.5 h1:JPue+SFn2gyDzTV9TYb8mGpuIH3kGt7WbGadulkpTcU= -github.com/cosmos/cosmos-sdk v0.53.5/go.mod h1:AQJx0jpon70WAD4oOs/y+SlST4u7VIwEPR6F8S7JMdo= +github.com/cosmos/cosmos-sdk v0.53.6 h1:aJeInld7rbsHtH1qLHu2aZJF9t40mGlqp3ylBLDT0HI= +github.com/cosmos/cosmos-sdk v0.53.6/go.mod h1:N6YuprhAabInbT3YGumGDKONbvPX5dNro7RjHvkQoKE= +github.com/cosmos/evm v0.6.0 h1:jwJerLS7btDgDpZOYy7lUC+1rNRCGGE80TJ6r4guufo= +github.com/cosmos/evm v0.6.0/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= 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= @@ -256,22 +284,34 @@ github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5Rtn github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/cosmos/ledger-cosmos-go v0.16.0 h1:YKlWPG9NnGZIEUb2bEfZ6zhON1CHlNTg0QKRRGcNEd0= -github.com/cosmos/ledger-cosmos-go v0.16.0/go.mod h1:WrM2xEa8koYoH2DgeIuZXNarF7FGuZl3mrIOnp3Dp0o= +github.com/cosmos/ledger-cosmos-go v1.0.0 h1:jNKW89nPf0vR0EkjHG8Zz16h6p3zqwYEOxlHArwgYtw= +github.com/cosmos/ledger-cosmos-go v1.0.0/go.mod h1:mGaw2wDOf+Z6SfRJsMGxU9DIrBa4du0MAiPlpPhLAOE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= +github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= +github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo= github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= @@ -308,12 +348,16 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 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/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= +github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= +github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-ethereum v1.15.11 h1:JK73WKeu0WC0O1eyX+mdQAVHUV+UR1a9VB/domDngBU= github.com/ethereum/go-ethereum v1.15.11/go.mod h1:mf8YiHIb0GR4x4TipcvBUPxJLw1mFdmxzoDi11sDRoI= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 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.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= @@ -330,8 +374,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/getsentry/sentry-go v0.35.0 h1:+FJNlnjJsZMG3g0/rmmP7GiKjQoUF5EXfEtBwtPtkzY= -github.com/getsentry/sentry-go v0.35.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= +github.com/getsentry/sentry-go v0.42.0 h1:eeFMACuZTbUQf90RE8dE4tXeSe4CZyfvR1MBL7RLEt8= +github.com/getsentry/sentry-go v0.42.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -361,6 +405,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= @@ -378,11 +424,14 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -497,6 +546,7 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -559,6 +609,8 @@ github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8 github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -567,6 +619,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.1 h1:dTi93MgjwErA/8idWTzIw4Y1kZsMWx35fmI2c8Rij7w= github.com/huandu/skiplist v1.2.1/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -579,6 +633,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -588,6 +646,7 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -605,10 +664,11 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= @@ -628,6 +688,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -656,6 +718,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= @@ -702,17 +766,20 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU= -github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= +github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -745,6 +812,16 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 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= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -783,8 +860,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b 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.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= 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= @@ -792,11 +869,13 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx 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.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= 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= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/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= @@ -822,6 +901,8 @@ github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6v github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shamaton/msgpack/v2 v2.2.3 h1:uDOHmxQySlvlUYfQwdjxyybAOzjlQsD1Vjy+4jmO9NM= github.com/shamaton/msgpack/v2 v2.2.3/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -872,28 +953,38 @@ 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/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 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.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= +github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= -github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= -github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo= +github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= +github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= +github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= +github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= +github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= @@ -908,6 +999,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/golem v0.27.0 h1:IbBjGIXF3SoGOZHsILJvIM/F/ylwJzMcHAcggiqniPw= github.com/zondax/golem v0.27.0/go.mod h1:AmorCgJPt00L8xN1VrMBe13PSifoZksnQ1Ge906bu4A= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -930,22 +1023,22 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= 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= @@ -967,12 +1060,13 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU= golang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -991,8 +1085,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= 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= @@ -1034,6 +1128,7 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1088,8 +1183,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= 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= @@ -1099,8 +1194,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= 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= @@ -1198,8 +1293,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -1209,8 +1304,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= 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= @@ -1226,8 +1321,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= 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= @@ -1375,10 +1470,10 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= 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= @@ -1405,8 +1500,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 5c438217e3a1843c970c045c89dbfa56c5446369 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 17 Mar 2026 15:41:45 -0400 Subject: [PATCH 02/22] evmigration fixes --- .gitignore | 3 +- docs/evm-migration.md | 136 ++++++++++++++++++++------------ p2p/kademlia/bootstrap.go | 65 ++++++++++++++- p2p/kademlia/dht.go | 24 +++--- p2p/p2p.go | 13 +++ pkg/net/credentials/lumeratc.go | 9 +++ supernode/cmd/start.go | 26 ++++++ 7 files changed, 212 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index e0837eb5..1a18a5c9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ supernode/__debug* /data /release AGENTS.md -analysis \ No newline at end of file +analysis +.claude/settings.json \ No newline at end of file diff --git a/docs/evm-migration.md b/docs/evm-migration.md index 9824d7a6..5f1cdfac 100644 --- a/docs/evm-migration.md +++ b/docs/evm-migration.md @@ -14,7 +14,8 @@ delegations, supernode registration, and optionally validator state — to a new address derived from the same mnemonic under the EVM HD path. The migration is: -- **One-time**: runs automatically at supernode startup when a legacy key is detected + +- **One-time**: runs automatically at superno0de startup when a legacy key is detected - **Rerunnable**: safe to retry if interrupted at any point - **Self-authenticating**: uses dual signatures (legacy + new key) embedded in the message, so no Cosmos-level tx signing is needed @@ -24,57 +25,59 @@ The migration is: ### Prerequisites 1. Your supernode binary must be the EVM-compatible version. -2. The connected Lumera chain must have the `evm` module active. -3. You need the **mnemonic** used to create your original supernode key. +2. The connected Lumera chain must have the`evm` module active. +3. You need the**mnemonic** used to create your original supernode key. ### Migration Steps 1. **Derive your new EVM key** from the same mnemonic: + ```bash supernode keys recover --name evm-key --mnemonic "your twelve or twenty four words ..." ``` + This creates an `eth_secp256k1` key under the name `evm-key` using HD path `m/44'/60'/0'/0/0`. The resulting address will be different from your legacy address — this is expected. - 2. **Add `evm_key_name` to your config.yaml** under the `supernode` section: + ```yaml supernode: key_name: mykey # your existing legacy key name evm_key_name: evm-key # the name you used in step 1 identity: lumera1... # your current legacy address ``` - 3. **Restart the supernode**. On startup it will: - - Detect the legacy `secp256k1` key under `key_name` - - Validate that `evm_key_name` points to a valid `eth_secp256k1` key + + - Detect the legacy`secp256k1` key under`key_name` + - Validate that`evm_key_name` points to a valid`eth_secp256k1` key - Query the chain for an existing migration record (handles reruns) - - Run a pre-flight `MigrationEstimate` to check if the migration would succeed + - Run a pre-flight`MigrationEstimate` to check if the migration would succeed - Sign the migration payload with both keys - - Broadcast `MsgClaimLegacyAccount` (or `MsgMigrateValidator` for validators) + - Broadcast`MsgClaimLegacyAccount` (or`MsgMigrateValidator` for validators) - Wait for block confirmation (DeliverTx) - Delete the legacy key from the keyring - - Update `config.yaml`: `key_name` -> `evm-key`, `identity` -> new address, - `evm_key_name` cleared - + - Update`config.yaml`:`key_name` ->`evm-key`,`identity` -> new address,`evm_key_name` cleared 4. **After migration completes**, your config will look like: + ```yaml supernode: key_name: evm-key identity: lumera1 ``` + The `evm_key_name` field is automatically removed. No further action is needed. ### Troubleshooting -| Error | Cause | Fix | -| ----- | ----- | --- | -| `no evm_key_name configured` | Legacy key detected but config missing `evm_key_name` | Add `evm_key_name` to config and restart | -| `not an eth_secp256k1 key` | `evm_key_name` points to a secp256k1 key (wrong derivation) | Re-derive using `supernode keys recover` (uses coin type 60) | -| `new address mismatch` | On-chain migration record has a different destination address than your local EVM key | Your `evm_key_name` doesn't match the key originally used for migration; fix the config | -| `migration estimate indicates migration would fail` | Chain rejected the pre-flight check | Check `rejection_reason` in logs; migration may be disabled or account may not exist | -| `migration tx was not confirmed` | Tx was not included in a block within 60s | Restart to retry; the check is idempotent | -| `failed to save updated config` | Config file write error after successful migration | Manually update config as instructed in the error message | +| Error | Cause | Fix | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `no evm_key_name configured` | Legacy key detected but config missing `evm_key_name` | Add `evm_key_name` to config and restart | +| `not an eth_secp256k1 key` | `evm_key_name` points to a secp256k1 key (wrong derivation) | Re-derive using `supernode keys recover` (uses coin type 60) | +| `new address mismatch` | On-chain migration record has a different destination address than your local EVM key | Your `evm_key_name` doesn't match the key originally used for migration; fix the config | +| `migration estimate indicates migration would fail` | Chain rejected the pre-flight check | Check `rejection_reason` in logs; migration may be disabled or account may not exist | +| `migration tx was not confirmed` | Tx was not included in a block within 60s | Restart to retry; the check is idempotent | +| `failed to save updated config` | Config file write error after successful migration | Manually update config as instructed in the error message | ## Chain-Side Reference @@ -106,12 +109,12 @@ validator operators with `ErrUseValidatorMigration`. ### Migration parameters (chain-side) -| Param | Default | Description | -| ----- | ------- | ----------- | -| `enable_migration` | `true` | Master switch | -| `migration_end_time` | `0` | Unix timestamp deadline (0 = no deadline) | -| `max_migrations_per_block` | `50` | Rate limit | -| `max_validator_delegations` | `2000` | Max delegators for validator migration | +| Param | Default | Description | +| ----------------------------- | -------- | ----------------------------------------- | +| `enable_migration` | `true` | Master switch | +| `migration_end_time` | `0` | Unix timestamp deadline (0 = no deadline) | +| `max_migrations_per_block` | `50` | Rate limit | +| `max_validator_delegations` | `2000` | Max delegators for validator migration | ### Fee waiving @@ -175,6 +178,7 @@ Update config (key_name, identity, evm_key_name) and save The chain expects different signing protocols for each key type: **Legacy (secp256k1):** + ``` supernode: hash = SHA256(payload) sig = kr.Sign(hash) -- internally: Sign(SHA256(hash)) @@ -182,22 +186,52 @@ chain: VerifySignature(hash, sig) -- internally: verify(SHA256(hash), sig ``` **EVM (eth_secp256k1):** + ``` supernode: sig = kr.Sign(payload) -- internally: Sign(Keccak256(payload)) chain: VerifySignature(payload, sig) -- internally: verify(Keccak256(payload), sig) ``` -### Key Architectural Decisions +### P2P Bootstrap Refresh After Migration -- **No `kr.Rename`**: The Cosmos SDK `Rename` method uses amino armor export/import - internally, which doesn't support `eth_secp256k1` keys. Instead, after migration - the EVM key keeps its original name and `config.yaml key_name` is updated to point - to it. +When an EVM migration occurs, all supernodes change their on-chain addresses +simultaneously. Without intervention, the P2P layer would keep stale addresses +in its routing table for up to 10 minutes (the normal bootstrap refresh +interval), causing handshake failures. -- **SYNC broadcast + polling**: `BROADCAST_MODE_SYNC` only waits for `CheckTx`. - Local state (keyring, config) is only mutated after `waitForTxConfirmation` polls - `GetTx` and confirms block inclusion via `DeliverTx`. +Three mechanisms work together to resolve this: + +1. **Immediate bootstrap refresh**: After migration completes and the Lumera + client is reloaded, `start.go` calls `p2pService.NotifyEVMMigration()`. + This triggers an immediate `SyncBootstrapOnce()` which re-queries + `ListSuperNodes()` from the chain and updates the routing table with + current addresses. + +2. **Accelerated refresh window**: After the migration signal, the bootstrap + refresher switches from the normal 10-minute interval to a **1-minute + interval for 5 cycles**. This catches peers that migrate slightly later + (staggered startup, network delays). After 5 accelerated cycles it + automatically reverts to the normal 10-minute cadence. + +3. **Staggered startup (devnet)**: In the devnet startup script, validator N + waits `(N-1) * 5` seconds before starting the supernode when EVM migration + is pending. This spreads migrations across ~20 seconds so that by the time + later validators query the chain, earlier validators have already committed + their migration records. +**Code locations:** + +| Component | File | Key symbol | +| --- | --- | --- | +| Migration notify channel | `p2p/kademlia/dht.go` | `migrationNotify` field | +| Accelerated refresher | `p2p/kademlia/bootstrap.go` | `StartBootstrapRefresher()`, `NotifyEVMMigration()` | +| P2P interface method | `p2p/p2p.go` | `NotifyEVMMigration()` | +| Startup integration | `supernode/cmd/start.go` | `evmMigrationOccurred` flag | + +### Key Architectural Decisions + +- **SYNC broadcast + polling**: `BROADCAST_MODE_SYNC` only waits for `CheckTx`. +- Local state (keyring, config) is only mutated after `waitForTxConfirmation` polls `GetTx` and confirms block inclusion via `DeliverTx`. - **`migrationChainClient` interface**: Chain interactions (queries + broadcast) are abstracted behind an interface, enabling comprehensive unit testing without a live gRPC connection. @@ -206,26 +240,26 @@ chain: VerifySignature(payload, sig) -- internally: verify(Keccak256(payloa ### New Files -| File | Description | -| ---- | ----------- | -| `supernode/cmd/evmigration.go` | Core migration logic: chain detection, key validation, dual signing, broadcast, config update | -| `supernode/cmd/evmigration_test.go` | Unit tests with mock chain client | -| `tests/integration/evmigration/evmigration_test.go` | Integration tests for keyring lifecycle, signing protocol, config persistence | +| File | Description | +| ----------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `supernode/cmd/evmigration.go` | Core migration logic: chain detection, key validation, dual signing, broadcast, config update | +| `supernode/cmd/evmigration_test.go` | Unit tests with mock chain client | +| `tests/integration/evmigration/evmigration_test.go` | Integration tests for keyring lifecycle, signing protocol, config persistence | ### Modified Files -| File | Changes | -| ---- | ------- | -| `pkg/keyring/keyring.go` | Switched to EVM defaults: `DefaultHDPath = "m/44'/60'/0'/0/0"`, `EthSecp256k1Option()`, `evmcryptocodec.RegisterInterfaces()` | -| `pkg/keyring/keyring_test.go` | Added 10 tests for EVM key creation, derivation, signing, legacy-vs-EVM address differences | -| `pkg/lumera/codec/encoding.go` | Registers `evmcryptocodec` and `evmigrationtypes` interfaces | -| `pkg/lumera/interface.go` | Added `Conn() *grpc.ClientConn` to Client interface | -| `pkg/lumera/client.go` | Implemented `Conn()` method | -| `pkg/lumera/lumera_mock.go` | Added `Conn()` to mock client | -| `pkg/testutil/lumera.go` | Added `Conn()` to `MockLumeraClient` | -| `supernode/config/config.go` | Added `EVMKeyName string` field to `SupernodeConfig` | -| `supernode/cmd/start.go` | Integrated `requireEVMChain()` and `ensureLegacyAccountMigrated()` at startup | -| `go.mod` / `go.sum` | Added `github.com/cosmos/evm` dependency | +| File | Changes | +| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `pkg/keyring/keyring.go` | Switched to EVM defaults:`DefaultHDPath = "m/44'/60'/0'/0/0"`, `EthSecp256k1Option()`, `evmcryptocodec.RegisterInterfaces()` | +| `pkg/keyring/keyring_test.go` | Added 10 tests for EVM key creation, derivation, signing, legacy-vs-EVM address differences | +| `pkg/lumera/codec/encoding.go` | Registers `evmcryptocodec` and `evmigrationtypes` interfaces | +| `pkg/lumera/interface.go` | Added `Conn() *grpc.ClientConn` to Client interface | +| `pkg/lumera/client.go` | Implemented `Conn()` method | +| `pkg/lumera/lumera_mock.go` | Added `Conn()` to mock client | +| `pkg/testutil/lumera.go` | Added `Conn()` to `MockLumeraClient` | +| `supernode/config/config.go` | Added `EVMKeyName string` field to `SupernodeConfig` | +| `supernode/cmd/start.go` | Integrated `requireEVMChain()` and `ensureLegacyAccountMigrated()` at startup | +| `go.mod` / `go.sum` | Added `github.com/cosmos/evm` dependency | ### Key Types and Functions diff --git a/p2p/kademlia/bootstrap.go b/p2p/kademlia/bootstrap.go index 4ecf53aa..680a1afe 100644 --- a/p2p/kademlia/bootstrap.go +++ b/p2p/kademlia/bootstrap.go @@ -16,8 +16,10 @@ import ( ) const ( - bootstrapRefreshInterval = 10 * time.Minute - defaultSuperNodeP2PPort int = 4445 + bootstrapRefreshInterval = 10 * time.Minute + bootstrapAcceleratedInterval = 1 * time.Minute + bootstrapAcceleratedCycles = 5 + defaultSuperNodeP2PPort int = 4445 ) // seed a couple of obviously bad addrs (unless in integration tests) @@ -301,6 +303,10 @@ func (s *DHT) SyncBootstrapOnce(ctx context.Context, bootstrapNodes string) erro // StartBootstrapRefresher runs SyncBootstrapOnce every 10 minutes (idempotent upserts). // This keeps replication_info and routing table current as the validator set changes. +// +// When NotifyEVMMigration is called, the refresher immediately runs a sync and +// temporarily switches to an accelerated 1-minute interval for 5 cycles so that +// peer address changes from EVM migration are picked up quickly. func (s *DHT) StartBootstrapRefresher(ctx context.Context, bootstrapNodes string) { go func() { // Initial sync @@ -310,13 +316,32 @@ func (s *DHT) StartBootstrapRefresher(ctx context.Context, bootstrapNodes string logtrace.FieldError: err.Error(), }) } - t := time.NewTicker(bootstrapRefreshInterval) + + acceleratedRemaining := 0 + currentInterval := bootstrapRefreshInterval + t := time.NewTicker(currentInterval) defer t.Stop() for { select { case <-ctx.Done(): return + case <-s.migrationNotify: + // EVM migration detected — immediate sync + accelerated refresh + logtrace.Info(ctx, "EVM migration notified — running immediate bootstrap sync and switching to accelerated refresh", logtrace.Fields{ + logtrace.FieldModule: "p2p", + "accelerated_cycles": bootstrapAcceleratedCycles, + "accelerated_interval": bootstrapAcceleratedInterval.String(), + }) + if err := s.SyncBootstrapOnce(ctx, bootstrapNodes); err != nil { + logtrace.Warn(ctx, "post-migration bootstrap sync failed", logtrace.Fields{ + logtrace.FieldModule: "p2p", + logtrace.FieldError: err.Error(), + }) + } + acceleratedRemaining = bootstrapAcceleratedCycles + currentInterval = bootstrapAcceleratedInterval + t.Reset(currentInterval) case <-t.C: if err := s.SyncBootstrapOnce(ctx, bootstrapNodes); err != nil { logtrace.Warn(ctx, "periodic bootstrap sync failed", logtrace.Fields{ @@ -324,11 +349,45 @@ func (s *DHT) StartBootstrapRefresher(ctx context.Context, bootstrapNodes string logtrace.FieldError: err.Error(), }) } + if acceleratedRemaining > 0 { + acceleratedRemaining-- + if acceleratedRemaining == 0 { + logtrace.Info(ctx, "Accelerated bootstrap refresh complete — reverting to normal interval", logtrace.Fields{ + logtrace.FieldModule: "p2p", + }) + currentInterval = bootstrapRefreshInterval + t.Reset(currentInterval) + } + } } } }() } +// NotifyEVMMigration flushes stale P2P state (credential cache and pooled +// connections) and signals the bootstrap refresher to immediately re-sync the +// peer list from the chain with temporarily accelerated refresh interval. +// This must be called after an EVM account migration completes so that the +// new local identity is used for all subsequent handshakes. +func (s *DHT) NotifyEVMMigration() { + // 1. Clear the global KeyExchanger cache so new handshakes use the + // post-migration local identity in HKDF key derivation. + ltc.ClearKeyExchangerCache() + + // 2. Close all pooled connections — they were established with the old + // identity and will fail authentication if reused. + if s.network != nil { + s.network.connPool.Release() + } + + // 3. Signal the bootstrap refresher to re-sync peers immediately. + select { + case s.migrationNotify <- struct{}{}: + default: + // already pending — no need to double-signal + } +} + // ConfigureBootstrapNodes wires to the new sync/refresher (no pings here). func (s *DHT) ConfigureBootstrapNodes(ctx context.Context, bootstrapNodes string) error { // One-time sync; start refresher in the background diff --git a/p2p/kademlia/dht.go b/p2p/kademlia/dht.go index 7466693f..5c6f2052 100644 --- a/p2p/kademlia/dht.go +++ b/p2p/kademlia/dht.go @@ -77,6 +77,11 @@ type DHT struct { routingAllow map[[32]byte]struct{} // blake3(peerID) -> exists routingAllowReady atomic.Bool routingAllowCount atomic.Int64 + + // migrationNotify is signalled by NotifyEVMMigration to trigger an + // immediate bootstrap refresh and temporarily accelerate the refresh + // interval (1 min for the first 5 cycles after migration). + migrationNotify chan struct{} } // bootstrapIgnoreList seeds the in-memory ignore list with nodes that are @@ -280,15 +285,16 @@ func NewDHT(ctx context.Context, store Store, metaStore MetaStore, options *Opti } s := &DHT{ - metaStore: metaStore, - store: store, - options: options, - done: make(chan struct{}), - cache: memory.NewKeyValue(), - bsConnected: &sync.Map{}, - ignorelist: NewBanList(ctx), - replicationMtx: sync.RWMutex{}, - rqstore: rqstore, + metaStore: metaStore, + store: store, + options: options, + done: make(chan struct{}), + cache: memory.NewKeyValue(), + bsConnected: &sync.Map{}, + ignorelist: NewBanList(ctx), + replicationMtx: sync.RWMutex{}, + rqstore: rqstore, + migrationNotify: make(chan struct{}, 1), } // Check that keyring is provided diff --git a/p2p/p2p.go b/p2p/p2p.go index f7387bce..b77a45e7 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -37,6 +37,12 @@ type P2P interface { // Run the node of distributed hash table Run(ctx context.Context) error + + // NotifyEVMMigration signals the P2P layer that an EVM account migration + // has completed. This triggers an immediate bootstrap refresh from the + // chain and temporarily accelerates the refresh interval so that stale + // peer addresses are replaced with post-migration addresses promptly. + NotifyEVMMigration() } // p2p structure to implements interface @@ -232,6 +238,13 @@ func (s *p2p) NClosestNodesWithIncludingNodeList(ctx context.Context, n int, key return ret } +// NotifyEVMMigration forwards the migration signal to the underlying DHT. +func (s *p2p) NotifyEVMMigration() { + if s.dht != nil { + s.dht.NotifyEVMMigration() + } +} + // configure the distributed hash table for p2p service func (s *p2p) configure(ctx context.Context) error { // new the queries storage diff --git a/pkg/net/credentials/lumeratc.go b/pkg/net/credentials/lumeratc.go index 466fdbcd..6828bc8f 100644 --- a/pkg/net/credentials/lumeratc.go +++ b/pkg/net/credentials/lumeratc.go @@ -23,6 +23,15 @@ var ( keyExMutex sync.Mutex ) +// ClearKeyExchangerCache removes all cached KeyExchanger instances so that the +// next handshake creates fresh ones with the current local identity. Must be +// called when the local address changes (e.g., after EVM migration). +func ClearKeyExchangerCache() { + keyExMutex.Lock() + defer keyExMutex.Unlock() + keyExchangers = map[string]*securekeyx.SecureKeyExchange{} +} + // CommonOptions contains the shared configuration for both client and server type CommonOptions struct { Keyring keyring.Keyring diff --git a/supernode/cmd/start.go b/supernode/cmd/start.go index 5a7f4e69..9b0a8af8 100644 --- a/supernode/cmd/start.go +++ b/supernode/cmd/start.go @@ -93,9 +93,27 @@ The supernode will connect to the Lumera network and begin participating in the // Fail fast with migration instructions if key_name still points to a // legacy secp256k1 key without a valid evm_key_name, otherwise perform // the automatic on-chain migration to the new EVM-compatible address. + preMigrationKeyName := appConfig.SupernodeConfig.KeyName + preMigrationIdentity := appConfig.SupernodeConfig.Identity if err := ensureLegacyAccountMigrated(ctx, kr, appConfig, &grpcMigrationClient{conn: lumeraClient.Conn()}, lumeraClient.SuperNode()); err != nil { logtrace.Fatal(ctx, "Legacy account migration failed", logtrace.Fields{"error": err.Error()}) } + evmMigrationOccurred := appConfig.SupernodeConfig.KeyName != preMigrationKeyName || appConfig.SupernodeConfig.Identity != preMigrationIdentity + if evmMigrationOccurred { + logtrace.Info(ctx, "Reloading Lumera client after EVM migration", logtrace.Fields{ + "old_key_name": preMigrationKeyName, + "new_key_name": appConfig.SupernodeConfig.KeyName, + "old_identity": preMigrationIdentity, + "new_identity": appConfig.SupernodeConfig.Identity, + }) + if err := lumeraClient.Close(); err != nil { + logtrace.Warn(ctx, "Failed to close pre-migration Lumera client", logtrace.Fields{"error": err.Error()}) + } + lumeraClient, err = initLumeraClient(ctx, appConfig, kr) + if err != nil { + logtrace.Fatal(ctx, "Failed to reconnect Lumera after EVM migration", logtrace.Fields{"error": err.Error()}) + } + } // Reachability evidence store (used for open_ports inference). reachability.SetDefaultStore(reachability.NewStore()) @@ -153,6 +171,14 @@ The supernode will connect to the Lumera network and begin participating in the logtrace.Fatal(ctx, "Failed to initialize P2P service", logtrace.Fields{"error": err.Error()}) } + // After P2P is up, notify it about the migration so the bootstrap + // refresher immediately re-fetches peer addresses from the chain and + // temporarily switches to an accelerated 1-minute refresh interval. + if evmMigrationOccurred { + logtrace.Info(ctx, "Notifying P2P layer of EVM migration for accelerated peer discovery", logtrace.Fields{}) + p2pService.NotifyEVMMigration() + } + // Supernode wrapper removed; components are managed directly // Configure cascade service From 495f292f5fcfaba67d7b659189e722cf4984d495 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Wed, 1 Apr 2026 16:19:57 -0400 Subject: [PATCH 03/22] fix evmigration payload --- docs/evm-migration.md | 2 +- go.mod | 22 +++--- go.sum | 74 ++++++++++--------- supernode/cmd/evmigration.go | 7 +- .../evmigration/evmigration_test.go | 4 +- 5 files changed, 56 insertions(+), 53 deletions(-) diff --git a/docs/evm-migration.md b/docs/evm-migration.md index 5f1cdfac..15e52227 100644 --- a/docs/evm-migration.md +++ b/docs/evm-migration.md @@ -153,7 +153,7 @@ Query MigrationEstimate(legacy_address) |-- Query error --> proceed anyway, default isValidator=false |-- WouldSucceed=true --> capture IsValidator flag v -Build payload: "lumera-evm-migration:{claim|validator}::" +Build payload: "lumera-evm-migration:::{claim|validator}::" v Dual sign: - Legacy: kr.Sign(SHA256(payload)) -- secp256k1 internally SHA256s again diff --git a/go.mod b/go.mod index 4fc54e1a..8c66d27f 100644 --- a/go.mod +++ b/go.mod @@ -41,13 +41,13 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil/v3 v3.24.5 - github.com/spf13/cobra v1.10.1 + github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 go.uber.org/mock v0.6.0 go.uber.org/ratelimit v0.3.1 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.48.0 - golang.org/x/sync v0.19.0 + golang.org/x/sync v0.20.0 golang.org/x/sys v0.41.0 google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 google.golang.org/grpc v1.79.2 @@ -71,7 +71,7 @@ require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/datadog-go v4.8.3+incompatible // indirect - github.com/Masterminds/semver/v3 v3.3.1 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -122,7 +122,7 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // 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 @@ -157,7 +157,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lib/pq v1.10.9 // indirect + github.com/lib/pq v1.11.2 // indirect github.com/linxGnu/grocksdb v1.9.8 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -198,10 +198,10 @@ require ( github.com/tidwall/btree v1.8.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect @@ -216,11 +216,11 @@ require ( golang.org/x/arch v0.17.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect - golang.org/x/mod v0.32.0 // indirect - golang.org/x/net v0.49.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.51.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect - golang.org/x/tools v0.41.0 // indirect + golang.org/x/tools v0.42.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 64cd09a5..35e5e138 100644 --- a/go.sum +++ b/go.sum @@ -19,10 +19,10 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go/auth v0.16.4 h1:fXOAIQmkApVvcIn7Pc2+5J8QTMVbUGLscnSVNl11su8= -cloud.google.com/go/auth v0.16.4/go.mod h1:j10ncYwjX/g3cdX7GpEzsdM+d+ZNsXAbb6qXA7p1Y5M= +cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg= +cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= +cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= +cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -50,8 +50,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= -cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= +cloud.google.com/go/storage v1.53.0 h1:gg0ERZwL17pJ+Cz3cD2qS60w1WMDnwcm5YPAIQBHUAw= +cloud.google.com/go/storage v1.53.0/go.mod h1:7/eO2a/srr9ImZW9k5uufcNahT2+fPb8w5it1i5boaA= cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/client/v2 v2.0.0-beta.11 h1:iHbjDw/NuNz2OVaPmx0iE9eu2HrbX+WAv2u9guRcd6o= @@ -106,17 +106,17 @@ github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/LumeraProtocol/lumera v1.11.2-0.20260331140230-4aeb5d0d7a89 h1:wDZnZ5wi4l0qyMufE3bOQImu1BF/igMAsxr6aMWRmp4= github.com/LumeraProtocol/lumera v1.11.2-0.20260331140230-4aeb5d0d7a89/go.mod h1:p2sZZG3bLzSBdaW883qjuU3DXXY4NJzTTwLywr8uI0w= github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4= github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8= -github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= -github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= @@ -434,8 +434,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -445,8 +445,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -607,8 +607,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -711,8 +711,9 @@ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzW github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= 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.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs= @@ -952,8 +953,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -967,8 +968,8 @@ github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8 github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -1017,14 +1018,15 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= @@ -1181,8 +1183,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= 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= @@ -1240,8 +1242,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= 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= @@ -1269,8 +1271,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= 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= @@ -1454,8 +1456,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= 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= diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index f6a29016..7fcb6c07 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -9,6 +9,7 @@ import ( "time" upgradetypes "cosmossdk.io/x/upgrade/types" + lcfg "github.com/LumeraProtocol/lumera/config" evmigrationtypes "github.com/LumeraProtocol/lumera/x/evmigration/types" "github.com/LumeraProtocol/supernode/v2/pkg/logtrace" lumeracodec "github.com/LumeraProtocol/supernode/v2/pkg/lumera/codec" @@ -293,7 +294,9 @@ func ensureLegacyAccountMigrated( } // Build the canonical migration payload. - payload := []byte(fmt.Sprintf("lumera-evm-migration:%s:%s:%s", payloadKind, legacyAddr.String(), newAddr.String())) + // Format: lumera-evm-migration::::: + chainID := cfg.LumeraClientConfig.ChainID + payload := []byte(fmt.Sprintf("lumera-evm-migration:%s:%d:%s:%s:%s", chainID, lcfg.EVMChainID, payloadKind, legacyAddr.String(), newAddr.String())) // Sign with legacy key from keyring. // secp256k1.Sign(msg) internally computes SHA256(msg), and the chain verifier @@ -321,7 +324,6 @@ func ensureLegacyAccountMigrated( LegacyAddress: legacyAddr.String(), LegacyPubKey: legacyPubKey.Bytes(), LegacySignature: legacySig, - NewPubKey: newPubKey.Bytes(), NewSignature: newSig, } logtrace.Info(ctx, "Validator account detected — using MsgMigrateValidator", logtrace.Fields{ @@ -334,7 +336,6 @@ func ensureLegacyAccountMigrated( LegacyAddress: legacyAddr.String(), LegacyPubKey: legacyPubKey.Bytes(), LegacySignature: legacySig, - NewPubKey: newPubKey.Bytes(), NewSignature: newSig, } } diff --git a/tests/integration/evmigration/evmigration_test.go b/tests/integration/evmigration/evmigration_test.go index 0d951e69..540e8a75 100644 --- a/tests/integration/evmigration/evmigration_test.go +++ b/tests/integration/evmigration/evmigration_test.go @@ -86,7 +86,7 @@ func TestFullMigrationKeyringFlow(t *testing.T) { // Step 3: Sign migration payload with both keys (simulating what // ensureLegacyAccountMigrated does). - payload := []byte("lumera-evm-migration:claim:" + legacyAddr.String() + ":" + evmAddr.String()) + payload := []byte("lumera-evm-migration:test-chain-1:76857769:claim:" + legacyAddr.String() + ":" + evmAddr.String()) // Legacy signing: SHA256(payload) → keyring.Sign (which does another SHA256 internally). hash := sha256.Sum256(payload) @@ -222,7 +222,7 @@ func TestDualSigningProtocol(t *testing.T) { require.NoError(t, err) evmAddr := sdk.AccAddress(evmPubKey.Address()) - payload := []byte("lumera-evm-migration:claim:" + legacyAddr.String() + ":" + evmAddr.String()) + payload := []byte("lumera-evm-migration:test-chain-1:76857769:claim:" + legacyAddr.String() + ":" + evmAddr.String()) // --- Legacy signature protocol --- // The supernode passes SHA256(payload) to kr.Sign. From 053b2e7142ee11fae8bc55e0e35d1535d08443ac Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 21 Apr 2026 15:09:38 -0400 Subject: [PATCH 04/22] fix evmigration legacy proof payload --- cmd/sncli/go.mod | 18 ++-- cmd/sncli/go.sum | 74 ++++++++-------- docs/evm-migration.md | 8 +- go.mod | 16 ++-- go.sum | 63 ++++++------- sn-manager/go.mod | 6 +- sn-manager/go.sum | 13 +-- supernode/cmd/evmigration.go | 32 ++++--- supernode/cmd/evmigration_test.go | 16 ++-- tests/system/go.mod | 32 +++---- tests/system/go.sum | 143 ++++++++++++++++-------------- 11 files changed, 224 insertions(+), 197 deletions(-) diff --git a/cmd/sncli/go.mod b/cmd/sncli/go.mod index 1ea3493f..ac1a138f 100644 --- a/cmd/sncli/go.mod +++ b/cmd/sncli/go.mod @@ -11,12 +11,12 @@ replace ( ) require ( - github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c + github.com/BurntSushi/toml v1.6.0 github.com/LumeraProtocol/lumera v1.11.0 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.53.6 - github.com/spf13/cobra v1.10.1 - google.golang.org/grpc v1.79.2 + github.com/spf13/cobra v1.10.2 + google.golang.org/grpc v1.79.3 google.golang.org/protobuf v1.36.11 ) @@ -38,7 +38,7 @@ require ( github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/datadog-go v4.8.3+incompatible // indirect github.com/DataDog/zstd v1.5.7 // indirect - github.com/Masterminds/semver/v3 v3.3.1 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -98,7 +98,7 @@ require ( github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // 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 @@ -137,7 +137,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lib/pq v1.10.9 // indirect + github.com/lib/pq v1.11.2 // indirect github.com/linxGnu/grocksdb v1.9.8 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -177,7 +177,7 @@ require ( github.com/tidwall/btree v1.8.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect @@ -195,8 +195,8 @@ require ( golang.org/x/arch v0.17.0 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect - golang.org/x/net v0.49.0 // indirect - golang.org/x/sync v0.19.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect diff --git a/cmd/sncli/go.sum b/cmd/sncli/go.sum index 859e0fb0..b4c17bc2 100644 --- a/cmd/sncli/go.sum +++ b/cmd/sncli/go.sum @@ -19,10 +19,10 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go/auth v0.16.4 h1:fXOAIQmkApVvcIn7Pc2+5J8QTMVbUGLscnSVNl11su8= -cloud.google.com/go/auth v0.16.4/go.mod h1:j10ncYwjX/g3cdX7GpEzsdM+d+ZNsXAbb6qXA7p1Y5M= +cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg= +cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= +cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= +cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -50,8 +50,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= -cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= +cloud.google.com/go/storage v1.53.0 h1:gg0ERZwL17pJ+Cz3cD2qS60w1WMDnwcm5YPAIQBHUAw= +cloud.google.com/go/storage v1.53.0/go.mod h1:7/eO2a/srr9ImZW9k5uufcNahT2+fPb8w5it1i5boaA= cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/client/v2 v2.0.0-beta.11 h1:iHbjDw/NuNz2OVaPmx0iE9eu2HrbX+WAv2u9guRcd6o= @@ -92,8 +92,8 @@ github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTB github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CosmWasm/wasmd v0.61.6 h1:wa1rY/mZi8OYnf0f6a02N7o3vBockOfL3P37hSH0XtY= github.com/CosmWasm/wasmd v0.61.6/go.mod h1:Wg2gfY2qrjjFY8UvpkTCRdy8t67qebOQn7UvRiGRzDw= @@ -106,13 +106,13 @@ github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= -github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -423,8 +423,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -434,8 +434,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -596,8 +596,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -694,8 +694,9 @@ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzW github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= 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.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs= @@ -917,8 +918,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -932,8 +933,8 @@ github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8 github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -982,14 +983,15 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= @@ -1200,8 +1202,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= 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= @@ -1229,8 +1231,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= 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= @@ -1520,8 +1522,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= -google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/docs/evm-migration.md b/docs/evm-migration.md index 15e52227..46a618f6 100644 --- a/docs/evm-migration.md +++ b/docs/evm-migration.md @@ -150,7 +150,7 @@ Query MigrationRecord(legacy_address) v Query MigrationEstimate(legacy_address) |-- WouldSucceed=false --> ERROR (with rejection reason) - |-- Query error --> proceed anyway, default isValidator=false + |-- Query error --> ERROR (fail closed; restart to retry) |-- WouldSucceed=true --> capture IsValidator flag v Build payload: "lumera-evm-migration:::{claim|validator}::" @@ -168,9 +168,9 @@ broadcastMigrationTx() v Verify new address registered as supernode (non-fatal) v -Delete legacy key from keyring - v Update config (key_name, identity, evm_key_name) and save + v +Delete legacy key from keyring ``` ### Signing Protocol @@ -366,7 +366,7 @@ type SupernodeConfig struct { **Message fields and resilience (2 tests):** - `TestEnsureLegacyAccountMigrated_MessageFieldsCorrect` — verifies addresses, public keys, and signatures in broadcasted message -- `TestEnsureLegacyAccountMigrated_BothQueriesFail_StillBroadcasts` — both MigrationRecord and MigrationEstimate fail, still broadcasts with defaults +- `TestEnsureLegacyAccountMigrated_BothQueriesFail_FailsClosed` — MigrationRecord query failure is tolerated, but MigrationEstimate query failure aborts before broadcast **End-to-end (1 test):** diff --git a/go.mod b/go.mod index 8c66d27f..7524046a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/LumeraProtocol/supernode/v2 -go 1.26.1 +go 1.26.2 replace ( // Use local Lumera with EVM support (evmigration, erc20policy, etc.) @@ -49,8 +49,8 @@ require ( golang.org/x/crypto v0.48.0 golang.org/x/sync v0.20.0 golang.org/x/sys v0.41.0 - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 - google.golang.org/grpc v1.79.2 + google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 + google.golang.org/grpc v1.80.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.4.1 @@ -61,13 +61,13 @@ require ( cosmossdk.io/collections v1.4.0 // indirect cosmossdk.io/core v0.11.3 // indirect cosmossdk.io/depinject v1.2.1 // indirect - cosmossdk.io/errors v1.0.2 // indirect + cosmossdk.io/errors v1.1.0 // indirect cosmossdk.io/log v1.6.1 // indirect cosmossdk.io/schema v1.1.0 // indirect cosmossdk.io/store v1.1.2 // indirect cosmossdk.io/x/feegrant v0.2.0 // indirect cosmossdk.io/x/tx v0.14.0 // indirect - filippo.io/edwards25519 v1.1.0 // indirect + filippo.io/edwards25519 v1.1.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/datadog-go v4.8.3+incompatible // indirect @@ -112,7 +112,7 @@ require ( github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect - github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/ethereum/go-ethereum v1.17.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -127,7 +127,7 @@ require ( github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect - github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -222,7 +222,7 @@ require ( golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.42.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.2 // indirect lukechampine.com/uint128 v1.3.0 // indirect diff --git a/go.sum b/go.sum index 35e5e138..8098d018 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= cosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM= -cosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo= -cosmossdk.io/errors v1.0.2/go.mod h1:0rjgiHkftRYPj//3DrD6y8hcm40HcPv/dR4R/4efr0k= +cosmossdk.io/errors v1.1.0 h1:X2DSt9JYgH7cuiaDr318aUqIl2z5Lfo/PdGzAtmczUU= +cosmossdk.io/errors v1.1.0/go.mod h1:lnjBmx7etZpMTLnxdspZupH0d9HGRWZhiezDZX2ayyI= cosmossdk.io/log v1.6.1 h1:YXNwAgbDwMEKwDlCdH8vPcoggma48MgZrTQXCfmMBeI= cosmossdk.io/log v1.6.1/go.mod h1:gMwsWyyDBjpdG9u2avCFdysXqxq28WJapJvu+vF1y+E= cosmossdk.io/math v1.5.3 h1:WH6tu6Z3AUCeHbeOSHg2mt9rnoiUWVWaQ2t6Gkll96U= @@ -83,8 +83,9 @@ cosmossdk.io/x/tx v0.14.0/go.mod h1:Tn30rSRA1PRfdGB3Yz55W4Sn6EIutr9xtMKSHij+9PM= cosmossdk.io/x/upgrade v0.2.0 h1:ZHy0xny3wBCSLomyhE06+UmQHWO8cYlVYjfFAJxjz5g= cosmossdk.io/x/upgrade v0.2.0/go.mod h1:DXDtkvi//TrFyHWSOaeCZGBoiGAE6Rs8/0ABt2pcDD0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= @@ -95,17 +96,17 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEK github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/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.61.6 h1:wa1rY/mZi8OYnf0f6a02N7o3vBockOfL3P37hSH0XtY= -github.com/CosmWasm/wasmd v0.61.6/go.mod h1:Wg2gfY2qrjjFY8UvpkTCRdy8t67qebOQn7UvRiGRzDw= -github.com/CosmWasm/wasmvm/v3 v3.0.2 h1:+MLkOX+IdklITLqfG26PCFv5OXdZvNb8z5Wq5JFXTRM= -github.com/CosmWasm/wasmvm/v3 v3.0.2/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= +github.com/CosmWasm/wasmd v0.61.10 h1:BB5dhCys4MSvRKUNvW1eFuhm61/251mFJ5Hefvm7MD0= +github.com/CosmWasm/wasmd v0.61.10/go.mod h1:GMPqtsb1T8FvaKpQGJmGuj/JMPXBauk4ZhUErgmtEus= +github.com/CosmWasm/wasmvm/v3 v3.0.3 h1:rg8cZ2qXFj3HwUOqni53OZV/oTvmA2mTVabKA7L0sro= +github.com/CosmWasm/wasmvm/v3 v3.0.3/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= @@ -400,8 +401,8 @@ github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -494,8 +495,8 @@ 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.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -1077,16 +1078,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= 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= @@ -1463,8 +1464,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1539,10 +1540,10 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= 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= @@ -1569,8 +1570,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= -google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/sn-manager/go.mod b/sn-manager/go.mod index b5345a3c..48cf5436 100644 --- a/sn-manager/go.mod +++ b/sn-manager/go.mod @@ -13,7 +13,7 @@ replace ( require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 - github.com/spf13/cobra v1.10.1 + github.com/spf13/cobra v1.10.2 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 ) @@ -26,11 +26,11 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/spf13/pflag v1.0.10 // indirect - golang.org/x/net v0.49.0 // indirect + golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/grpc v1.79.2 // indirect + google.golang.org/grpc v1.79.3 // indirect ) diff --git a/sn-manager/go.sum b/sn-manager/go.sum index 11186ce8..22152bc6 100644 --- a/sn-manager/go.sum +++ b/sn-manager/go.sum @@ -47,8 +47,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -69,14 +69,15 @@ go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2W go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -108,8 +109,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1: google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= -google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index 7fcb6c07..7813188e 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -316,15 +316,28 @@ func ensureLegacyAccountMigrated( return fmt.Errorf("failed to sign migration payload with EVM key: %w", err) } + // Build the LegacyProof wrapper. The keeper replaced the flat + // LegacyPubKey/LegacySignature fields with a single oneof carrying + // either a SingleKeyProof or MultisigProof; supernode only ever signs + // with one secp256k1 key so we always use the Single case. + legacyProof := evmigrationtypes.LegacyProof{ + Proof: &evmigrationtypes.LegacyProof_Single{ + Single: &evmigrationtypes.SingleKeyProof{ + PubKey: legacyPubKey.Bytes(), + Signature: legacySig, + SigFormat: evmigrationtypes.SigFormat_SIG_FORMAT_CLI, + }, + }, + } + // Build the appropriate message type. var msg sdk.Msg if isValidator { msg = &evmigrationtypes.MsgMigrateValidator{ - NewAddress: newAddr.String(), - LegacyAddress: legacyAddr.String(), - LegacyPubKey: legacyPubKey.Bytes(), - LegacySignature: legacySig, - NewSignature: newSig, + NewAddress: newAddr.String(), + LegacyAddress: legacyAddr.String(), + LegacyProof: legacyProof, + NewSignature: newSig, } logtrace.Info(ctx, "Validator account detected — using MsgMigrateValidator", logtrace.Fields{ "legacy_address": legacyAddr.String(), @@ -332,11 +345,10 @@ func ensureLegacyAccountMigrated( }) } else { msg = &evmigrationtypes.MsgClaimLegacyAccount{ - NewAddress: newAddr.String(), - LegacyAddress: legacyAddr.String(), - LegacyPubKey: legacyPubKey.Bytes(), - LegacySignature: legacySig, - NewSignature: newSig, + NewAddress: newAddr.String(), + LegacyAddress: legacyAddr.String(), + LegacyProof: legacyProof, + NewSignature: newSig, } } diff --git a/supernode/cmd/evmigration_test.go b/supernode/cmd/evmigration_test.go index 78ccb97c..804b4612 100644 --- a/supernode/cmd/evmigration_test.go +++ b/supernode/cmd/evmigration_test.go @@ -839,10 +839,12 @@ func TestEnsureLegacyAccountMigrated_ValidatorFullHappyPath(t *testing.T) { valMsg, isVal := mc.broadcastedMsg.(*evmigrationtypes.MsgMigrateValidator) require.True(t, isVal, "should use MsgMigrateValidator for validator") assert.Equal(t, newAddr, valMsg.NewAddress) - assert.NotEmpty(t, valMsg.LegacySignature) assert.NotEmpty(t, valMsg.NewSignature) - assert.NotEmpty(t, valMsg.LegacyPubKey) - assert.NotEmpty(t, valMsg.NewPubKey) + valSingle := valMsg.LegacyProof.GetSingle() + require.NotNil(t, valSingle, "expected single-key legacy proof") + assert.NotEmpty(t, valSingle.Signature) + assert.NotEmpty(t, valSingle.PubKey) + assert.Equal(t, evmigrationtypes.SigFormat_SIG_FORMAT_CLI, valSingle.SigFormat) // Legacy key deleted. _, err = kr.Key("val-key") @@ -1044,10 +1046,12 @@ func TestEnsureLegacyAccountMigrated_MessageFieldsCorrect(t *testing.T) { assert.Equal(t, legacyAddr.String(), claimMsg.LegacyAddress) assert.Equal(t, newAddr, claimMsg.NewAddress) - assert.Equal(t, legacyPub.Bytes(), claimMsg.LegacyPubKey) - assert.Equal(t, evmPub.Bytes(), claimMsg.NewPubKey) - assert.NotEmpty(t, claimMsg.LegacySignature) assert.NotEmpty(t, claimMsg.NewSignature) + claimSingle := claimMsg.LegacyProof.GetSingle() + require.NotNil(t, claimSingle, "expected single-key legacy proof") + assert.Equal(t, legacyPub.Bytes(), claimSingle.PubKey) + assert.NotEmpty(t, claimSingle.Signature) + assert.Equal(t, evmigrationtypes.SigFormat_SIG_FORMAT_CLI, claimSingle.SigFormat) } // --- estimate with both record query error and estimate error --- diff --git a/tests/system/go.mod b/tests/system/go.mod index 48012c63..b2c06588 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -1,11 +1,13 @@ module github.com/LumeraProtocol/supernode/v2/tests/systemtests -go 1.26.1 +go 1.26.2 replace ( github.com/LumeraProtocol/lumera => ../../../lumera github.com/LumeraProtocol/supernode/v2 => ../../ github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 + // cosmos/evm requires a forked go-ethereum with custom EVM operation methods + github.com/ethereum/go-ethereum => github.com/cosmos/go-ethereum v1.16.2-cosmos-1 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 nhooyr.io/websocket => github.com/coder/websocket v1.8.7 ) @@ -30,20 +32,20 @@ require ( cosmossdk.io/collections v1.4.0 // indirect cosmossdk.io/core v0.11.3 // indirect cosmossdk.io/depinject v1.2.1 // indirect - cosmossdk.io/errors v1.0.2 // indirect + cosmossdk.io/errors v1.1.0 // indirect cosmossdk.io/log v1.6.1 // indirect cosmossdk.io/schema v1.1.0 // indirect cosmossdk.io/store v1.1.2 // indirect cosmossdk.io/x/feegrant v0.2.0 // indirect cosmossdk.io/x/tx v0.14.0 // indirect cosmossdk.io/x/upgrade v0.2.0 // indirect - filippo.io/edwards25519 v1.1.0 // indirect + filippo.io/edwards25519 v1.1.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/datadog-go v4.8.3+incompatible // indirect github.com/DataDog/zstd v1.5.7 // indirect github.com/LumeraProtocol/rq-go v0.2.1 // indirect - github.com/Masterminds/semver/v3 v3.3.1 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.2.0 // indirect @@ -88,7 +90,7 @@ require ( github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect - github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/ethereum/go-ethereum v1.17.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -98,13 +100,13 @@ require ( github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // 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/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -135,7 +137,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lib/pq v1.10.9 // indirect + github.com/lib/pq v1.11.2 // indirect github.com/linxGnu/grocksdb v1.9.8 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -161,7 +163,7 @@ require ( github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/viper v1.21.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect @@ -170,7 +172,7 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.8.1 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/zondax/golem v0.27.0 // indirect @@ -185,15 +187,15 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.17.0 // indirect golang.org/x/crypto v0.48.0 // indirect - golang.org/x/net v0.49.0 // indirect - golang.org/x/sync v0.19.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/grpc v1.79.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect + google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.2 // indirect diff --git a/tests/system/go.sum b/tests/system/go.sum index b5cac596..72f37681 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -19,10 +19,10 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go/auth v0.16.4 h1:fXOAIQmkApVvcIn7Pc2+5J8QTMVbUGLscnSVNl11su8= -cloud.google.com/go/auth v0.16.4/go.mod h1:j10ncYwjX/g3cdX7GpEzsdM+d+ZNsXAbb6qXA7p1Y5M= +cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg= +cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= +cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= +cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -50,8 +50,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= -cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= +cloud.google.com/go/storage v1.53.0 h1:gg0ERZwL17pJ+Cz3cD2qS60w1WMDnwcm5YPAIQBHUAw= +cloud.google.com/go/storage v1.53.0/go.mod h1:7/eO2a/srr9ImZW9k5uufcNahT2+fPb8w5it1i5boaA= cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= cosmossdk.io/client/v2 v2.0.0-beta.11 h1:iHbjDw/NuNz2OVaPmx0iE9eu2HrbX+WAv2u9guRcd6o= @@ -62,8 +62,8 @@ cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= cosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM= -cosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo= -cosmossdk.io/errors v1.0.2/go.mod h1:0rjgiHkftRYPj//3DrD6y8hcm40HcPv/dR4R/4efr0k= +cosmossdk.io/errors v1.1.0 h1:X2DSt9JYgH7cuiaDr318aUqIl2z5Lfo/PdGzAtmczUU= +cosmossdk.io/errors v1.1.0/go.mod h1:lnjBmx7etZpMTLnxdspZupH0d9HGRWZhiezDZX2ayyI= cosmossdk.io/log v1.6.1 h1:YXNwAgbDwMEKwDlCdH8vPcoggma48MgZrTQXCfmMBeI= cosmossdk.io/log v1.6.1/go.mod h1:gMwsWyyDBjpdG9u2avCFdysXqxq28WJapJvu+vF1y+E= cosmossdk.io/math v1.5.3 h1:WH6tu6Z3AUCeHbeOSHg2mt9rnoiUWVWaQ2t6Gkll96U= @@ -83,34 +83,34 @@ cosmossdk.io/x/tx v0.14.0/go.mod h1:Tn30rSRA1PRfdGB3Yz55W4Sn6EIutr9xtMKSHij+9PM= cosmossdk.io/x/upgrade v0.2.0 h1:ZHy0xny3wBCSLomyhE06+UmQHWO8cYlVYjfFAJxjz5g= cosmossdk.io/x/upgrade v0.2.0/go.mod h1:DXDtkvi//TrFyHWSOaeCZGBoiGAE6Rs8/0ABt2pcDD0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/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.61.6 h1:wa1rY/mZi8OYnf0f6a02N7o3vBockOfL3P37hSH0XtY= -github.com/CosmWasm/wasmd v0.61.6/go.mod h1:Wg2gfY2qrjjFY8UvpkTCRdy8t67qebOQn7UvRiGRzDw= -github.com/CosmWasm/wasmvm/v3 v3.0.2 h1:+MLkOX+IdklITLqfG26PCFv5OXdZvNb8z5Wq5JFXTRM= -github.com/CosmWasm/wasmvm/v3 v3.0.2/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= +github.com/CosmWasm/wasmd v0.61.10 h1:BB5dhCys4MSvRKUNvW1eFuhm61/251mFJ5Hefvm7MD0= +github.com/CosmWasm/wasmd v0.61.10/go.mod h1:GMPqtsb1T8FvaKpQGJmGuj/JMPXBauk4ZhUErgmtEus= +github.com/CosmWasm/wasmvm/v3 v3.0.3 h1:rg8cZ2qXFj3HwUOqni53OZV/oTvmA2mTVabKA7L0sro= +github.com/CosmWasm/wasmvm/v3 v3.0.3/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4= github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8= -github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= -github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -269,6 +269,8 @@ github.com/cosmos/evm v0.6.0 h1:jwJerLS7btDgDpZOYy7lUC+1rNRCGGE80TJ6r4guufo= github.com/cosmos/evm v0.6.0/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= 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/go-ethereum v1.16.2-cosmos-1 h1:QIaIS6HIdPSBdTvpFhxswhMLUJgcr4irbd2o9ZKldAI= +github.com/cosmos/go-ethereum v1.16.2-cosmos-1/go.mod h1:X5CIOyo8SuK1Q5GnaEizQVLHT/DfsiGWuNeVdQcEMNA= 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= @@ -292,8 +294,6 @@ github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= -github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= -github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= @@ -354,8 +354,6 @@ github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9O github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= -github.com/ethereum/go-ethereum v1.15.11 h1:JK73WKeu0WC0O1eyX+mdQAVHUV+UR1a9VB/domDngBU= -github.com/ethereum/go-ethereum v1.15.11/go.mod h1:mf8YiHIb0GR4x4TipcvBUPxJLw1mFdmxzoDi11sDRoI= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -364,6 +362,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -386,8 +386,8 @@ github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -416,8 +416,8 @@ github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -430,8 +430,8 @@ github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PU github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -480,8 +480,8 @@ 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.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -592,8 +592,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -692,8 +692,8 @@ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzW github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= 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.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs= @@ -724,6 +724,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -733,6 +735,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -908,8 +912,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -923,8 +927,8 @@ github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8 github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -971,14 +975,15 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= @@ -1029,16 +1034,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= 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= @@ -1183,8 +1188,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= 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= @@ -1212,8 +1217,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= 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= @@ -1394,8 +1399,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1470,10 +1475,10 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= 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= @@ -1500,8 +1505,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= -google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 7bda95bfb93cb22b9cbc5fb805357f7978159723 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 21 Apr 2026 15:58:17 -0400 Subject: [PATCH 05/22] evmigration: refuse automatic migration for multisig legacy accounts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supernode's startup migration path holds a single signing key and cannot run the K-of-N ceremony required for a multisig legacy account. Detect is_multisig=true from MigrationEstimate and return an actionable error pointing to lumerad's 4-step offline flow (generate-proof-payload → sign-proof → assemble-proof → submit-proof). After the operator completes the offline ceremony, the next restart finds the on-chain MigrationRecord and drives local cleanup through the existing alreadyMigrated branch — no new multisig-aware code in the daemon. Also log the new is_multisig/threshold/num_signers fields from QueryMigrationEstimate in the pre-flight summary, and bump the lumera pseudo-version pin to origin/evm HEAD (e09830d70704) so a clean checkout without ../lumera still resolves to a version that has the LegacyProof oneof, SingleKeyProof/MultisigProof types, and MaxMultisigSubKeys param. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/evm-migration.md | 35 +++++++++++++++++ go.mod | 2 +- go.sum | 2 - supernode/cmd/evmigration.go | 39 +++++++++++++++++++ supernode/cmd/evmigration_test.go | 64 +++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 3 deletions(-) diff --git a/docs/evm-migration.md b/docs/evm-migration.md index 46a618f6..57407dbc 100644 --- a/docs/evm-migration.md +++ b/docs/evm-migration.md @@ -76,9 +76,44 @@ The migration is: | `not an eth_secp256k1 key` | `evm_key_name` points to a secp256k1 key (wrong derivation) | Re-derive using `supernode keys recover` (uses coin type 60) | | `new address mismatch` | On-chain migration record has a different destination address than your local EVM key | Your `evm_key_name` doesn't match the key originally used for migration; fix the config | | `migration estimate indicates migration would fail` | Chain rejected the pre-flight check | Check `rejection_reason` in logs; migration may be disabled or account may not exist | +| `automatic migration is not supported` (multisig) | Legacy supernode account is a K-of-N multisig; the daemon holds a single key | Complete the migration out-of-band using the `lumerad tx evmigration` 4-step offline flow (see Multisig section below), then restart supernode to trigger local cleanup | | `migration tx was not confirmed` | Tx was not included in a block within 60s | Restart to retry; the check is idempotent | | `failed to save updated config` | Config file write error after successful migration | Manually update config as instructed in the error message | +### Multisig legacy accounts + +A supernode daemon holds a single signing key and cannot run the K-of-N signing +ceremony required for a multisig legacy account. When startup detects +`is_multisig=true` in `QueryMigrationEstimate`, the daemon refuses to sign and +instructs the operator to complete migration offline using `lumerad`: + +```bash +# 1. Generate the payload template (queries on-chain pubkey). +lumerad tx evmigration generate-proof-payload \ + --legacy-address --new-address \ + --chain-id --kind claim \ + > proof.json +# Use --kind validator if the account is a validator operator. + +# 2. Each of K sub-signers signs independently. +lumerad tx evmigration sign-proof proof.json --from \ + --chain-id > partial-1.json +# ... repeat on each sub-signer's machine, producing partial-2.json, ... + +# 3. Assemble the K partial proofs into one full proof. +lumerad tx evmigration assemble-proof proof.json partial-*.json > signed.json + +# 4. Broadcast. Any funded account can pay the (zero) fee. +lumerad tx evmigration submit-proof signed.json --from \ + --chain-id +``` + +After `submit-proof` lands in a block, restart supernode. The startup migration +check sees the existing on-chain `MigrationRecord`, skips broadcasting, and +performs local cleanup (delete legacy key from the keyring, update +`key_name`/`identity`, clear `evm_key_name`) via the idempotent path — no +special handling for multisig is needed on the daemon side. + ## Chain-Side Reference The on-chain `x/evmigration` module is documented in detail in the Lumera chain diff --git a/go.mod b/go.mod index 7524046a..fc6dea8c 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( cosmossdk.io/x/upgrade v0.2.0 github.com/AlecAivazis/survey/v2 v2.3.7 github.com/DataDog/zstd v1.5.7 - github.com/LumeraProtocol/lumera v1.11.2-0.20260331140230-4aeb5d0d7a89 + github.com/LumeraProtocol/lumera v1.11.2-0.20260420182021-e09830d70704 github.com/LumeraProtocol/rq-go v0.2.1 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/cenkalti/backoff/v4 v4.3.0 diff --git a/go.sum b/go.sum index 8098d018..d70aa814 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,6 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.11.2-0.20260331140230-4aeb5d0d7a89 h1:wDZnZ5wi4l0qyMufE3bOQImu1BF/igMAsxr6aMWRmp4= -github.com/LumeraProtocol/lumera v1.11.2-0.20260331140230-4aeb5d0d7a89/go.mod h1:p2sZZG3bLzSBdaW883qjuU3DXXY4NJzTTwLywr8uI0w= github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4= github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index 7813188e..a9c7de9e 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -28,6 +28,39 @@ const ( evmModuleName = "evm" ) +// multisigMigrationInstructions returns an error directing the operator to the +// lumerad offline CLI flow. The supernode daemon holds a single signing key and +// cannot participate in the K-of-N ceremony required for a multisig legacy +// account; migration must be completed out-of-band, after which the next +// supernode restart will detect the on-chain MigrationRecord and finish local +// cleanup (delete legacy key, update config) via the idempotent path. +func multisigMigrationInstructions(legacyAddr, newAddr, chainID string, threshold, numSigners uint32) error { + return fmt.Errorf( + "legacy supernode account %s is a %d-of-%d multisig; automatic migration is not supported.\n\n"+ + "The daemon holds a single key and cannot run the multi-party signing ceremony. "+ + "Please complete migration offline using the lumerad CLI, then restart supernode — "+ + "the existing on-chain record will trigger local cleanup automatically.\n\n"+ + "Offline flow (run on any host with lumerad and the sub-signers' keyrings):\n"+ + " 1. lumerad tx evmigration generate-proof-payload \\\n"+ + " --legacy-address %s --new-address %s --chain-id %s --kind claim \\\n"+ + " > proof.json\n"+ + " (use --kind validator if this account is a validator operator)\n"+ + " 2. Each of %d sub-signers runs:\n"+ + " lumerad tx evmigration sign-proof proof.json --from \\\n"+ + " --chain-id %s > partial-.json\n"+ + " 3. lumerad tx evmigration assemble-proof proof.json partial-*.json > signed.json\n"+ + " 4. lumerad tx evmigration submit-proof signed.json --from \\\n"+ + " --chain-id %s\n\n"+ + "After submit-proof lands in a block, restart supernode to complete local cleanup.\n"+ + "See docs/evm-migration.md for details.", + legacyAddr, threshold, numSigners, + legacyAddr, newAddr, chainID, + threshold, + chainID, + chainID, + ) +} + func legacyKeyMigrationInstructions(keyName string) string { return fmt.Sprintf( "Lumera is running with the EVM module enabled, but supernode.key_name=%q still points to a legacy secp256k1 key (coin type 118).\n\n"+ @@ -275,6 +308,9 @@ func ensureLegacyAccountMigrated( "would_succeed": estimateResp.WouldSucceed, "rejection_reason": estimateResp.RejectionReason, "is_validator": estimateResp.IsValidator, + "is_multisig": estimateResp.IsMultisig, + "threshold": estimateResp.Threshold, + "num_signers": estimateResp.NumSigners, "total_touched": estimateResp.TotalTouched, }) if !estimateResp.WouldSucceed { @@ -283,6 +319,9 @@ func ensureLegacyAccountMigrated( legacyAddr.String(), estimateResp.RejectionReason, ) } + if estimateResp.IsMultisig { + return multisigMigrationInstructions(legacyAddr.String(), newAddr.String(), cfg.LumeraClientConfig.ChainID, estimateResp.Threshold, estimateResp.NumSigners) + } } // Choose the correct payload kind based on whether the legacy account diff --git a/supernode/cmd/evmigration_test.go b/supernode/cmd/evmigration_test.go index 804b4612..1d4a1c8b 100644 --- a/supernode/cmd/evmigration_test.go +++ b/supernode/cmd/evmigration_test.go @@ -477,6 +477,70 @@ func TestEnsureLegacyAccountMigrated_EstimateWouldNotSucceed(t *testing.T) { assert.Nil(t, mc.broadcastedMsg) } +// --- multisig legacy account tests --- + +func TestEnsureLegacyAccountMigrated_MultisigRefused(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + cfg.LumeraClientConfig.ChainID = "lumera-devnet-1" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, // no record + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + IsValidator: false, + IsMultisig: true, + Threshold: 2, + NumSigners: 3, + }, + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "2-of-3 multisig") + assert.Contains(t, err.Error(), "automatic migration is not supported") + assert.Contains(t, err.Error(), "lumerad tx evmigration generate-proof-payload") + assert.Contains(t, err.Error(), "sign-proof") + assert.Contains(t, err.Error(), "assemble-proof") + assert.Contains(t, err.Error(), "submit-proof") + assert.Contains(t, err.Error(), "lumera-devnet-1") + assert.Nil(t, mc.broadcastedMsg, "should not broadcast for multisig accounts") +} + +// Multisig accounts that were already migrated out-of-band should still reach +// local cleanup via the alreadyMigrated branch — the daemon never looks at the +// proof shape on the chain record, only at the new address. +func TestEnsureLegacyAccountMigrated_MultisigAlreadyMigrated_CleanupProceeds(t *testing.T) { + kr := newTestKeyring(t) + addLegacyKey(t, kr, "mykey") + addEVMKey(t, kr, "evm-key") + + newAddr := evmKeyAddr(t, kr, "evm-key") + cfg := newMigrationCfg(t, "mykey", "evm-key") + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{ + Record: &evmigrationtypes.MigrationRecord{ + NewAddress: newAddr, + }, + }, + // estimateResp intentionally absent — alreadyMigrated short-circuits before the estimate call. + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.NoError(t, err) + + // Local cleanup must complete: legacy key deleted, config updated to EVM key. + _, err = kr.Key("mykey") + require.Error(t, err, "legacy key should be deleted after offline migration completes") + assert.Equal(t, "evm-key", cfg.SupernodeConfig.KeyName) + assert.Equal(t, newAddr, cfg.SupernodeConfig.Identity) + assert.Nil(t, mc.broadcastedMsg, "no broadcast needed — migration already on-chain") +} + // --- broadcast failure tests --- func TestEnsureLegacyAccountMigrated_BroadcastFails(t *testing.T) { From 1ab5bc5ef5ad5430f23dce0c94fc5e7f7bb55c95 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 21 Apr 2026 15:58:26 -0400 Subject: [PATCH 06/22] sncli: align go.mod with EVM-enabled lumera MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sncli transitively depends on lumera's app package (via x/lumeraid/securekeyx tests), which pulls in cosmos/evm's statedb → github.com/ethereum/go-ethereum/trie/utils. Upstream go-ethereum doesn't export that package; cosmos/evm requires the cosmos/go-ethereum fork. The main go.mod already has this replace; mirror it here so `go build ./...` from cmd/sncli resolves. Bump the lumera require to the pseudo-version at origin/evm HEAD (was v1.11.0 from before the EVM work) and let go mod tidy refresh the rest of the indirect graph to match the root module. Co-Authored-By: Claude Opus 4.7 (1M context) --- cmd/sncli/go.mod | 21 ++++++++------ cmd/sncli/go.sum | 75 ++++++++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/cmd/sncli/go.mod b/cmd/sncli/go.mod index ac1a138f..c3583d2b 100644 --- a/cmd/sncli/go.mod +++ b/cmd/sncli/go.mod @@ -1,22 +1,25 @@ module github.com/LumeraProtocol/supernode/v2/cmd/sncli -go 1.26.1 +go 1.26.2 replace ( + // Use local Lumera with EVM support (evmigration, erc20policy, etc.) github.com/LumeraProtocol/lumera => ../../../lumera github.com/LumeraProtocol/supernode/v2 => ../.. github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 + // cosmos/evm requires a forked go-ethereum with custom EVM operation methods + github.com/ethereum/go-ethereum => github.com/cosmos/go-ethereum v1.16.2-cosmos-1 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 nhooyr.io/websocket => github.com/coder/websocket v1.8.7 ) require ( github.com/BurntSushi/toml v1.6.0 - github.com/LumeraProtocol/lumera v1.11.0 + github.com/LumeraProtocol/lumera v1.11.2-0.20260420182021-e09830d70704 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.53.6 github.com/spf13/cobra v1.10.2 - google.golang.org/grpc v1.79.3 + google.golang.org/grpc v1.80.0 google.golang.org/protobuf v1.36.11 ) @@ -25,7 +28,7 @@ require ( cosmossdk.io/collections v1.4.0 // indirect cosmossdk.io/core v0.11.3 // indirect cosmossdk.io/depinject v1.2.1 // indirect - cosmossdk.io/errors v1.0.2 // indirect + cosmossdk.io/errors v1.1.0 // indirect cosmossdk.io/log v1.6.1 // indirect cosmossdk.io/math v1.5.3 // indirect cosmossdk.io/schema v1.1.0 // indirect @@ -33,7 +36,7 @@ require ( cosmossdk.io/x/feegrant v0.2.0 // indirect cosmossdk.io/x/tx v0.14.0 // indirect cosmossdk.io/x/upgrade v0.2.0 // indirect - filippo.io/edwards25519 v1.1.0 // indirect + filippo.io/edwards25519 v1.1.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/datadog-go v4.8.3+incompatible // indirect @@ -88,7 +91,7 @@ require ( github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect - github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/ethereum/go-ethereum v1.17.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -104,7 +107,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -201,8 +204,8 @@ require ( golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.2 // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/cmd/sncli/go.sum b/cmd/sncli/go.sum index b4c17bc2..61912a49 100644 --- a/cmd/sncli/go.sum +++ b/cmd/sncli/go.sum @@ -62,8 +62,8 @@ cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= cosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM= -cosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo= -cosmossdk.io/errors v1.0.2/go.mod h1:0rjgiHkftRYPj//3DrD6y8hcm40HcPv/dR4R/4efr0k= +cosmossdk.io/errors v1.1.0 h1:X2DSt9JYgH7cuiaDr318aUqIl2z5Lfo/PdGzAtmczUU= +cosmossdk.io/errors v1.1.0/go.mod h1:lnjBmx7etZpMTLnxdspZupH0d9HGRWZhiezDZX2ayyI= cosmossdk.io/log v1.6.1 h1:YXNwAgbDwMEKwDlCdH8vPcoggma48MgZrTQXCfmMBeI= cosmossdk.io/log v1.6.1/go.mod h1:gMwsWyyDBjpdG9u2avCFdysXqxq28WJapJvu+vF1y+E= cosmossdk.io/math v1.5.3 h1:WH6tu6Z3AUCeHbeOSHg2mt9rnoiUWVWaQ2t6Gkll96U= @@ -83,8 +83,9 @@ cosmossdk.io/x/tx v0.14.0/go.mod h1:Tn30rSRA1PRfdGB3Yz55W4Sn6EIutr9xtMKSHij+9PM= cosmossdk.io/x/upgrade v0.2.0 h1:ZHy0xny3wBCSLomyhE06+UmQHWO8cYlVYjfFAJxjz5g= cosmossdk.io/x/upgrade v0.2.0/go.mod h1:DXDtkvi//TrFyHWSOaeCZGBoiGAE6Rs8/0ABt2pcDD0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= @@ -95,17 +96,17 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CosmWasm/wasmd v0.61.6 h1:wa1rY/mZi8OYnf0f6a02N7o3vBockOfL3P37hSH0XtY= -github.com/CosmWasm/wasmd v0.61.6/go.mod h1:Wg2gfY2qrjjFY8UvpkTCRdy8t67qebOQn7UvRiGRzDw= -github.com/CosmWasm/wasmvm/v3 v3.0.2 h1:+MLkOX+IdklITLqfG26PCFv5OXdZvNb8z5Wq5JFXTRM= -github.com/CosmWasm/wasmvm/v3 v3.0.2/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= +github.com/CosmWasm/wasmd v0.61.10 h1:BB5dhCys4MSvRKUNvW1eFuhm61/251mFJ5Hefvm7MD0= +github.com/CosmWasm/wasmd v0.61.10/go.mod h1:GMPqtsb1T8FvaKpQGJmGuj/JMPXBauk4ZhUErgmtEus= +github.com/CosmWasm/wasmvm/v3 v3.0.3 h1:rg8cZ2qXFj3HwUOqni53OZV/oTvmA2mTVabKA7L0sro= +github.com/CosmWasm/wasmvm/v3 v3.0.3/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= @@ -273,6 +274,8 @@ github.com/cosmos/evm v0.6.0 h1:jwJerLS7btDgDpZOYy7lUC+1rNRCGGE80TJ6r4guufo= github.com/cosmos/evm v0.6.0/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= 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/go-ethereum v1.16.2-cosmos-1 h1:QIaIS6HIdPSBdTvpFhxswhMLUJgcr4irbd2o9ZKldAI= +github.com/cosmos/go-ethereum v1.16.2-cosmos-1/go.mod h1:X5CIOyo8SuK1Q5GnaEizQVLHT/DfsiGWuNeVdQcEMNA= 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= @@ -294,8 +297,6 @@ github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= -github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= -github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= @@ -357,8 +358,6 @@ github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9O github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= -github.com/ethereum/go-ethereum v1.15.11 h1:JK73WKeu0WC0O1eyX+mdQAVHUV+UR1a9VB/domDngBU= -github.com/ethereum/go-ethereum v1.15.11/go.mod h1:mf8YiHIb0GR4x4TipcvBUPxJLw1mFdmxzoDi11sDRoI= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -367,6 +366,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -390,8 +391,8 @@ github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -483,8 +484,8 @@ 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.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -730,6 +731,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -739,6 +742,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1042,16 +1047,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= 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= @@ -1416,8 +1421,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1492,10 +1497,10 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= 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= @@ -1522,8 +1527,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 31f797ece0882fbd397a3940a01d2feb6d602dcd Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Thu, 30 Apr 2026 15:23:50 -0400 Subject: [PATCH 07/22] evmigration: migrate to unified MigrationProof for new side Lumera unified legacy and new sides under a single MigrationProof oneof. Wrap newSig in a SingleKeyProof and pass it via NewProof on both MsgMigrateValidator and MsgMigrateAccount. Co-Authored-By: Claude Opus 4.7 (1M context) --- supernode/cmd/evmigration.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index a9c7de9e..af93b3b1 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -355,12 +355,16 @@ func ensureLegacyAccountMigrated( return fmt.Errorf("failed to sign migration payload with EVM key: %w", err) } - // Build the LegacyProof wrapper. The keeper replaced the flat - // LegacyPubKey/LegacySignature fields with a single oneof carrying - // either a SingleKeyProof or MultisigProof; supernode only ever signs - // with one secp256k1 key so we always use the Single case. - legacyProof := evmigrationtypes.LegacyProof{ - Proof: &evmigrationtypes.LegacyProof_Single{ + // Build the MigrationProof wrappers for both sides. Lumera's + // proof.proto unifies legacy and new sides under a single MigrationProof + // type with a oneof carrying either SingleKeyProof or MultisigProof. + // The supernode daemon holds exactly one signing key per side + // (legacy secp256k1, new eth_secp256k1), so it always populates the + // Single variant on both. Multisig legacy accounts are rejected + // upstream by multisigMigrationInstructions; the daemon never reaches + // this branch with a multisig-shaped key. + legacyProof := evmigrationtypes.MigrationProof{ + Proof: &evmigrationtypes.MigrationProof_Single{ Single: &evmigrationtypes.SingleKeyProof{ PubKey: legacyPubKey.Bytes(), Signature: legacySig, @@ -368,6 +372,15 @@ func ensureLegacyAccountMigrated( }, }, } + newProof := evmigrationtypes.MigrationProof{ + Proof: &evmigrationtypes.MigrationProof_Single{ + Single: &evmigrationtypes.SingleKeyProof{ + PubKey: newPubKey.Bytes(), + Signature: newSig, + SigFormat: evmigrationtypes.SigFormat_SIG_FORMAT_CLI, + }, + }, + } // Build the appropriate message type. var msg sdk.Msg @@ -376,7 +389,7 @@ func ensureLegacyAccountMigrated( NewAddress: newAddr.String(), LegacyAddress: legacyAddr.String(), LegacyProof: legacyProof, - NewSignature: newSig, + NewProof: newProof, } logtrace.Info(ctx, "Validator account detected — using MsgMigrateValidator", logtrace.Fields{ "legacy_address": legacyAddr.String(), @@ -387,7 +400,7 @@ func ensureLegacyAccountMigrated( NewAddress: newAddr.String(), LegacyAddress: legacyAddr.String(), LegacyProof: legacyProof, - NewSignature: newSig, + NewProof: newProof, } } From acca2b80ea97f72daa98845120cd8a551239e905 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 12 May 2026 12:02:12 -0400 Subject: [PATCH 08/22] sn-manager: align go.mod with EVM-enabled lumera Co-Authored-By: Claude Opus 4.7 (1M context) --- sn-manager/go.mod | 24 ++++++++++++------------ sn-manager/go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/sn-manager/go.mod b/sn-manager/go.mod index 48cf5436..01caf7ce 100644 --- a/sn-manager/go.mod +++ b/sn-manager/go.mod @@ -1,6 +1,6 @@ module github.com/LumeraProtocol/supernode/v2/sn-manager -go 1.26.1 +go 1.26.2 replace ( github.com/LumeraProtocol/lumera => ../../lumera @@ -12,25 +12,25 @@ replace ( require ( github.com/AlecAivazis/survey/v2 v2.3.7 - github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 + github.com/LumeraProtocol/supernode/v2 v2.4.72 github.com/spf13/cobra v1.10.2 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/mattn/go-isatty v0.0.22 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/spf13/pflag v1.0.10 // indirect - golang.org/x/net v0.51.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/text v0.34.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/grpc v1.79.3 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260427160629-7cedc36a6bc4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect + google.golang.org/grpc v1.80.0 // indirect ) diff --git a/sn-manager/go.sum b/sn-manager/go.sum index 22152bc6..78a482c1 100644 --- a/sn-manager/go.sum +++ b/sn-manager/go.sum @@ -21,8 +21,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 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/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -37,10 +37,11 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= +github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -76,8 +77,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -86,31 +87,30 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= 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.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260427160629-7cedc36a6bc4 h1:yOzSCGPx+cp5VO7IxvZ9SBFF7j1tZVcNtlHR2iYKtVo= +google.golang.org/genproto/googleapis/api v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:Q9HWtNeE7tM9npdIsEvqXj1QJIvVoeAV3rtXtS715Cw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From f49b98b42ba310f1436d0acf1c3cd52be8af369a Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 12 May 2026 13:22:03 -0400 Subject: [PATCH 09/22] evmigration: align with EVM-enabled lumera and document release - Bump cmd/sncli and tests/system to lumera v1.20.0-rc2; drop local ../lumera replace now that the EVM-enabled release exists upstream. - tests/system: bump devnet tx fee to 1000ulume and make initSDKConfig idempotent so multiple test invocations don't trip the SDK's "Config is sealed" panic. - CHANGELOG: add Upcoming EVM Release section summarising the evm-support work (migration flow, keyring, p2p reactions, deps). Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ cmd/sncli/go.mod | 2 +- tests/system/cli.go | 2 +- tests/system/go.mod | 5 +---- tests/system/go.sum | 16 +++++++--------- tests/system/main_test.go | 22 ++++++++++++++++++++++ 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f47dfb6..f36667f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,34 @@ # Changelog +## Upcoming EVM Release + +This release adds end-to-end support for Lumera's EVM-enabled chain (Cosmos EVM integration, `evmigration` module, ERC-20 policy, unified migration proofs): + +- **EVM account migration on startup.** SuperNode and SDK can now migrate a legacy `secp256k1` account to a new `eth_secp256k1` (EVM) account on the chain. The flow: + - Detects whether the configured legacy key still exists in the keyring and whether on-chain migration has already happened (`QueryMigrationRecord`). + - Submits `MsgClaimLegacyAccount` for plain accounts and `MsgMigrateValidator` when the account is a validator operator, using a unified `MigrationProof` (single-key or multisig) for both the legacy and new sides. + - Estimates fees via `QueryMigrationEstimate`, signs with both legacy and new keys (CLI sig format), and broadcasts the migration tx. + - On success, deletes the legacy key from the keyring and rewrites the operator's SuperNode config to use the new EVM address. + - **Refuses automatic migration** when the legacy account is a multisig — these must be migrated manually because they require an offline multi-party signing ceremony. See `docs/evm-migration.md` for the full operator playbook. +- **Keyring extensions** (`pkg/keyring`): + - Supports both `secp256k1` (legacy) and `eth_secp256k1` (EVM) key algorithms in the same keyring backend (Cosmos SDK + cosmos/evm codec registration). + - New helpers to look up keys by address, regardless of algorithm, and delete legacy keys after a successful migration. +- **Protobuf / codec wiring** for cosmos/evm and `evmigration` types so that messages round-trip correctly through the SuperNode and SDK transaction pipelines. +- **P2P bootstrap reacts to migrations.** After a successful EVM migration, the local DHT: + - Clears the `KeyExchanger` credential cache so subsequent handshakes use the post-migration identity for HKDF key derivation. + - Releases all pooled gRPC connections (they were authenticated with the old identity and would fail re-use). + - Signals the bootstrap refresher via `NotifyEVMMigration` to immediately re-sync peers from the chain and switch to an **accelerated 1-minute refresh interval for 5 cycles** so peer-address changes propagate quickly. Reverts to the normal 10-minute cadence afterwards. +- **SDK ICA / signing updates** (`sdk/task`): + - Cascade signing path now produces signatures compatible with EVM-style accounts (eth_secp256k1) in addition to the legacy ADR-36 path. + - `spendable_balance` checks correctly handle EVM-derived addresses. +- **Module dependencies bumped to EVM-enabled Lumera** (`v1.20.0-rc2`), which provides the `evmigration` module, `erc20policy`, Cosmos EVM integration, and forked `go-ethereum` (`cosmos/go-ethereum v1.16.2-cosmos-1`). Aligned across `supernode`, `sn-manager`, `cmd/sncli`, and `tests/system` go.mod files; Go toolchain bumped to **1.26.2**. +- **Integration tests** for the full EVM migration flow (`tests/integration/evmigration`): legacy → EVM migration of plain accounts, validators, and rejection of multisig accounts; verifies on-chain state, keyring state, and config rewrites. +- **Build & release** workflow updated to produce artifacts against the EVM-enabled toolchain. +- **Operator documentation:** `docs/evm-migration.md` describes the migration model, supported account types, the automatic startup flow, manual multisig procedure, and recovery scenarios. + +(Will be finalized on release.) + ## Upcoming Release: v2.4.9 This release focuses on stability, performance, and operational clarity across the cascade pipeline and SuperNode operation: diff --git a/cmd/sncli/go.mod b/cmd/sncli/go.mod index c3583d2b..107c2b13 100644 --- a/cmd/sncli/go.mod +++ b/cmd/sncli/go.mod @@ -15,7 +15,7 @@ replace ( require ( github.com/BurntSushi/toml v1.6.0 - github.com/LumeraProtocol/lumera v1.11.2-0.20260420182021-e09830d70704 + github.com/LumeraProtocol/lumera v1.20.0-rc2 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.53.6 github.com/spf13/cobra v1.10.2 diff --git a/tests/system/cli.go b/tests/system/cli.go index 633fe933..4f5d9928 100644 --- a/tests/system/cli.go +++ b/tests/system/cli.go @@ -39,7 +39,7 @@ func NewLumeradCLI(t *testing.T, sut *SystemUnderTest, verbose bool) *LumeradCli sut.AwaitNextBlock, sut.nodesCount, filepath.Join(WorkDir, sut.outputDir), - "1"+"ulume", + "1000ulume", verbose, assert.NoError, true, diff --git a/tests/system/go.mod b/tests/system/go.mod index 03e3264a..bf2a215d 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -53,12 +53,12 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect github.com/btcsuite/btcd/btcutil v1.1.6 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect github.com/cockroachdb/errors v1.12.0 // indirect github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a // indirect github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect @@ -207,9 +207,6 @@ require ( replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 - // Fix bytedance/sonic compatibility - github.com/bytedance/sonic => github.com/bytedance/sonic v1.12.3 - github.com/bytedance/sonic/loader => github.com/bytedance/sonic/loader v0.2.1 // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // See: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 diff --git a/tests/system/go.sum b/tests/system/go.sum index 837ee0e3..6dccae01 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -190,10 +190,12 @@ github.com/bufbuild/protoc-gen-validate v1.3.0 h1:0lq2b9qA1uzfVnMW6oFJepiVVihDOO github.com/bufbuild/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= -github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= -github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -215,8 +217,6 @@ github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -671,10 +671,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.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 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/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -960,6 +958,7 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F 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/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -1570,7 +1569,6 @@ lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/tests/system/main_test.go b/tests/system/main_test.go index 67c97efa..7d4e75d5 100644 --- a/tests/system/main_test.go +++ b/tests/system/main_test.go @@ -96,11 +96,33 @@ func requireEnoughFileHandlers(nodesCount int) { func initSDKConfig(bech32Prefix string) { config := sdk.GetConfig() + + if sdkConfigMatches(config, bech32Prefix) { + return + } + defer func() { + if r := recover(); r != nil { + if fmt.Sprint(r) == "Config is sealed" && sdkConfigMatches(config, bech32Prefix) { + return + } + panic(r) + } + }() + config.SetBech32PrefixForAccount(bech32Prefix, bech32Prefix+sdk.PrefixPublic) config.SetBech32PrefixForValidator(bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator, bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic) config.SetBech32PrefixForConsensusNode(bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus, bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic) } +func sdkConfigMatches(config *sdk.Config, bech32Prefix string) bool { + return config.GetBech32AccountAddrPrefix() == bech32Prefix && + config.GetBech32AccountPubPrefix() == bech32Prefix+sdk.PrefixPublic && + config.GetBech32ValidatorAddrPrefix() == bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator && + config.GetBech32ValidatorPubPrefix() == bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic && + config.GetBech32ConsensusAddrPrefix() == bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus && + config.GetBech32ConsensusPubPrefix() == bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic +} + const ( successFlag = ` ___ _ _ ___ ___ ___ ___ ___ From 651b9d8f384802e485a8d0450555cb5137c2a1e3 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Wed, 27 May 2026 17:56:13 -0400 Subject: [PATCH 10/22] Fix cascade e2e EVM identities --- tests/system/config.test-1.yml | 2 +- tests/system/config.test-2.yml | 2 +- tests/system/config.test-3.yml | 2 +- tests/system/e2e_cascade_test.go | 16 ++++++++-------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/system/config.test-1.yml b/tests/system/config.test-1.yml index 191c6b37..cd99dd27 100644 --- a/tests/system/config.test-1.yml +++ b/tests/system/config.test-1.yml @@ -3,7 +3,7 @@ # Supernode Configuration supernode: key_name: "testkey1" - identity: "lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4" + identity: "lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8" host: "0.0.0.0" port: 4444 gateway_port: 8002 diff --git a/tests/system/config.test-2.yml b/tests/system/config.test-2.yml index 5cc934e3..557373f8 100644 --- a/tests/system/config.test-2.yml +++ b/tests/system/config.test-2.yml @@ -4,7 +4,7 @@ # Supernode Configuration supernode: key_name: "testkey2" - identity: "lumera1cf0ms9ttgdvz6zwlqfty4tjcawhuaq69p40w0c" + identity: "lumera19x8cqj4nqmvmnzu75n3jalzhjc3mt643m738qn" host: "0.0.0.0" port: 4446 gateway_port: 8003 diff --git a/tests/system/config.test-3.yml b/tests/system/config.test-3.yml index 06beaf9b..a9c54bf2 100644 --- a/tests/system/config.test-3.yml +++ b/tests/system/config.test-3.yml @@ -4,7 +4,7 @@ # Supernode Configuration supernode: key_name: "testkey3" - identity: "lumera1cjyc4ruq739e2lakuhargejjkr0q5vg6x3d7kp" + identity: "lumera1kfkqz3w5rd9qfgzmvc6pzfle0wt8dqyeh7rmgu" host: "0.0.0.0" port: 4448 gateway_port: 8004 diff --git a/tests/system/e2e_cascade_test.go b/tests/system/e2e_cascade_test.go index bd92561c..7b265140 100644 --- a/tests/system/e2e_cascade_test.go +++ b/tests/system/e2e_cascade_test.go @@ -67,7 +67,7 @@ func TestCascadeE2E(t *testing.T) { defer os.Unsetenv("INTEGRATION_TEST") // Test account credentials - these values are consistent across test runs const testMnemonic = "odor kiss switch swarm spell make planet bundle skate ozone path planet exclude butter atom ahead angle royal shuffle door prevent merry alter robust" - const expectedAddress = "lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4" + const expectedAddress = "lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8" const testKeyName = "testkey1" const userKeyName = "user" const userMnemonic = "little tone alley oval festival gloom sting asthma crime select swap auto when trip luxury pact risk sister pencil about crisp upon opera timber" @@ -127,15 +127,15 @@ func TestCascadeE2E(t *testing.T) { } // Register three supernodes with different ports - registerSupernode("node0", "4444", "lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4", "4445") - registerSupernode("node1", "4446", "lumera1cf0ms9ttgdvz6zwlqfty4tjcawhuaq69p40w0c", "4447") - registerSupernode("node2", "4448", "lumera1cjyc4ruq739e2lakuhargejjkr0q5vg6x3d7kp", "4449") + registerSupernode("node0", "4444", "lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8", "4445") + registerSupernode("node1", "4446", "lumera19x8cqj4nqmvmnzu75n3jalzhjc3mt643m738qn", "4447") + registerSupernode("node2", "4448", "lumera1kfkqz3w5rd9qfgzmvc6pzfle0wt8dqyeh7rmgu", "4449") t.Log("Successfully registered three supernodes") // Fund Lume - cli.FundAddress("lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4", "100000ulume") - cli.FundAddressWithNode("lumera1cf0ms9ttgdvz6zwlqfty4tjcawhuaq69p40w0c", "100000ulume", "node1") - cli.FundAddressWithNode("lumera1cjyc4ruq739e2lakuhargejjkr0q5vg6x3d7kp", "100000ulume", "node2") + cli.FundAddress("lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8", "100000ulume") + cli.FundAddressWithNode("lumera19x8cqj4nqmvmnzu75n3jalzhjc3mt643m738qn", "100000ulume", "node1") + cli.FundAddressWithNode("lumera1kfkqz3w5rd9qfgzmvc6pzfle0wt8dqyeh7rmgu", "100000ulume", "node2") queryHeight := sut.AwaitNextBlock(t) args := []string{ @@ -704,7 +704,7 @@ waitLoop: t.Logf("File verification successful: downloaded file content matches original file") - status, err := actionClient.GetSupernodeStatus(ctx, "lumera1cjyc4ruq739e2lakuhargejjkr0q5vg6x3d7kp") + status, err := actionClient.GetSupernodeStatus(ctx, "lumera1kfkqz3w5rd9qfgzmvc6pzfle0wt8dqyeh7rmgu") t.Logf("Supernode status: %+v", status) require.NoError(t, err, "Failed to get supernode status") From be0c9107f55ab50c6661a5822685308ce2c73c77 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Wed, 27 May 2026 18:01:54 -0400 Subject: [PATCH 11/22] Normalize EVM keyring signatures --- pkg/keyring/keyring.go | 6 ++++++ pkg/keyring/keyring_test.go | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/keyring/keyring.go b/pkg/keyring/keyring.go index 3795be03..d1ec67a0 100644 --- a/pkg/keyring/keyring.go +++ b/pkg/keyring/keyring.go @@ -228,6 +228,12 @@ func SignBytes(kr sdkkeyring.Keyring, name string, bz []byte) ([]byte, error) { return nil, err } sig, _, err := kr.SignByAddress(addr, bz, signing.SignMode_SIGN_MODE_DIRECT) + if err != nil { + return nil, err + } + if len(sig) == 65 { + sig = sig[:64] + } return sig, err } diff --git a/pkg/keyring/keyring_test.go b/pkg/keyring/keyring_test.go index dad4b00e..57fd429f 100644 --- a/pkg/keyring/keyring_test.go +++ b/pkg/keyring/keyring_test.go @@ -182,13 +182,18 @@ func TestLegacyAndEVMKeys_ProduceDifferentAddresses(t *testing.T) { func TestSignBytes_WithEVMKey(t *testing.T) { kr := newEVMKeyring(t) - _, _, err := CreateNewAccount(kr, "signer") + _, rec, err := CreateNewAccount(kr, "signer") require.NoError(t, err) msg := []byte("hello world") sig, err := SignBytes(kr, "signer", msg) require.NoError(t, err) assert.NotEmpty(t, sig, "signature should not be empty") + assert.Len(t, sig, 64, "EVM signatures should be normalized to r||s") + + pubKey, err := rec.GetPubKey() + require.NoError(t, err) + require.True(t, pubKey.VerifySignature(msg, sig), "signature should verify with the signer pubkey") } func TestGetAddress_WithEVMKey(t *testing.T) { From 34b57c549f271422211fd2debea522abd9684f8d Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Mon, 8 Jun 2026 14:24:16 -0400 Subject: [PATCH 12/22] Address PR #299 review feedback - go.mod: drop local `=> ../../../lumera` replace in cmd/sncli and sn-manager so a clean checkout builds against the tagged lumera v1.20.0-rc2 instead of failing on a missing directory. - evmigration: isEthSecp256k1Key now type-asserts *ethsecp256k1.PubKey instead of treating any non-legacy key as EVM, so ed25519/multisig/ offline keys are rejected at the pre-flight gate. Add negative test. - evmigration_test: compare legacy vs EVM addresses in the same bech32 encoding (was bech32 vs hex, which could never collide). - sdk/task: report actual and required spendable balance from `min` and denom instead of hard-coding ">= 1 LUME". - docs/evm-migration: fix "superno0de" typo and the `keys recover` example (positional [name], not --name). - gofmt reachability_active_probing_test.go. Co-Authored-By: Claude Opus 4.8 (1M context) --- cmd/sncli/go.mod | 2 -- cmd/sncli/go.sum | 2 ++ docs/evm-migration.md | 4 +-- sdk/task/task.go | 4 +-- sn-manager/go.mod | 1 - supernode/cmd/evmigration.go | 20 +++++++++---- supernode/cmd/evmigration_test.go | 30 ++++++++++++++++++- .../reachability_active_probing_test.go | 2 +- 8 files changed, 51 insertions(+), 14 deletions(-) diff --git a/cmd/sncli/go.mod b/cmd/sncli/go.mod index 107c2b13..4edf1b2a 100644 --- a/cmd/sncli/go.mod +++ b/cmd/sncli/go.mod @@ -3,8 +3,6 @@ module github.com/LumeraProtocol/supernode/v2/cmd/sncli go 1.26.2 replace ( - // Use local Lumera with EVM support (evmigration, erc20policy, etc.) - github.com/LumeraProtocol/lumera => ../../../lumera github.com/LumeraProtocol/supernode/v2 => ../.. github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 // cosmos/evm requires a forked go-ethereum with custom EVM operation methods diff --git a/cmd/sncli/go.sum b/cmd/sncli/go.sum index 61912a49..7b8b1acf 100644 --- a/cmd/sncli/go.sum +++ b/cmd/sncli/go.sum @@ -112,6 +112,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/LumeraProtocol/lumera v1.20.0-rc2 h1:T7lQVigQfb+ywH925qqBILiR3awWTXGAOXWbYZppF4E= +github.com/LumeraProtocol/lumera v1.20.0-rc2/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/docs/evm-migration.md b/docs/evm-migration.md index 57407dbc..3cff7459 100644 --- a/docs/evm-migration.md +++ b/docs/evm-migration.md @@ -15,7 +15,7 @@ address derived from the same mnemonic under the EVM HD path. The migration is: -- **One-time**: runs automatically at superno0de startup when a legacy key is detected +- **One-time**: runs automatically at supernode startup when a legacy key is detected - **Rerunnable**: safe to retry if interrupted at any point - **Self-authenticating**: uses dual signatures (legacy + new key) embedded in the message, so no Cosmos-level tx signing is needed @@ -33,7 +33,7 @@ The migration is: 1. **Derive your new EVM key** from the same mnemonic: ```bash - supernode keys recover --name evm-key --mnemonic "your twelve or twenty four words ..." + supernode keys recover evm-key --mnemonic "your twelve or twenty four words ..." ``` This creates an `eth_secp256k1` key under the name `evm-key` using HD path diff --git a/sdk/task/task.go b/sdk/task/task.go index b5d61aef..d270ed69 100644 --- a/sdk/task/task.go +++ b/sdk/task/task.go @@ -114,8 +114,8 @@ func hasMinimumSpendableBalance(ctx context.Context, client lumera.Client, addre return false, "spendable balance info unavailable" } if bal.Balance.Amount.LT(min) { - actualLUME := bal.Balance.Amount.Quo(sdkmath.NewInt(1_000_000)) - return false, fmt.Sprintf("insufficient spendable balance: %s LUME (need >= 1 LUME)", actualLUME.String()) + return false, fmt.Sprintf("insufficient spendable balance: have %s%s, need >= %s%s", + bal.Balance.Amount.String(), denom, min.String(), denom) } return true, "" } diff --git a/sn-manager/go.mod b/sn-manager/go.mod index 01caf7ce..33d40446 100644 --- a/sn-manager/go.mod +++ b/sn-manager/go.mod @@ -3,7 +3,6 @@ module github.com/LumeraProtocol/supernode/v2/sn-manager go 1.26.2 replace ( - github.com/LumeraProtocol/lumera => ../../lumera github.com/LumeraProtocol/supernode/v2 => ../ github.com/envoyproxy/protoc-gen-validate => github.com/bufbuild/protoc-gen-validate v1.3.0 github.com/lyft/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v1.3.0 diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index af93b3b1..5defce54 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -20,6 +20,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdktx "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + ethsecp256k1 "github.com/cosmos/evm/crypto/ethsecp256k1" "google.golang.org/grpc" ) @@ -149,14 +150,23 @@ func isLegacyKey(kr cKeyring.Keyring, keyName string) (bool, error) { return isSecp, nil } -// isEthSecp256k1Key returns true if the key stored in the keyring under keyName -// uses the EVM-compatible eth_secp256k1 algorithm. +// isEthSecp256k1Key returns true only if the key stored in the keyring under +// keyName uses the EVM-compatible eth_secp256k1 algorithm. It explicitly +// type-asserts the public key rather than treating "anything that is not legacy +// secp256k1" as EVM, so multisig/offline/ledger or any other non-EVM key type is +// rejected at this pre-flight gate instead of failing later during signing or +// proof validation. func isEthSecp256k1Key(kr cKeyring.Keyring, keyName string) (bool, error) { - legacy, err := isLegacyKey(kr, keyName) + rec, err := kr.Key(keyName) if err != nil { - return false, err + return false, fmt.Errorf("key %q not found in keyring: %w", keyName, err) + } + pubKey, err := rec.GetPubKey() + if err != nil { + return false, fmt.Errorf("failed to get public key for %q: %w", keyName, err) } - return !legacy, nil + _, isEth := pubKey.(*ethsecp256k1.PubKey) + return isEth, nil } // migrationChainClient abstracts chain interactions needed by the migration diff --git a/supernode/cmd/evmigration_test.go b/supernode/cmd/evmigration_test.go index a7fe79df..564718dd 100644 --- a/supernode/cmd/evmigration_test.go +++ b/supernode/cmd/evmigration_test.go @@ -17,6 +17,7 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" sdktx "github.com/cosmos/cosmos-sdk/types/tx" @@ -108,6 +109,28 @@ func TestIsEthSecp256k1Key_WithLegacyKey(t *testing.T) { assert.False(t, isEVM) } +// TestIsEthSecp256k1Key_WithNonEVMNonLegacyKey guards the pre-flight gate +// against keys that are neither legacy secp256k1 nor eth_secp256k1 (e.g. +// ed25519/offline/multisig). The previous implementation returned !isLegacyKey, +// which incorrectly classified any non-legacy key as EVM and let it pass setup +// validation only to fail later during signing/proof validation. +func TestIsEthSecp256k1Key_WithNonEVMNonLegacyKey(t *testing.T) { + kr := newTestKeyring(t) + // An offline ed25519 key: not legacy secp256k1, not eth_secp256k1. + priv := ed25519.GenPrivKey() + _, err := kr.SaveOfflineKey("ed25519-key", priv.PubKey()) + require.NoError(t, err) + + isEVM, err := isEthSecp256k1Key(kr, "ed25519-key") + require.NoError(t, err) + assert.False(t, isEVM, "ed25519 key must not be classified as eth_secp256k1") + + // It must also not be mistaken for a legacy secp256k1 key. + legacy, err := isLegacyKey(kr, "ed25519-key") + require.NoError(t, err) + assert.False(t, legacy, "ed25519 key must not be classified as legacy secp256k1") +} + func TestValidateLegacyMigrationSetup_NoMigrationNeeded(t *testing.T) { kr := newTestKeyring(t) addEVMKey(t, kr, "mykey") @@ -292,7 +315,12 @@ func TestEnsureLegacyAccountMigrated_AddressCollision(t *testing.T) { evmPubKey, err := evmRec.GetPubKey() require.NoError(t, err) - assert.NotEqual(t, legacyAddr.String(), fmt.Sprintf("%x", evmPubKey.Address()), + // Compare both addresses in the same (bech32) encoding so the assertion can + // actually catch a regression where the two coin types collide. A previous + // version compared a bech32 string against a hex byte dump, which could + // never be equal and so always passed. + evmAddr := sdk.AccAddress(evmPubKey.Address()).String() + assert.NotEqual(t, legacyAddr.String(), evmAddr, "keys with different coin types should produce different addresses") } diff --git a/supernode/supernode_metrics/reachability_active_probing_test.go b/supernode/supernode_metrics/reachability_active_probing_test.go index a035c98a..1b4b404b 100644 --- a/supernode/supernode_metrics/reachability_active_probing_test.go +++ b/supernode/supernode_metrics/reachability_active_probing_test.go @@ -428,7 +428,7 @@ func (c *fakeLumeraClient) SuperNodeMsg() supernode_msg.Module { return nil } func (c *fakeLumeraClient) Bank() bank.Module { return nil } func (c *fakeLumeraClient) Tx() tx.Module { return nil } func (c *fakeLumeraClient) Node() node.Module { return c.nodeModule } -func (c *fakeLumeraClient) Conn() *grpc.ClientConn { return nil } +func (c *fakeLumeraClient) Conn() *grpc.ClientConn { return nil } func (c *fakeLumeraClient) Close() error { return nil } type fakeNodeModule struct { From fdb974647d7adcbfa583c284898fb05117b9aaf0 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Mon, 8 Jun 2026 14:47:01 -0400 Subject: [PATCH 13/22] Fix test fakes for EVM-extended interfaces after merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The merge brought master's test fakes together with the EVM branch's extended interfaces, leaving the fakes incomplete: - lumera.Client gained Conn() *grpc.ClientConn — add it to fakeLumera (self_healing) and handlerLumera (transport/grpc/self_healing), delegating to the underlying testutil mock. Fixes the unit-tests build failure in both packages. - p2p.P2P gained NotifyEVMMigration() — add a no-op to the lep6StoreBackedP2P fake. Fixes the tests/systemtests build failure that broke both the cascade-e2e and lep6-e2e jobs. Co-Authored-By: Claude Opus 4.8 (1M context) --- supernode/self_healing/lumera_test.go | 2 ++ supernode/transport/grpc/self_healing/handler_test.go | 4 ++++ tests/system/e2e_lep6_negative_matrix_test.go | 1 + 3 files changed, 7 insertions(+) diff --git a/supernode/self_healing/lumera_test.go b/supernode/self_healing/lumera_test.go index 47c8284c..a4d72398 100644 --- a/supernode/self_healing/lumera_test.go +++ b/supernode/self_healing/lumera_test.go @@ -13,6 +13,7 @@ import ( "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode_msg" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/tx" "github.com/LumeraProtocol/supernode/v2/pkg/testutil" + "google.golang.org/grpc" ) // fakeLumera satisfies lumera.Client by composing per-test programmable @@ -43,4 +44,5 @@ func (f *fakeLumera) SuperNodeMsg() supernode_msg.Module { return f.other.SuperN func (f *fakeLumera) Bank() bankmod.Module { return f.other.Bank() } func (f *fakeLumera) Tx() tx.Module { return f.other.Tx() } func (f *fakeLumera) Node() node.Module { return f.other.Node() } +func (f *fakeLumera) Conn() *grpc.ClientConn { return f.other.Conn() } func (f *fakeLumera) Close() error { return nil } diff --git a/supernode/transport/grpc/self_healing/handler_test.go b/supernode/transport/grpc/self_healing/handler_test.go index f6feedbb..f8c33999 100644 --- a/supernode/transport/grpc/self_healing/handler_test.go +++ b/supernode/transport/grpc/self_healing/handler_test.go @@ -220,6 +220,10 @@ func (h *handlerLumera) Node() node.Module { h.ensureStubs() return h.stubsRef.Node() } +func (h *handlerLumera) Conn() *grpc.ClientConn { + h.ensureStubs() + return h.stubsRef.Conn() +} func (h *handlerLumera) Close() error { return nil } func (h *handlerLumera) ensureStubs() { diff --git a/tests/system/e2e_lep6_negative_matrix_test.go b/tests/system/e2e_lep6_negative_matrix_test.go index e35e4115..63ac0ff7 100644 --- a/tests/system/e2e_lep6_negative_matrix_test.go +++ b/tests/system/e2e_lep6_negative_matrix_test.go @@ -409,4 +409,5 @@ func (p *lep6StoreBackedP2P) EnableKey(context.Context, string) error { return func (p *lep6StoreBackedP2P) GetLocalKeys(context.Context, *time.Time, time.Time) ([]string, error) { return nil, fmt.Errorf("not implemented in LEP-6 matrix test fake") } +func (p *lep6StoreBackedP2P) NotifyEVMMigration() {} func (p *lep6StoreBackedP2P) Run(context.Context) error { return nil } From 573fb9776d893aa609fb109b982e4e98b5c5d447 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Mon, 8 Jun 2026 15:21:21 -0400 Subject: [PATCH 14/22] Fix LEP-6 e2e EVM identities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The merged-in LEP-6 e2e configs and tests still used legacy secp256k1 (coin type 118) supernode addresses. With the EVM-enabled binary, testkey1/2/3 derive eth_secp256k1 (coin type 60) addresses, so the supernodes failed config verification at startup ("Key resolves to X but config identity is Y") and never came up — cascading into the concurrency/enforcement/restart/matrix test failures. Update config.lep6-{1,2,3}.yml identities and the hardcoded address constants/assertions in the runtime and negative-matrix tests to the EVM-derived addresses, matching the mapping already applied for the cascade e2e in 651b9d8 (which now passes). Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/system/config.lep6-1.yml | 2 +- tests/system/config.lep6-2.yml | 2 +- tests/system/config.lep6-3.yml | 2 +- tests/system/e2e_lep6_negative_matrix_test.go | 2 +- tests/system/e2e_lep6_runtime_test.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/system/config.lep6-1.yml b/tests/system/config.lep6-1.yml index d5c36a7c..16461d25 100644 --- a/tests/system/config.lep6-1.yml +++ b/tests/system/config.lep6-1.yml @@ -3,7 +3,7 @@ # Supernode Configuration supernode: key_name: "testkey1" - identity: "lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4" + identity: "lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8" host: "0.0.0.0" port: 4444 gateway_port: 8002 diff --git a/tests/system/config.lep6-2.yml b/tests/system/config.lep6-2.yml index b5cbba69..c0c7a1c3 100644 --- a/tests/system/config.lep6-2.yml +++ b/tests/system/config.lep6-2.yml @@ -4,7 +4,7 @@ # Supernode Configuration supernode: key_name: "testkey2" - identity: "lumera1cf0ms9ttgdvz6zwlqfty4tjcawhuaq69p40w0c" + identity: "lumera19x8cqj4nqmvmnzu75n3jalzhjc3mt643m738qn" host: "0.0.0.0" port: 4446 gateway_port: 8003 diff --git a/tests/system/config.lep6-3.yml b/tests/system/config.lep6-3.yml index b6c58ea9..a66011bb 100644 --- a/tests/system/config.lep6-3.yml +++ b/tests/system/config.lep6-3.yml @@ -4,7 +4,7 @@ # Supernode Configuration supernode: key_name: "testkey3" - identity: "lumera1cjyc4ruq739e2lakuhargejjkr0q5vg6x3d7kp" + identity: "lumera1kfkqz3w5rd9qfgzmvc6pzfle0wt8dqyeh7rmgu" host: "0.0.0.0" port: 4448 gateway_port: 8004 diff --git a/tests/system/e2e_lep6_negative_matrix_test.go b/tests/system/e2e_lep6_negative_matrix_test.go index 63ac0ff7..b4f56531 100644 --- a/tests/system/e2e_lep6_negative_matrix_test.go +++ b/tests/system/e2e_lep6_negative_matrix_test.go @@ -96,7 +96,7 @@ func setupLEP6RuntimeCascadeFixture(t *testing.T) lep6RuntimeCascadeFixture { testMnemonic = "odor kiss switch swarm spell make planet bundle skate ozone path planet exclude butter atom ahead angle royal shuffle door prevent merry alter robust" testKey2Mnemonic = "club party current length duck agent love into slide extend spawn sentence kangaroo chunk festival order plate rare public good include situate liar miss" testKey3Mnemonic = "young envelope urban crucial denial zone toward mansion protect bonus exotic puppy resource pistol expand tell cupboard radio hurry world radio trust explain million" - expectedAddress = "lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4" + expectedAddress = "lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8" userKeyName = "user" userMnemonic = "little tone alley oval festival gloom sting asthma crime select swap auto when trip luxury pact risk sister pencil about crisp upon opera timber" fundAmount = "1000000ulume" diff --git a/tests/system/e2e_lep6_runtime_test.go b/tests/system/e2e_lep6_runtime_test.go index 3657f43d..0833048d 100644 --- a/tests/system/e2e_lep6_runtime_test.go +++ b/tests/system/e2e_lep6_runtime_test.go @@ -60,7 +60,7 @@ func TestLEP6RuntimeE2E_CascadeChallengeHealVerifyAndStore(t *testing.T) { testMnemonic = "odor kiss switch swarm spell make planet bundle skate ozone path planet exclude butter atom ahead angle royal shuffle door prevent merry alter robust" testKey2Mnemonic = "club party current length duck agent love into slide extend spawn sentence kangaroo chunk festival order plate rare public good include situate liar miss" testKey3Mnemonic = "young envelope urban crucial denial zone toward mansion protect bonus exotic puppy resource pistol expand tell cupboard radio hurry world radio trust explain million" - expectedAddress = "lumera1em87kgrvgttrkvuamtetyaagjrhnu3vjy44at4" + expectedAddress = "lumera1jcus5g9v6r080rg7dljvvpr4cm8k7psqwg7tj8" userKeyName = "user" userMnemonic = "little tone alley oval festival gloom sting asthma crime select swap auto when trip luxury pact risk sister pencil about crisp upon opera timber" fundAmount = "1000000ulume" From 5fe24834756ade6ad156dfa5f68c58535ee8ed72 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Mon, 8 Jun 2026 15:46:25 -0400 Subject: [PATCH 15/22] Fix LEP-6 e2e upload-user key derivation (coin type 60) generateLEP6UploadUsers created and funded user accounts with legacy secp256k1 (sdkhd.Secp256k1) while newLEP6ActionClientsForKey signs via keyring.RecoverAccountFromMnemonic, which uses eth_secp256k1 (coin type 60). The funded address and the signing address therefore differed, so RequestAction failed with "account ... not found" in the concurrency and restart e2e tests. Derive upload users with evmhd.EthSecp256k1 so the funded address matches the address the action client signs with. Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/system/e2e_lep6_concurrency_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/system/e2e_lep6_concurrency_test.go b/tests/system/e2e_lep6_concurrency_test.go index ae7245a9..5cbb8c23 100644 --- a/tests/system/e2e_lep6_concurrency_test.go +++ b/tests/system/e2e_lep6_concurrency_test.go @@ -15,8 +15,8 @@ import ( "time" actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types" - sdkhd "github.com/cosmos/cosmos-sdk/crypto/hd" sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" + evmhd "github.com/cosmos/evm/crypto/hd" "github.com/LumeraProtocol/supernode/v2/pkg/keyring" "github.com/LumeraProtocol/supernode/v2/pkg/lumera" @@ -197,7 +197,12 @@ func generateLEP6UploadUsers(t *testing.T, count int) []lep6UploadUser { users := make([]lep6UploadUser, 0, count) for i := 0; i < count; i++ { keyName := fmt.Sprintf("phase3-upload-user-%d", i+1) - record, mnemonic, err := kr.NewMnemonic(keyName, sdkkeyring.English, keyring.DefaultHDPath, keyring.DefaultBIP39Passphrase, sdkhd.Secp256k1) + // Derive with eth_secp256k1 (coin type 60) so the funded userAddress + // matches the address newLEP6ActionClientsForKey signs with via + // keyring.RecoverAccountFromMnemonic (also eth_secp256k1). Using legacy + // secp256k1 here funded a different address, so RequestAction failed with + // "account not found". + record, mnemonic, err := kr.NewMnemonic(keyName, sdkkeyring.English, keyring.DefaultHDPath, keyring.DefaultBIP39Passphrase, evmhd.EthSecp256k1) require.NoError(t, err) addr, err := record.GetAddress() require.NoError(t, err) From 99c076a52c1aec4e6b0b2368eb7386334a468ae4 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Mon, 8 Jun 2026 16:03:36 -0400 Subject: [PATCH 16/22] Fix EVM migration retry cleanup --- p2p/evm_migration_test.go | 13 ++++++++ p2p/p2p.go | 31 +++++++++++-------- supernode/cmd/evmigration.go | 16 ++++++++-- supernode/cmd/evmigration_test.go | 49 +++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 p2p/evm_migration_test.go diff --git a/p2p/evm_migration_test.go b/p2p/evm_migration_test.go new file mode 100644 index 00000000..dbdf18b9 --- /dev/null +++ b/p2p/evm_migration_test.go @@ -0,0 +1,13 @@ +package p2p + +import "testing" + +func TestNotifyEVMMigrationBeforeDHTIsConfiguredMarksPending(t *testing.T) { + svc := &p2p{} + + svc.NotifyEVMMigration() + + if !svc.migrationPending.Load() { + t.Fatal("expected migration notification to remain pending until DHT is configured") + } +} diff --git a/p2p/p2p.go b/p2p/p2p.go index b77a45e7..1eecc85a 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "sync" + "sync/atomic" "time" "github.com/LumeraProtocol/supernode/v2/p2p/kademlia" @@ -47,16 +48,17 @@ type P2P interface { // p2p structure to implements interface type p2p struct { - store kademlia.Store // the store for kademlia network - metaStore kademlia.MetaStore - dht *kademlia.DHT // the kademlia network - config *Config // the service configuration - running bool // if the kademlia network is ready - lumeraClient lumera.Client - keyring keyring.Keyring // Add the keyring field - rqstore rqstore.Store - stats *p2pStatsManager - statsOnce sync.Once + store kademlia.Store // the store for kademlia network + metaStore kademlia.MetaStore + dht *kademlia.DHT // the kademlia network + config *Config // the service configuration + running bool // if the kademlia network is ready + lumeraClient lumera.Client + keyring keyring.Keyring // Add the keyring field + rqstore rqstore.Store + stats *p2pStatsManager + statsOnce sync.Once + migrationPending atomic.Bool } // Run the kademlia network @@ -102,6 +104,9 @@ func (s *p2p) run(ctx context.Context) error { logtrace.Error(ctx, "failed to configure bootstrap nodes", logtrace.Fields{logtrace.FieldModule: "p2p", logtrace.FieldError: err}) logtrace.Error(ctx, "failed to get bootstap ip", logtrace.Fields{logtrace.FieldModule: "p2p", logtrace.FieldError: err}) } + if s.migrationPending.Swap(false) { + s.dht.NotifyEVMMigration() + } s.running = true logtrace.Debug(ctx, "p2p service is started", logtrace.Fields{}) @@ -240,9 +245,11 @@ func (s *p2p) NClosestNodesWithIncludingNodeList(ctx context.Context, n int, key // NotifyEVMMigration forwards the migration signal to the underlying DHT. func (s *p2p) NotifyEVMMigration() { - if s.dht != nil { - s.dht.NotifyEVMMigration() + if s.dht == nil { + s.migrationPending.Store(true) + return } + s.dht.NotifyEVMMigration() } // configure the distributed hash table for p2p service diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index 5defce54..1cf85d38 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -224,6 +224,7 @@ func ensureLegacyAccountMigrated( ) error { keyName := cfg.SupernodeConfig.KeyName evmKeyName := cfg.SupernodeConfig.EVMKeyName + originalIdentity := cfg.SupernodeConfig.Identity legacy, err := validateLegacyMigrationSetup(kr, keyName, evmKeyName) if err != nil { @@ -472,9 +473,20 @@ func ensureLegacyAccountMigrated( // If config persistence fails, keeping the legacy key allows the next startup // to resume from the on-chain migration record and complete local cleanup. if err := kr.Delete(keyName); err != nil { + cfg.SupernodeConfig.KeyName = keyName + cfg.SupernodeConfig.Identity = originalIdentity + cfg.SupernodeConfig.EVMKeyName = evmKeyName + if restoreErr := snConfig.SaveConfig(cfg, cfgFile); restoreErr != nil { + return fmt.Errorf( + "migration complete and config updated, but failed to delete legacy key %q: %w\n"+ + "Also failed to restore the pre-migration config for retry: %v\n"+ + "Please manually remove the old key or restore config.yml with key_name=%s, identity=%s, evm_key_name=%s.", + keyName, err, restoreErr, keyName, originalIdentity, evmKeyName, + ) + } return fmt.Errorf( - "migration complete and config updated, but failed to delete legacy key %q: %w\n"+ - "Please manually remove the old key.\n"+ + "migration complete, but failed to delete legacy key %q: %w\n"+ + "Restored the pre-migration config so the next startup can retry local cleanup from the on-chain migration record.\n"+ "Safe to retry — just restart the supernode.", keyName, err, ) diff --git a/supernode/cmd/evmigration_test.go b/supernode/cmd/evmigration_test.go index 564718dd..6e2c8c02 100644 --- a/supernode/cmd/evmigration_test.go +++ b/supernode/cmd/evmigration_test.go @@ -221,6 +221,15 @@ type fakeMigrationClient struct { broadcastedMsg sdk.Msg // captures the message passed to BroadcastMigrationTx } +type failingDeleteKeyring struct { + sdkkeyring.Keyring + err error +} + +func (f failingDeleteKeyring) Delete(_ string) error { + return f.err +} + func (f *fakeMigrationClient) MigrationRecord(_ context.Context, _ string) (*evmigrationtypes.QueryMigrationRecordResponse, error) { return f.recordResp, f.recordErr } @@ -639,6 +648,46 @@ func TestEnsureLegacyAccountMigrated_ConfigSaveFailsBeforeKeyDelete(t *testing.T assert.NoError(t, err, "legacy key should remain when config save fails") } +func TestEnsureLegacyAccountMigrated_DeleteFailureRestoresRetryableConfig(t *testing.T) { + baseKR := newTestKeyring(t) + addLegacyKey(t, baseKR, "mykey") + addEVMKey(t, baseKR, "evm-key") + + cfg := newMigrationCfg(t, "mykey", "evm-key") + cfg.SupernodeConfig.Identity = "lumera1original" + + mc := &fakeMigrationClient{ + recordResp: &evmigrationtypes.QueryMigrationRecordResponse{}, + estimateResp: &evmigrationtypes.QueryMigrationEstimateResponse{ + WouldSucceed: true, + }, + } + + kr := failingDeleteKeyring{ + Keyring: baseKR, + err: fmt.Errorf("delete denied"), + } + + err := ensureLegacyAccountMigrated(context.Background(), kr, cfg, mc, &fakeSuperNodeModule{}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to delete legacy key") + assert.Contains(t, err.Error(), "retry") + + assert.Equal(t, "mykey", cfg.SupernodeConfig.KeyName) + assert.Equal(t, "lumera1original", cfg.SupernodeConfig.Identity) + assert.Equal(t, "evm-key", cfg.SupernodeConfig.EVMKeyName) + + cfgFile := filepath.Join(cfg.BaseDir, DefaultConfigFile) + loaded, loadErr := snConfig.LoadConfig(cfgFile, cfg.BaseDir) + require.NoError(t, loadErr) + assert.Equal(t, "mykey", loaded.SupernodeConfig.KeyName) + assert.Equal(t, "lumera1original", loaded.SupernodeConfig.Identity) + assert.Equal(t, "evm-key", loaded.SupernodeConfig.EVMKeyName) + + _, err = baseKR.Key("mykey") + assert.NoError(t, err, "legacy key should remain so the next startup can retry cleanup") +} + // --- full happy-path end-to-end test --- func TestEnsureLegacyAccountMigrated_FullHappyPath(t *testing.T) { From 1ca8b291f8a023a0eb12811cd0ef31652ffffd8d Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 9 Jun 2026 16:29:02 -0400 Subject: [PATCH 17/22] Bump lumera dependency to v1.20.0-rc3 (LEP-6) Update lumera to v1.20.0-rc3, the new release with LEP-6, across go.mod/go.sum for the root, cmd/sncli, and tests/system modules. Ran go mod tidy in each. Updated CHANGELOG reference. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 2 +- cmd/sncli/go.mod | 2 +- cmd/sncli/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- tests/system/go.mod | 4 ++-- tests/system/go.sum | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f36667f5..fea91247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ This release adds end-to-end support for Lumera's EVM-enabled chain (Cosmos EVM - **SDK ICA / signing updates** (`sdk/task`): - Cascade signing path now produces signatures compatible with EVM-style accounts (eth_secp256k1) in addition to the legacy ADR-36 path. - `spendable_balance` checks correctly handle EVM-derived addresses. -- **Module dependencies bumped to EVM-enabled Lumera** (`v1.20.0-rc2`), which provides the `evmigration` module, `erc20policy`, Cosmos EVM integration, and forked `go-ethereum` (`cosmos/go-ethereum v1.16.2-cosmos-1`). Aligned across `supernode`, `sn-manager`, `cmd/sncli`, and `tests/system` go.mod files; Go toolchain bumped to **1.26.2**. +- **Module dependencies bumped to EVM-enabled Lumera** (`v1.20.0-rc3`), which provides the `evmigration` module, `erc20policy`, Cosmos EVM integration, and forked `go-ethereum` (`cosmos/go-ethereum v1.16.2-cosmos-1`). Aligned across `supernode`, `sn-manager`, `cmd/sncli`, and `tests/system` go.mod files; Go toolchain bumped to **1.26.2**. - **Integration tests** for the full EVM migration flow (`tests/integration/evmigration`): legacy → EVM migration of plain accounts, validators, and rejection of multisig accounts; verifies on-chain state, keyring state, and config rewrites. - **Build & release** workflow updated to produce artifacts against the EVM-enabled toolchain. - **Operator documentation:** `docs/evm-migration.md` describes the migration model, supported account types, the automatic startup flow, manual multisig procedure, and recovery scenarios. diff --git a/cmd/sncli/go.mod b/cmd/sncli/go.mod index 4edf1b2a..e32fa244 100644 --- a/cmd/sncli/go.mod +++ b/cmd/sncli/go.mod @@ -13,7 +13,7 @@ replace ( require ( github.com/BurntSushi/toml v1.6.0 - github.com/LumeraProtocol/lumera v1.20.0-rc2 + github.com/LumeraProtocol/lumera v1.20.0-rc3 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 github.com/cosmos/cosmos-sdk v0.53.6 github.com/spf13/cobra v1.10.2 diff --git a/cmd/sncli/go.sum b/cmd/sncli/go.sum index 7b8b1acf..3408bce8 100644 --- a/cmd/sncli/go.sum +++ b/cmd/sncli/go.sum @@ -112,8 +112,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.20.0-rc2 h1:T7lQVigQfb+ywH925qqBILiR3awWTXGAOXWbYZppF4E= -github.com/LumeraProtocol/lumera v1.20.0-rc2/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= +github.com/LumeraProtocol/lumera v1.20.0-rc3 h1:DkQGiF7zlCFYC7ygdlmJa+sPs2gxCMNN0ypIAWAjNBA= +github.com/LumeraProtocol/lumera v1.20.0-rc3/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/go.mod b/go.mod index e7719eec..2fbd6459 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( cosmossdk.io/x/upgrade v0.2.0 github.com/AlecAivazis/survey/v2 v2.3.7 github.com/DataDog/zstd v1.5.7 - github.com/LumeraProtocol/lumera v1.20.0-rc2 + github.com/LumeraProtocol/lumera v1.20.0-rc3 github.com/LumeraProtocol/rq-go v0.2.1 github.com/Masterminds/semver/v3 v3.4.0 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce diff --git a/go.sum b/go.sum index 9a2a5f06..501fd972 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.20.0-rc2 h1:T7lQVigQfb+ywH925qqBILiR3awWTXGAOXWbYZppF4E= -github.com/LumeraProtocol/lumera v1.20.0-rc2/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= +github.com/LumeraProtocol/lumera v1.20.0-rc3 h1:DkQGiF7zlCFYC7ygdlmJa+sPs2gxCMNN0ypIAWAjNBA= +github.com/LumeraProtocol/lumera v1.20.0-rc3/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4= github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= diff --git a/tests/system/go.mod b/tests/system/go.mod index 681f680f..67e4de8b 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -13,11 +13,12 @@ replace ( require ( cosmossdk.io/math v1.5.3 - github.com/LumeraProtocol/lumera v1.20.0-rc2 + github.com/LumeraProtocol/lumera v1.20.0-rc3 github.com/LumeraProtocol/supernode/v2 v2.0.0-00010101000000-000000000000 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/cometbft/cometbft v0.38.21 github.com/cosmos/cosmos-sdk v0.53.6 + github.com/cosmos/evm v0.6.0 github.com/cosmos/gogoproto v1.7.2 github.com/cosmos/ibc-go/v10 v10.5.0 github.com/mattn/go-sqlite3 v1.14.24 @@ -75,7 +76,6 @@ require ( github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.1.3 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect - github.com/cosmos/evm v0.6.0 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.2.6 // indirect diff --git a/tests/system/go.sum b/tests/system/go.sum index 9c0e65f4..9b497662 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -108,8 +108,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.20.0-rc2 h1:T7lQVigQfb+ywH925qqBILiR3awWTXGAOXWbYZppF4E= -github.com/LumeraProtocol/lumera v1.20.0-rc2/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= +github.com/LumeraProtocol/lumera v1.20.0-rc3 h1:DkQGiF7zlCFYC7ygdlmJa+sPs2gxCMNN0ypIAWAjNBA= +github.com/LumeraProtocol/lumera v1.20.0-rc3/go.mod h1:Ru+SQjwg47CsceToex+izOA8ZMILl0vB0Fxd89umk5E= github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4= github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= From e66314fd99c8838f71719ee59aca7f444e03c60b Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 9 Jun 2026 22:32:29 -0400 Subject: [PATCH 18/22] Address PR #299 review feedback (EVM signing/startup) - requireEVMChain: distinguish a transient module-version query failure (chain unreachable / gRPC blip at boot) from a definitive "EVM module absent" answer. Transient errors are now retried with backoff instead of immediately Fatal-ing into a crash loop; module-absent still fails fast. Extracted requireEVMChainWithQuerier behind a small interface and added unit tests (present, absent-no-retry, transient-then-success, persistent-failure, context-cancelled). - evmigration: document why the EVM proof signature intentionally keeps the 65th recovery byte (chain verifier requires R||S||V and strips V itself), and why the migration broadcast tx is deliberately unsigned (self-authenticating via dual MigrationProof + evmigration ante). - keyring.SignBytes: return sig, nil (err is nil here) and document that the 65->64 truncation targets cosmos-form chain verifiers; the P2P securekeyx handshake is unaffected (separate sign/verify path). - testutil/lumera.go: gofmt import grouping (grpc was mid-group). Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/keyring/keyring.go | 12 +++- pkg/testutil/lumera.go | 2 +- supernode/cmd/evmigration.go | 100 ++++++++++++++++++++++++------ supernode/cmd/evmigration_test.go | 88 ++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 22 deletions(-) diff --git a/pkg/keyring/keyring.go b/pkg/keyring/keyring.go index d1ec67a0..37b147fc 100644 --- a/pkg/keyring/keyring.go +++ b/pkg/keyring/keyring.go @@ -231,10 +231,20 @@ func SignBytes(kr sdkkeyring.Keyring, name string, bz []byte) ([]byte, error) { if err != nil { return nil, err } + // eth_secp256k1 signs as 65 bytes (R||S||V); drop the trailing recovery byte + // so the result is the 64-byte (R||S) cosmos form expected by the verifiers of + // SignBytes callers (action/cascade ADR-036, storage-challenge, audit proofs). + // Legacy secp256k1 sigs are already 64 bytes and unaffected. + // + // This does NOT affect the P2P/secure-channel handshake: securekeyx signs and + // verifies via its own path (SecureKeyExchange + ethsecp256k1.VerifySignature, + // which strips V internally), not through SignBytes. The migration proof path + // (supernode/cmd/evmigration.go) likewise keeps the full 65-byte sig because + // the chain's evmigration verifier requires R||S||V. if len(sig) == 65 { sig = sig[:64] } - return sig, err + return sig, nil } func GetAddress(kr sdkkeyring.Keyring, name string) (types.AccAddress, error) { diff --git a/pkg/testutil/lumera.go b/pkg/testutil/lumera.go index 7ee0e42e..72689285 100644 --- a/pkg/testutil/lumera.go +++ b/pkg/testutil/lumera.go @@ -20,13 +20,13 @@ import ( sdkmath "cosmossdk.io/math" cmtservice "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" - "google.golang.org/grpc" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdktypes "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" sdktx "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "google.golang.org/grpc" ) // MockLumeraClient implements the lumera.Client interface for testing purposes diff --git a/supernode/cmd/evmigration.go b/supernode/cmd/evmigration.go index 1cf85d38..3ec8fd92 100644 --- a/supernode/cmd/evmigration.go +++ b/supernode/cmd/evmigration.go @@ -107,31 +107,76 @@ func validateLegacyMigrationSetup(kr cKeyring.Keyring, keyName, evmKeyName strin return true, nil } +// moduleVersionQuerier is the subset of upgradetypes.QueryClient that +// requireEVMChain needs. It is an interface so the retry/classification logic +// can be unit-tested without a live gRPC connection. +type moduleVersionQuerier interface { + ModuleVersions(ctx context.Context, req *upgradetypes.QueryModuleVersionsRequest, opts ...grpc.CallOption) (*upgradetypes.QueryModuleVersionsResponse, error) +} + +// requireEVMChainQueryRetries is the number of attempts requireEVMChain makes +// against a transiently-failing chain before giving up. requireEVMChainRetryBackoff +// returns the delay before the given (1-based) attempt; it is a var so tests can +// shrink it. +const requireEVMChainQueryRetries = 5 + +var requireEVMChainRetryBackoff = func(attempt int) time.Duration { + return time.Duration(attempt) * time.Second +} + // requireEVMChain verifies that the connected Lumera chain has the EVM module // active. If the module is absent, this supernode binary is incompatible and // must not proceed. +// +// A transient query failure (chain momentarily unreachable / gRPC blip at boot) +// is retried with backoff so a brief network hiccup does not turn into a hard +// crash loop. Only a query that *succeeds* and reports the EVM module absent is +// treated as a definitive incompatibility and returned immediately. func requireEVMChain(ctx context.Context, conn *grpc.ClientConn) error { - client := upgradetypes.NewQueryClient(conn) - resp, err := client.ModuleVersions(ctx, &upgradetypes.QueryModuleVersionsRequest{ - ModuleName: evmModuleName, - }) - if err != nil { - return fmt.Errorf("failed to query chain module versions: %w", err) - } - if len(resp.ModuleVersions) == 0 { - return fmt.Errorf( - "connected Lumera chain does not have EVM support (module %q not found). "+ - "This supernode binary requires an EVM-enabled Lumera chain. "+ - "Please upgrade your Lumera node or connect to an EVM-enabled chain", - evmModuleName, - ) - } + return requireEVMChainWithQuerier(ctx, upgradetypes.NewQueryClient(conn)) +} - logtrace.Info(ctx, "EVM module detected on chain", logtrace.Fields{ - "module": evmModuleName, - "version": resp.ModuleVersions[0].Version, - }) - return nil +func requireEVMChainWithQuerier(ctx context.Context, client moduleVersionQuerier) error { + var lastErr error + for attempt := 1; attempt <= requireEVMChainQueryRetries; attempt++ { + resp, err := client.ModuleVersions(ctx, &upgradetypes.QueryModuleVersionsRequest{ + ModuleName: evmModuleName, + }) + if err != nil { + // Transient: chain unreachable / gRPC error. Retry with backoff. + lastErr = err + logtrace.Warn(ctx, "EVM module-version query failed; will retry", logtrace.Fields{ + "attempt": attempt, + "max_attempts": requireEVMChainQueryRetries, + "error": err.Error(), + }) + if attempt == requireEVMChainQueryRetries { + break + } + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(requireEVMChainRetryBackoff(attempt)): + } + continue + } + if len(resp.ModuleVersions) == 0 { + // Definitive: chain answered, EVM module is absent. Do not retry. + return fmt.Errorf( + "connected Lumera chain does not have EVM support (module %q not found). "+ + "This supernode binary requires an EVM-enabled Lumera chain. "+ + "Please upgrade your Lumera node or connect to an EVM-enabled chain", + evmModuleName, + ) + } + + logtrace.Info(ctx, "EVM module detected on chain", logtrace.Fields{ + "module": evmModuleName, + "version": resp.ModuleVersions[0].Version, + }) + return nil + } + return fmt.Errorf("failed to query chain module versions after %d attempts: %w", requireEVMChainQueryRetries, lastErr) } // isLegacyKey returns true if the key stored in the keyring under keyName uses @@ -361,6 +406,13 @@ func ensureLegacyAccountMigrated( // Sign with new EVM key from keyring (eth_secp256k1 signs raw payload; // internally uses Keccak-256). + // + // The 65-byte signature (R||S||V) is embedded into SingleKeyProof as-is — + // the trailing recovery byte is intentionally retained here. The chain's + // proof verifier (x/evmigration VerifyEthSecp256k1) requires exactly 65 + // bytes and strips V itself before VerifySignature. This deliberately + // differs from keyring.SignBytes, which truncates eth sigs to 64 bytes for + // the cosmos-form (ADR-036/action) verifiers used elsewhere. newSig, _, err := kr.Sign(evmKeyName, payload, signingtypes.SignMode_SIGN_MODE_DIRECT) if err != nil { return fmt.Errorf("failed to sign migration payload with EVM key: %w", err) @@ -519,6 +571,14 @@ func broadcastMigrationTx(ctx context.Context, conn *grpc.ClientConn, msg sdk.Ms return fmt.Errorf("failed to set message on tx builder: %w", err) } + // NOTE: this tx is broadcast deliberately UNSIGNED — no signer info, sequence, + // or fee is set. evmigration messages are self-authenticating via the dual + // MigrationProof signatures inside the message, and the chain's evmigration + // ante decorator waives signature/fee verification for them. Do not "fix" this + // by adding signer setup: that would break the self-authenticating design. + // requireEVMChain gates module presence at startup, but not the ante config, so + // on a chain lacking that decorator this broadcast will fail at CheckTx. + // Simulate to get gas estimate. Migration txs are fee-exempt on chain, but // we still need a valid gas limit. txBytes, err := encCfg.TxConfig.TxEncoder()(txBuilder.GetTx()) diff --git a/supernode/cmd/evmigration_test.go b/supernode/cmd/evmigration_test.go index 6e2c8c02..e8431197 100644 --- a/supernode/cmd/evmigration_test.go +++ b/supernode/cmd/evmigration_test.go @@ -2,12 +2,15 @@ package cmd import ( "context" + "errors" "fmt" "os" "path/filepath" "testing" "time" + upgradetypes "cosmossdk.io/x/upgrade/types" + evmigrationtypes "github.com/LumeraProtocol/lumera/x/evmigration/types" supernodeTypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types" "github.com/LumeraProtocol/supernode/v2/pkg/lumera/modules/supernode" @@ -1231,3 +1234,88 @@ func TestEnsureLegacyAccountMigrated_BothQueriesFail_FailsClosed(t *testing.T) { assert.Contains(t, err.Error(), "failed to query migration estimate") assert.Nil(t, mc.broadcastedMsg, "should not broadcast when both migration queries are unavailable") } + +// --- requireEVMChain retry / classification tests --- + +// fakeModuleVersionQuerier returns a scripted sequence of results, one per call, +// so tests can model transient failures, eventual success, and the module-absent +// case. If more calls happen than scripted entries, the last entry is reused. +type fakeModuleVersionQuerier struct { + resps []*upgradetypes.QueryModuleVersionsResponse + errs []error + calls int +} + +func (f *fakeModuleVersionQuerier) ModuleVersions(_ context.Context, _ *upgradetypes.QueryModuleVersionsRequest, _ ...grpc.CallOption) (*upgradetypes.QueryModuleVersionsResponse, error) { + i := f.calls + f.calls++ + if i >= len(f.errs) { + i = len(f.errs) - 1 + } + return f.resps[min(i, len(f.resps)-1)], f.errs[i] +} + +func withFastEVMChainBackoff(t *testing.T) { + t.Helper() + orig := requireEVMChainRetryBackoff + requireEVMChainRetryBackoff = func(int) time.Duration { return time.Millisecond } + t.Cleanup(func() { requireEVMChainRetryBackoff = orig }) +} + +func evmPresentResp() *upgradetypes.QueryModuleVersionsResponse { + return &upgradetypes.QueryModuleVersionsResponse{ + ModuleVersions: []*upgradetypes.ModuleVersion{{Name: evmModuleName, Version: 1}}, + } +} + +func TestRequireEVMChain_ModulePresent(t *testing.T) { + q := &fakeModuleVersionQuerier{resps: []*upgradetypes.QueryModuleVersionsResponse{evmPresentResp()}, errs: []error{nil}} + require.NoError(t, requireEVMChainWithQuerier(context.Background(), q)) + assert.Equal(t, 1, q.calls, "a successful query must not retry") +} + +func TestRequireEVMChain_ModuleAbsent_NoRetry(t *testing.T) { + withFastEVMChainBackoff(t) + q := &fakeModuleVersionQuerier{ + resps: []*upgradetypes.QueryModuleVersionsResponse{{ModuleVersions: nil}}, + errs: []error{nil}, + } + err := requireEVMChainWithQuerier(context.Background(), q) + require.Error(t, err) + assert.Contains(t, err.Error(), "does not have EVM support") + assert.Equal(t, 1, q.calls, "a definitive module-absent answer must not retry") +} + +func TestRequireEVMChain_TransientThenSuccess(t *testing.T) { + withFastEVMChainBackoff(t) + q := &fakeModuleVersionQuerier{ + resps: []*upgradetypes.QueryModuleVersionsResponse{nil, nil, evmPresentResp()}, + errs: []error{errors.New("connection refused"), errors.New("connection refused"), nil}, + } + require.NoError(t, requireEVMChainWithQuerier(context.Background(), q)) + assert.Equal(t, 3, q.calls, "should retry transient failures until the query succeeds") +} + +func TestRequireEVMChain_PersistentFailure(t *testing.T) { + withFastEVMChainBackoff(t) + q := &fakeModuleVersionQuerier{ + resps: []*upgradetypes.QueryModuleVersionsResponse{nil}, + errs: []error{errors.New("unreachable")}, + } + err := requireEVMChainWithQuerier(context.Background(), q) + require.Error(t, err) + assert.Contains(t, err.Error(), "after 5 attempts") + assert.Equal(t, requireEVMChainQueryRetries, q.calls, "should exhaust all retries on persistent failure") +} + +func TestRequireEVMChain_ContextCancelledDuringBackoff(t *testing.T) { + withFastEVMChainBackoff(t) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + q := &fakeModuleVersionQuerier{ + resps: []*upgradetypes.QueryModuleVersionsResponse{nil}, + errs: []error{errors.New("unreachable")}, + } + err := requireEVMChainWithQuerier(ctx, q) + require.ErrorIs(t, err, context.Canceled) +} From 57da6d2cc8e6393b9238712683ba944fb2cf3d81 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 9 Jun 2026 22:53:11 -0400 Subject: [PATCH 19/22] Fix flaky sqlite store shutdown (TempDir cleanup race) TestGetKeysForReplication_CanceledContext intermittently failed in CI with "TempDir RemoveAll cleanup: directory not empty" because the sqlite store's background goroutines could still write WAL/-shm files after Close() returned. Root cause: Worker.Stop() sent a single value on an unbuffered quit channel that BOTH the DB worker and the checkpoint worker selected on, so only one was released and the checkpoint worker leaked. It also slept up to checkpointInterval inside backoff.RetryNotify before re-checking quit, and Close() never waited for the goroutines before closing the DB. Fix: - Worker.Stop() now closes the quit channel (broadcast to all listeners) via sync.Once instead of sending one value. - The checkpoint worker bails out of its retry loop on shutdown (backoff.Permanent(errStoreClosing)) and uses an interruptible inter-checkpoint wait so it stops promptly. - Store tracks its three long-lived goroutines (DB worker, checkpoint worker, replication writer) with a WaitGroup; Close() signals stop, waits for them to exit, then closes the DB. Close() is now idempotent (sync.Once), and startRepWriter no longer spawns a nested goroutine. - Converted RetrieveBatchValues / retrieveBatchValues from value to pointer receiver (a Store value can no longer be copied now that it holds sync primitives). Added TestStore_CloseStopsWorkersAndIsIdempotent. Verified with go test -race -count=10 (sqlite + kademlia packages). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../store/sqlite/close_lifecycle_test.go | 50 ++++++++++ p2p/kademlia/store/sqlite/replication.go | 86 ++++++++--------- p2p/kademlia/store/sqlite/sqlite.go | 92 +++++++++++++++---- 3 files changed, 167 insertions(+), 61 deletions(-) create mode 100644 p2p/kademlia/store/sqlite/close_lifecycle_test.go diff --git a/p2p/kademlia/store/sqlite/close_lifecycle_test.go b/p2p/kademlia/store/sqlite/close_lifecycle_test.go new file mode 100644 index 00000000..0e0c875b --- /dev/null +++ b/p2p/kademlia/store/sqlite/close_lifecycle_test.go @@ -0,0 +1,50 @@ +package sqlite + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +// TestStore_CloseStopsWorkersAndIsIdempotent verifies the store shutdown +// contract that backs TestGetKeysForReplication_CanceledContext's TempDir +// cleanup: Close must stop every background goroutine (DB worker, checkpoint +// worker, replication writer) and wait for them to exit, so nothing touches the +// database or its WAL files afterwards. It must also be safe to call more than +// once. +// +// Regression guard: Worker.Stop previously sent a single value on an unbuffered +// quit channel that two goroutines selected on, so the checkpoint worker could +// leak and keep writing WAL/-shm files after Close returned — racing teardown. +func TestStore_CloseStopsWorkersAndIsIdempotent(t *testing.T) { + store, err := NewStore(context.Background(), t.TempDir(), nil, nil) + require.NoError(t, err) + + // Close must return promptly: if a worker ignored the quit signal, the + // internal WaitGroup would block here forever. + done := make(chan struct{}) + go func() { + store.Close(context.Background()) + close(done) + }() + select { + case <-done: + case <-time.After(15 * time.Second): + t.Fatal("Close did not return in time; a background worker did not stop") + } + + // Idempotent: a second Close must neither panic (double close of quit + // channels) nor hang. + secondClose := make(chan struct{}) + go func() { + require.NotPanics(t, func() { store.Close(context.Background()) }) + close(secondClose) + }() + select { + case <-secondClose: + case <-time.After(5 * time.Second): + t.Fatal("second Close did not return in time") + } +} diff --git a/p2p/kademlia/store/sqlite/replication.go b/p2p/kademlia/store/sqlite/replication.go index 3616553e..8e776a54 100644 --- a/p2p/kademlia/store/sqlite/replication.go +++ b/p2p/kademlia/store/sqlite/replication.go @@ -481,12 +481,12 @@ func (s *Store) RetrieveBatchNotExist(ctx context.Context, keys []string, batchS return nonExistingKeys, nil } -func (s Store) RetrieveBatchValues(ctx context.Context, keys []string, getFromCloud bool) ([][]byte, int, error) { +func (s *Store) RetrieveBatchValues(ctx context.Context, keys []string, getFromCloud bool) ([][]byte, int, error) { return retrieveBatchValues(ctx, s.db, keys, getFromCloud, s) } // RetrieveBatchValues returns a list of values for the given keys (hex-encoded). -func retrieveBatchValues(ctx context.Context, db *sqlx.DB, keys []string, getFromCloud bool, s Store) ([][]byte, int, error) { +func retrieveBatchValues(ctx context.Context, db *sqlx.DB, keys []string, getFromCloud bool, s *Store) ([][]byte, int, error) { // Early return if len(keys) == 0 { return nil, 0, nil @@ -702,49 +702,51 @@ func NewRepWriter(buf int) *RepWriter { func (w *RepWriter) Stop() { close(w.quit) } // startRepWriter runs a single serialized loop for replication_info updates. +// It is launched with `go s.startRepWriter(ctx)`, so the loop runs directly in +// that goroutine; it is tracked by s.workersWG and exits on ctx cancel or the +// repWriter quit signal. func (s *Store) startRepWriter(ctx context.Context) { - go func() { - for { - select { - case <-ctx.Done(): - return - case <-s.repWriter.quit: - return - case j := <-s.repWriter.ch: - var err error - // pick a context for DB ops (prefer job ctx if non-nil) - dbctx := j.ctx - if dbctx == nil { - dbctx = context.Background() - } - switch j.kind { - case repJobLastSeen: - _, err = s.db.ExecContext(dbctx, - `UPDATE replication_info SET last_seen = ? WHERE id = ?`, - time.Now().UTC(), j.id) - - case repJobIsActive: - _, err = s.db.ExecContext(dbctx, - `UPDATE replication_info SET is_active = ?, is_adjusted = ?, updatedAt = ? WHERE id = ?`, - j.isActive, j.isAdjusted, time.Now().UTC(), j.id) - - case repJobIsAdjusted: - _, err = s.db.ExecContext(dbctx, - `UPDATE replication_info SET is_adjusted = ?, updatedAt = ? WHERE id = ?`, - j.isAdjusted, time.Now().UTC(), j.id) - - case repJobLastReplicated: - _, err = s.db.ExecContext(dbctx, - `UPDATE replication_info SET lastReplicatedAt = ?, updatedAt = ? WHERE id = ?`, - j.t, time.Now().UTC(), j.id) - } - // deliver result - if j.done != nil { - j.done <- err - } + defer s.workersWG.Done() + for { + select { + case <-ctx.Done(): + return + case <-s.repWriter.quit: + return + case j := <-s.repWriter.ch: + var err error + // pick a context for DB ops (prefer job ctx if non-nil) + dbctx := j.ctx + if dbctx == nil { + dbctx = context.Background() + } + switch j.kind { + case repJobLastSeen: + _, err = s.db.ExecContext(dbctx, + `UPDATE replication_info SET last_seen = ? WHERE id = ?`, + time.Now().UTC(), j.id) + + case repJobIsActive: + _, err = s.db.ExecContext(dbctx, + `UPDATE replication_info SET is_active = ?, is_adjusted = ?, updatedAt = ? WHERE id = ?`, + j.isActive, j.isAdjusted, time.Now().UTC(), j.id) + + case repJobIsAdjusted: + _, err = s.db.ExecContext(dbctx, + `UPDATE replication_info SET is_adjusted = ?, updatedAt = ? WHERE id = ?`, + j.isAdjusted, time.Now().UTC(), j.id) + + case repJobLastReplicated: + _, err = s.db.ExecContext(dbctx, + `UPDATE replication_info SET lastReplicatedAt = ?, updatedAt = ? WHERE id = ?`, + j.t, time.Now().UTC(), j.id) + } + // deliver result + if j.done != nil { + j.done <- err } } - }() + } } // UpdateLastSeen updates last_seen for a node (serialized via writer) diff --git a/p2p/kademlia/store/sqlite/sqlite.go b/p2p/kademlia/store/sqlite/sqlite.go index 222fe0d7..fd1df1b5 100644 --- a/p2p/kademlia/store/sqlite/sqlite.go +++ b/p2p/kademlia/store/sqlite/sqlite.go @@ -9,6 +9,7 @@ import ( "os" "path" "strings" + "sync" "time" "github.com/LumeraProtocol/supernode/v2/p2p/kademlia" @@ -29,6 +30,10 @@ var ( storeBatchRetryTimeout = 5 * time.Second ) +// errStoreClosing is returned (wrapped via backoff.Permanent) by the checkpoint +// worker's retry loop to stop retrying once the store is shutting down. +var errStoreClosing = errors.New("sqlite store is closing") + // Job represents the job to be run type Job struct { JobType string // Insert, Update or Delete @@ -49,6 +54,7 @@ type Job struct { type Worker struct { JobQueue chan Job quit chan bool + stopOnce sync.Once } // Store is the main struct @@ -59,6 +65,12 @@ type Store struct { migrationStore *MigrationMetaStore repWriter *RepWriter dbFilePath string + + // workersWG tracks the long-lived background goroutines (DB worker, + // checkpoint worker, replication writer) so Close can wait for them to + // exit before closing the database. closeOnce makes Close idempotent. + workersWG sync.WaitGroup + closeOnce sync.Once } // Record is a data record @@ -163,6 +175,9 @@ func NewStore(ctx context.Context, dataDir string, cloud cloud.Storage, mst *Mig s.db = db s.dbFilePath = dbFile + // Track the long-lived background goroutines so Close can wait for them + // to exit before closing the database (prevents WAL writes racing teardown). + s.workersWG.Add(3) go s.start(ctx) // Run WAL checkpoint worker every 60 seconds go s.startCheckpointWorker(ctx) @@ -274,28 +289,43 @@ func (s *Store) migrate() error { } func (s *Store) startCheckpointWorker(ctx context.Context) { + defer s.workersWG.Done() + b := backoff.NewExponentialBackOff() b.MaxElapsedTime = 1 * time.Minute b.InitialInterval = 100 * time.Millisecond for { + // Stop promptly if shutdown was already signalled, before doing any work. + if s.shuttingDown(ctx) { + logtrace.Debug(ctx, "Stopping checkpoint worker because of shutdown signal", logtrace.Fields{}) + return + } + err := backoff.RetryNotify(func() error { - err := s.checkpoint() - if err == nil { - // If no error, delay for 5 seconds. - time.Sleep(checkpointInterval) + // Don't keep retrying a checkpoint once the store is closing — the DB + // is about to be (or already) closed, so further attempts only spin. + if s.shuttingDown(ctx) { + return backoff.Permanent(errStoreClosing) } - return err + return s.checkpoint() }, b, func(err error, duration time.Duration) { logtrace.Error(ctx, "Failed to perform checkpoint, retrying...", logtrace.Fields{logtrace.FieldError: err.Error(), "duration": duration}) }) + if errors.Is(err, errStoreClosing) { + return + } if err == nil { b.Reset() b.MaxElapsedTime = 1 * time.Minute b.InitialInterval = 100 * time.Millisecond } + // Interruptible inter-checkpoint wait: a closed quit channel or a + // cancelled context releases the worker immediately instead of after the + // full checkpoint interval, so Close does not block (and the goroutine + // cannot touch WAL files after teardown begins). select { case <-ctx.Done(): logtrace.Debug(ctx, "Stopping checkpoint worker because of context cancel", logtrace.Fields{}) @@ -303,13 +333,27 @@ func (s *Store) startCheckpointWorker(ctx context.Context) { case <-s.worker.quit: logtrace.Debug(ctx, "Stopping checkpoint worker because of quit signal", logtrace.Fields{}) return - default: + case <-time.After(checkpointInterval): } } } +// shuttingDown reports whether the store is being torn down, either via context +// cancellation or the worker quit signal. +func (s *Store) shuttingDown(ctx context.Context) bool { + select { + case <-ctx.Done(): + return true + case <-s.worker.quit: + return true + default: + return false + } +} + // Start method starts the run loop for the worker func (s *Store) start(ctx context.Context) { + defer s.workersWG.Done() for { select { case job := <-s.worker.JobQueue: @@ -335,11 +379,14 @@ func (s *Store) start(ctx context.Context) { } } -// Stop signals the worker to stop listening for work requests. +// Stop signals the worker to stop listening for work requests. It closes the +// quit channel (rather than sending a single value) so that every goroutine +// selecting on it — the DB worker and the checkpoint worker — is released, not +// just whichever happens to receive first. Safe to call multiple times. func (w *Worker) Stop() { - go func() { - w.quit <- true - }() + w.stopOnce.Do(func() { + close(w.quit) + }) } // Store function creates a new job and pushes it into the JobQueue @@ -749,18 +796,25 @@ func (s *Store) Stats(ctx context.Context) (kademlia.DatabaseStats, error) { // Close the store func (s *Store) Close(ctx context.Context) { - s.worker.Stop() + s.closeOnce.Do(func() { + // Signal the background goroutines to stop... + s.worker.Stop() + if s.repWriter != nil { + s.repWriter.Stop() + } - if s.repWriter != nil { - s.repWriter.Stop() - } + // ...and wait for them to actually exit before closing the DB. This + // guarantees no checkpoint/replication goroutine touches the database or + // its WAL/-shm files after Close returns, which previously raced test + // TempDir cleanup and could corrupt teardown ordering in production. + s.workersWG.Wait() - if s.db != nil { - if err := s.db.Close(); err != nil { - logtrace.Error(ctx, "Failed to close database", logtrace.Fields{logtrace.FieldModule: "p2p", logtrace.FieldError: err.Error()}) + if s.db != nil { + if err := s.db.Close(); err != nil { + logtrace.Error(ctx, "Failed to close database", logtrace.Fields{logtrace.FieldModule: "p2p", logtrace.FieldError: err.Error()}) + } } - } - + }) } // GetOwnCreatedAt func From fc063ffdcac6aa1a7b0b2b97a1694e2ed75e08a4 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 9 Jun 2026 23:05:42 -0400 Subject: [PATCH 20/22] Retry finalize simulation on transient account-sequence mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TestLEP6ConcurrentCascadesContendedReporter intermittently failed when a single supernode finalized several cascade actions concurrently: the finalize *simulation* pre-check (cascade/register.go step 11) fatally failed with "account sequence mismatch, expected N, got M". Simulation reads the signer's committed sequence into accountInfo, but under concurrent in-flight txs from the same signer that value goes stale between the read and the simulate ante check (TOCTOU). The actual FinalizeAction broadcast already retries sequence mismatches, so a simulate-only mismatch is a false negative that needlessly fails the upload. TxHelper.Simulate now retries on sequence mismatch — re-fetching fresh account info each attempt, bounded by the same SequenceMismatchMaxAttempts cap as the broadcast path. Added unit tests for the retry-then-succeed and exhaust-cap cases. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../tx/execute_oog_integration_test.go | 11 +++ pkg/lumera/modules/tx/helper.go | 38 ++++++++- .../tx/simulate_sequence_retry_test.go | 80 +++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 pkg/lumera/modules/tx/simulate_sequence_retry_test.go diff --git a/pkg/lumera/modules/tx/execute_oog_integration_test.go b/pkg/lumera/modules/tx/execute_oog_integration_test.go index b8615f92..369453db 100644 --- a/pkg/lumera/modules/tx/execute_oog_integration_test.go +++ b/pkg/lumera/modules/tx/execute_oog_integration_test.go @@ -63,6 +63,11 @@ type scenarioTxModule struct { // Optional: fail with a non-OOG error instead of an OOG one. nonOOGError error + + // If non-zero, SimulateTransaction returns an account-sequence-mismatch + // error for this many calls before succeeding. + seqMismatchSims int + simCalls int } func (s *scenarioTxModule) ProcessTransaction(_ context.Context, _ []types.Msg, _ *authtypes.BaseAccount, cfg *TxConfig) (*sdktx.BroadcastTxResponse, error) { @@ -88,6 +93,12 @@ func (s *scenarioTxModule) ProcessTransaction(_ context.Context, _ []types.Msg, } func (s *scenarioTxModule) SimulateTransaction(_ context.Context, _ []types.Msg, _ *authtypes.BaseAccount, _ *TxConfig) (*sdktx.SimulateResponse, error) { + s.mu.Lock() + defer s.mu.Unlock() + s.simCalls++ + if s.simCalls <= s.seqMismatchSims { + return nil, fmt.Errorf("rpc error: code = Unknown desc = account sequence mismatch, expected 1, got 0: incorrect account sequence [cosmos/cosmos-sdk@v0.53.6/x/auth/ante/sigverify.go:364]") + } return &sdktx.SimulateResponse{}, nil } diff --git a/pkg/lumera/modules/tx/helper.go b/pkg/lumera/modules/tx/helper.go index 99a0dc7d..778cb8f9 100644 --- a/pkg/lumera/modules/tx/helper.go +++ b/pkg/lumera/modules/tx/helper.go @@ -499,5 +499,41 @@ func (h *TxHelper) GetConfig() *TxConfig { // Simulate runs an offline simulation for the provided messages using the // configured tx settings and given account info. Useful for pre-flight checks. func (h *TxHelper) Simulate(ctx context.Context, msgs []types.Msg, accountInfo *authtypes.BaseAccount) (*sdktx.SimulateResponse, error) { - return h.txmod.SimulateTransaction(ctx, msgs, accountInfo, h.config) + // Retry on sequence mismatch. Simulation reads the signer's committed + // sequence into accountInfo, but under concurrent transactions from the same + // signer (e.g. one supernode finalizing several cascade actions at once) that + // value can go stale between the read and the simulate ante check, yielding + // "account sequence mismatch, expected N, got M". This is transient: the + // broadcast path (ExecuteTransaction) already retries the same way, so a + // simulate-only mismatch is a false negative that should not fail the caller. + // Re-fetch fresh account info and retry, bounded by the same cap as broadcast. + maxAttempts := h.config.SequenceMismatchMaxAttempts + if maxAttempts <= 0 { + maxAttempts = DefaultSequenceMismatchMaxAttempts + } + if maxAttempts > MaxSequenceMismatchAttemptsCap { + maxAttempts = MaxSequenceMismatchAttemptsCap + } + + var lastErr error + for attempt := 0; attempt < maxAttempts; attempt++ { + resp, err := h.txmod.SimulateTransaction(ctx, msgs, accountInfo, h.config) + if err == nil { + return resp, nil + } + if !isSequenceMismatch(err) { + return nil, err + } + lastErr = err + + // Refresh the signer's account info so the next attempt uses the settled + // sequence; if that fails, return the original mismatch error. + fresh, refreshErr := h.GetAccountInfo(ctx) + if refreshErr != nil { + return nil, err + } + accountInfo = fresh + sleepSequenceMismatchBackoff(ctx, attempt+1) + } + return nil, lastErr } diff --git a/pkg/lumera/modules/tx/simulate_sequence_retry_test.go b/pkg/lumera/modules/tx/simulate_sequence_retry_test.go new file mode 100644 index 00000000..34871d9d --- /dev/null +++ b/pkg/lumera/modules/tx/simulate_sequence_retry_test.go @@ -0,0 +1,80 @@ +package tx + +import ( + "context" + "testing" + + "github.com/cosmos/cosmos-sdk/types" +) + +// TestTxHelper_Simulate_RetriesOnSequenceMismatch verifies that a transient +// account-sequence-mismatch during simulation is retried (with a fresh account +// info fetch) rather than surfaced to the caller. This is the regression guard +// for TestLEP6ConcurrentCascadesContendedReporter, where one supernode +// finalizing several cascade actions concurrently could see the simulate +// pre-check fail with "account sequence mismatch, expected N, got M" even though +// the subsequent broadcast (which already retries) would have succeeded. +func TestTxHelper_Simulate_RetriesOnSequenceMismatch(t *testing.T) { + t.Parallel() + + kr, addr := newTestKeyring(t, "validator") + auth := &stubAuthModule{addr: addr, seq: 0, num: 7} + + // First two simulate attempts fail with a sequence mismatch; the third + // succeeds — within the default 3-attempt cap. + txMod := &scenarioTxModule{seqMismatchSims: 2} + + h := NewTxHelper(auth, txMod, &TxHelperConfig{ + ChainID: "lumera-devnet-1", + Keyring: kr, + KeyName: "validator", + }) + + acc, err := h.GetAccountInfo(context.Background()) + if err != nil { + t.Fatalf("GetAccountInfo: %v", err) + } + + resp, err := h.Simulate(context.Background(), []types.Msg{}, acc) + if err != nil { + t.Fatalf("Simulate: expected success after sequence-mismatch retries, got: %v", err) + } + if resp == nil { + t.Fatal("Simulate: nil response") + } + if txMod.simCalls != 3 { + t.Fatalf("Simulate: expected 3 attempts (2 mismatch + 1 success), got %d", txMod.simCalls) + } +} + +// TestTxHelper_Simulate_GivesUpAfterMaxAttempts verifies the retry is bounded: +// a persistent sequence mismatch eventually surfaces instead of looping forever. +func TestTxHelper_Simulate_GivesUpAfterMaxAttempts(t *testing.T) { + t.Parallel() + + kr, addr := newTestKeyring(t, "validator") + auth := &stubAuthModule{addr: addr, seq: 0, num: 7} + + // Always fail with a sequence mismatch. + txMod := &scenarioTxModule{seqMismatchSims: 1000} + + h := NewTxHelper(auth, txMod, &TxHelperConfig{ + ChainID: "lumera-devnet-1", + Keyring: kr, + KeyName: "validator", + SequenceMismatchMaxAttempts: 2, + }) + + acc, err := h.GetAccountInfo(context.Background()) + if err != nil { + t.Fatalf("GetAccountInfo: %v", err) + } + + _, err = h.Simulate(context.Background(), []types.Msg{}, acc) + if err == nil { + t.Fatal("Simulate: expected error after exhausting retries") + } + if txMod.simCalls != 2 { + t.Fatalf("Simulate: expected exactly 2 attempts (cap), got %d", txMod.simCalls) + } +} From efd0320000c283b8b0152dc204ad13bd426fc712 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 9 Jun 2026 23:11:26 -0400 Subject: [PATCH 21/22] Retry transient P2P artefact-store failures during cascade register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The other half of TestLEP6ConcurrentCascadesContendedReporter: under concurrent uploads, StoreArtefacts could fail with transient P2P conditions — "no eligible store peers" (routing not yet converged on store-eligible peers), "0.00% successful" (store RPCs to peers failing under load), or a momentary "zero peers" — and the cascade register path made a single attempt, failing the whole upload. storeArtefacts now retries these transient failures with bounded backoff (4 attempts, base 2s * attempt). Retries force IdempotentDirectoryRecord so the symbol-directory row (a plain INSERT on first pass) is upserted rather than colliding; the symbol/data key stores are already idempotent by key. Deterministic errors (e.g. layout/encoding) are not retried. Added tests: transient-then-succeed (asserting retries flip to the idempotent path), non-transient-no-retry, and exhaust-cap. Co-Authored-By: Claude Opus 4.8 (1M context) --- supernode/cascade/helper.go | 73 +++++++++++- .../cascade/store_artefacts_retry_test.go | 107 ++++++++++++++++++ 2 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 supernode/cascade/store_artefacts_retry_test.go diff --git a/supernode/cascade/helper.go b/supernode/cascade/helper.go index 37d96436..c3895b92 100644 --- a/supernode/cascade/helper.go +++ b/supernode/cascade/helper.go @@ -4,6 +4,7 @@ import ( "context" "strconv" "strings" + "time" "cosmossdk.io/math" actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types" @@ -146,6 +147,32 @@ func (task *CascadeRegistrationTask) generateRQIDFiles(ctx context.Context, meta return indexIDs, allFiles, nil } +// storeArtefactsMaxAttempts / storeArtefactsRetryBackoff bound the retry on +// transient P2P store failures (see isTransientStoreErr). The base backoff is +// multiplied by the attempt number, so total added latency is bounded at a few +// seconds. +const storeArtefactsMaxAttempts = 4 + +// storeArtefactsRetryBackoff is the base inter-attempt delay (multiplied by the +// attempt number). It is a var so tests can shrink it. +var storeArtefactsRetryBackoff = 2 * time.Second + +// isTransientStoreErr reports whether a StoreArtefacts failure is a transient +// P2P condition worth retrying — typically the routing table not yet having +// converged on store-eligible peers, momentary disconnection, or store RPCs to +// peers failing under concurrent load. These recover on their own given a short +// backoff. Deterministic failures (e.g. layout/encoding errors) are not retried. +func isTransientStoreErr(err error) bool { + if err == nil { + return false + } + msg := strings.ToLower(err.Error()) + return strings.Contains(msg, "no eligible store peers") || + strings.Contains(msg, "desired success rate") || + strings.Contains(msg, "zero peers") || + strings.Contains(msg, "iterate batch store") +} + func (task *CascadeRegistrationTask) storeArtefacts(ctx context.Context, actionID string, idFiles [][]byte, symbolsDir string, layout codec.Layout, f logtrace.Fields) error { if f == nil { f = logtrace.Fields{} @@ -156,11 +183,49 @@ func (task *CascadeRegistrationTask) storeArtefacts(ctx context.Context, actionI } ctx = logtrace.CtxWithOrigin(ctx, "first_pass") logtrace.Info(ctx, "store: first-pass begin", lf) - if err := task.P2P.StoreArtefacts(ctx, adaptors.StoreArtefactsRequest{IDFiles: idFiles, SymbolsDir: symbolsDir, Layout: layout, TaskID: task.taskID, ActionID: actionID, IdempotentDirectoryRecord: f[logtrace.FieldMethod] == "PublishStagedArtefacts"}, f); err != nil { - return task.wrapErr(ctx, "failed to store artefacts", err, lf) + + req := adaptors.StoreArtefactsRequest{ + IDFiles: idFiles, + SymbolsDir: symbolsDir, + Layout: layout, + TaskID: task.taskID, + ActionID: actionID, + IdempotentDirectoryRecord: f[logtrace.FieldMethod] == "PublishStagedArtefacts", } - logtrace.Info(ctx, "store: first-pass ok", lf) - return nil + + var lastErr error + for attempt := 1; attempt <= storeArtefactsMaxAttempts; attempt++ { + err := task.P2P.StoreArtefacts(ctx, req, f) + if err == nil { + if attempt > 1 { + logtrace.Info(ctx, "store: first-pass ok after retry", logtrace.Fields{logtrace.FieldActionID: actionID, logtrace.FieldTaskID: task.taskID, "attempt": attempt}) + } else { + logtrace.Info(ctx, "store: first-pass ok", lf) + } + return nil + } + lastErr = err + if attempt >= storeArtefactsMaxAttempts || !isTransientStoreErr(err) { + break + } + // The symbol-directory row may already have been written on a prior + // attempt, so subsequent attempts must use the idempotent upsert path + // (the symbol/data key stores are idempotent by key). + req.IdempotentDirectoryRecord = true + logtrace.Warn(ctx, "store: artefact store failed; retrying", logtrace.Fields{ + logtrace.FieldActionID: actionID, + logtrace.FieldTaskID: task.taskID, + "attempt": attempt, + "max_attempts": storeArtefactsMaxAttempts, + logtrace.FieldError: err.Error(), + }) + select { + case <-ctx.Done(): + return task.wrapErr(ctx, "failed to store artefacts", ctx.Err(), lf) + case <-time.After(time.Duration(attempt) * storeArtefactsRetryBackoff): + } + } + return task.wrapErr(ctx, "failed to store artefacts", lastErr, lf) } func (task *CascadeRegistrationTask) wrapErr(ctx context.Context, msg string, err error, f logtrace.Fields) error { diff --git a/supernode/cascade/store_artefacts_retry_test.go b/supernode/cascade/store_artefacts_retry_test.go new file mode 100644 index 00000000..82c1d721 --- /dev/null +++ b/supernode/cascade/store_artefacts_retry_test.go @@ -0,0 +1,107 @@ +package cascade + +import ( + "context" + "errors" + "sync" + "testing" + "time" + + "github.com/LumeraProtocol/supernode/v2/pkg/codec" + "github.com/LumeraProtocol/supernode/v2/pkg/logtrace" + "github.com/LumeraProtocol/supernode/v2/supernode/adaptors" +) + +// fakeStoreP2P scripts StoreArtefacts to fail its first failN calls with errFn, +// then succeed. It records the IdempotentDirectoryRecord flag seen per call. +type fakeStoreP2P struct { + mu sync.Mutex + calls int + failN int + err error + gotIdempotent []bool +} + +func (f *fakeStoreP2P) StoreArtefacts(_ context.Context, req adaptors.StoreArtefactsRequest, _ logtrace.Fields) error { + f.mu.Lock() + defer f.mu.Unlock() + f.calls++ + f.gotIdempotent = append(f.gotIdempotent, req.IdempotentDirectoryRecord) + if f.calls <= f.failN { + return f.err + } + return nil +} + +func newStoreTask(p adaptors.P2PService) *CascadeRegistrationTask { + return &CascadeRegistrationTask{ + CascadeService: &CascadeService{P2P: p}, + taskID: "task-test", + } +} + +func withFastStoreBackoff(t *testing.T) { + t.Helper() + orig := storeArtefactsRetryBackoff + storeArtefactsRetryBackoff = time.Millisecond + t.Cleanup(func() { storeArtefactsRetryBackoff = orig }) +} + +func TestStoreArtefacts_RetriesTransientThenSucceeds(t *testing.T) { + withFastStoreBackoff(t) + p := &fakeStoreP2P{ + failN: 2, + err: errors.New("error storing artefacts: p2p store batch (first): iterate batch store: no eligible store peers for 100/100 keys"), + } + task := newStoreTask(p) + + err := task.storeArtefacts(context.Background(), "action-1", [][]byte{{1}}, "/tmp/symbols", codec.Layout{}, nil) + if err != nil { + t.Fatalf("expected success after transient retries, got: %v", err) + } + if p.calls != 3 { + t.Fatalf("expected 3 attempts (2 transient + 1 success), got %d", p.calls) + } + // First attempt uses the non-idempotent path; retries must force the + // idempotent directory upsert so the re-inserted symbol-dir row doesn't fail. + if p.gotIdempotent[0] { + t.Errorf("first attempt should not force IdempotentDirectoryRecord") + } + if !p.gotIdempotent[1] || !p.gotIdempotent[2] { + t.Errorf("retry attempts must force IdempotentDirectoryRecord, got %v", p.gotIdempotent) + } +} + +func TestStoreArtefacts_DoesNotRetryNonTransient(t *testing.T) { + withFastStoreBackoff(t) + p := &fakeStoreP2P{ + failN: 99, + err: errors.New("error storing artefacts: store symbol dir: bad layout"), + } + task := newStoreTask(p) + + err := task.storeArtefacts(context.Background(), "action-1", [][]byte{{1}}, "/tmp/symbols", codec.Layout{}, nil) + if err == nil { + t.Fatal("expected error for non-transient failure") + } + if p.calls != 1 { + t.Fatalf("non-transient error must not be retried, got %d attempts", p.calls) + } +} + +func TestStoreArtefacts_GivesUpAfterMaxAttempts(t *testing.T) { + withFastStoreBackoff(t) + p := &fakeStoreP2P{ + failN: 99, + err: errors.New("error storing artefacts: p2p store batch (first): iterate batch store: failed to achieve desired success rate, only: 0.00% successful"), + } + task := newStoreTask(p) + + err := task.storeArtefacts(context.Background(), "action-1", [][]byte{{1}}, "/tmp/symbols", codec.Layout{}, nil) + if err == nil { + t.Fatal("expected error after exhausting retries") + } + if p.calls != storeArtefactsMaxAttempts { + t.Fatalf("expected %d attempts, got %d", storeArtefactsMaxAttempts, p.calls) + } +} From 14bddf0e0fae6b0f413856cfe35698d0885a0b11 Mon Sep 17 00:00:00 2001 From: Andrey Kobrin Date: Tue, 9 Jun 2026 23:14:18 -0400 Subject: [PATCH 22/22] docs(changelog): record post-merge reliability & concurrency hardening (LEP-6/EVM) Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fea91247..44484366 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,16 @@ This release adds end-to-end support for Lumera's EVM-enabled chain (Cosmos EVM - **Build & release** workflow updated to produce artifacts against the EVM-enabled toolchain. - **Operator documentation:** `docs/evm-migration.md` describes the migration model, supported account types, the automatic startup flow, manual multisig procedure, and recovery scenarios. +### Reliability & concurrency hardening (post-merge) + +- **Storage-truth recovery restored.** The `v1.20.0-rc3` bump pulls in lumera audit fixes (#139/#143) so **POSTPONED** SuperNodes remain storage-truth target candidates and can recover to ACTIVE via clean PASS proofs. `rc2` had excluded them, which broke the postpone→recover lifecycle (and the LEP-6 enforcement/heal e2e tests). +- **Concurrent cascade uploads hardened** (real-binary contention path): + - **Finalize simulation** now retries a transient `account sequence mismatch` by re-fetching account info, bounded by the same cap as the broadcast path. Previously the simulate pre-check failed the whole upload on a stale-sequence false negative even though the subsequent broadcast (which already retries) would have succeeded — surfaced when one SuperNode finalizes several actions at once. + - **Artefact storage** retries transient P2P conditions — `no eligible store peers` (routing not yet converged), `0.00% successful` (store RPCs failing under load), and momentary `zero peers` — with bounded backoff, forcing the idempotent symbol-directory upsert on retries (symbol/data key stores are already idempotent by key). Deterministic errors are not retried. +- **SQLite P2P store shutdown fixed.** `Store.Close` now broadcasts the stop signal to *all* background goroutines (DB worker, WAL checkpoint worker, replication writer) and waits for them to exit before closing the database; the checkpoint worker is interruptible and bails out of its retry loop on shutdown. Fixes a goroutine leak and a WAL-write-after-close race that intermittently corrupted teardown (and flaked unit tests). +- **EVM-chain startup gate is crash-loop safe.** `requireEVMChain` distinguishes a transient module-version query failure (chain momentarily unreachable / gRPC blip → retried with backoff) from a definitive "EVM module absent" answer (fail fast), so a brief network blip at boot no longer hard-crashes the daemon. +- **Stricter EVM key validation.** The migration pre-flight gate now explicitly type-asserts `*ethsecp256k1.PubKey` instead of treating "anything that is not legacy `secp256k1`" as EVM, so multisig/offline/ledger or other non-EVM key types are rejected up front rather than failing later during signing/proof validation. + (Will be finalized on release.) ## Upcoming Release: v2.4.9