diff --git a/.github/actions/install-wasmvm/action.yml b/.github/actions/install-wasmvm/action.yml index 7e2f8076..acfd9489 100644 --- a/.github/actions/install-wasmvm/action.yml +++ b/.github/actions/install-wasmvm/action.yml @@ -5,7 +5,7 @@ inputs: description: Path to the Makefile containing WASMVM_VERSION default: Makefile version: - description: Override wasmvm version (e.g. v3.0.0-ibc2.0) + description: Override wasmvm version (e.g. v3.0.2) required: false outputs: version: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cbd79c92..abd4cc86 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6.0.1 with: fetch-depth: 0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc45617..fb3a6e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ --- +## 1.10.0 + +Changes included since `v1.9.1` (range: `v1.9.1..v1.10.0`). + +- Cosmos SDK: upgraded from v0.50.14 to v0.53.5, CometBFT upgraded to v0.38.20 +- enabled unordered +- migrated consensus params from `x/params` to `x/consensus` via baseapp.MigrateParams; removed `x/params` usage. +- IBC: upgraded to IBC-Go from v10.3.0 to v10.5.0 with IBC v2 readiness (Router v2, v2 packet/event handling helpers). +- Wasm: upgraded wasmd from v0.55.0-ibc2.0 to v0.61.6 and wasmvm from v3.0.0-ibc2.0 to v3.0.2. +- Module changes: removed `x/crisis`, deleted its store key and disabled crisis invariants by default. +- Client/indexer impact: legacy tx logs removed in SDK v0.53. +- Unordered transactions feature (SDK v0.52) is enabled: "fire-and-forget" tx submission model with timeout_timestamp as TTL/replay protection, useful for throughput-focused clients where strict ordering is not required. + +--- + ## 1.9.1 Changes included since `v1.9.0` (range: `v1.9.0..v1.9.1`). diff --git a/Makefile b/Makefile index 481897a2..821b125a 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ IGNITE_INSTALL_SCRIPT ?= https://get.ignite.com/cli! GOFLAGS = "-trimpath" -WASMVM_VERSION := v3@v3.0.0-ibc2.0 +WASMVM_VERSION := v3@v3.0.2 RELEASE_CGO_LDFLAGS ?= -Wl,-rpath,/usr/lib -Wl,--disable-new-dtags COSMOS_PROTO_VERSION := $(call module_version,github.com/cosmos/cosmos-proto) GOGOPROTO_VERSION := $(call module_version,github.com/cosmos/gogoproto) diff --git a/app/app.go b/app/app.go index 2abad273..ce049728 100644 --- a/app/app.go +++ b/app/app.go @@ -35,6 +35,7 @@ import ( servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" @@ -47,8 +48,6 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" _ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" - _ "github.com/cosmos/cosmos-sdk/x/crisis" // import for side-effects - crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" _ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -129,7 +128,6 @@ type App struct { AuthzKeeper authzkeeper.Keeper ConsensusParamsKeeper consensuskeeper.Keeper CircuitBreakerKeeper circuitkeeper.Keeper - CrisisKeeper *crisiskeeper.Keeper ParamsKeeper paramskeeper.Keeper EvidenceKeeper evidencekeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper @@ -240,7 +238,6 @@ func New( &app.MintKeeper, &app.DistrKeeper, &app.GovKeeper, - &app.CrisisKeeper, &app.UpgradeKeeper, &app.ParamsKeeper, &app.AuthzKeeper, @@ -264,6 +261,7 @@ func New( // build app app.App = appBuilder.Build(db, traceStore, baseAppOptions...) + app.SetVersion(version.Version) // register legacy modules if err := app.registerIBCModules(appOpts, wasmOpts...); err != nil { @@ -280,7 +278,6 @@ func New( app.setupUpgrades() /**** Module Options ****/ - app.ModuleManager.RegisterInvariants(app.CrisisKeeper) // create the simulation manager and define the order of the modules for deterministic simulations overrideModules := map[string]module.AppModuleSimulation{ @@ -324,12 +321,14 @@ func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { // This needs to be called BEFORE app.Load() func (app *App) setupUpgrades() { params := appParams.AppUpgradeParams{ - ChainID: app.ChainID(), - Logger: app.Logger(), - ModuleManager: app.ModuleManager, - Configurator: app.Configurator(), - ActionKeeper: &app.ActionKeeper, - SupernodeKeeper: app.SupernodeKeeper, + ChainID: app.ChainID(), + Logger: app.Logger(), + ModuleManager: app.ModuleManager, + Configurator: app.Configurator(), + ActionKeeper: &app.ActionKeeper, + SupernodeKeeper: app.SupernodeKeeper, + ParamsKeeper: &app.ParamsKeeper, + ConsensusParamsKeeper: &app.ConsensusParamsKeeper, } allUpgrades := upgrades.AllUpgrades(params) diff --git a/app/app_config.go b/app/app_config.go index ac883ea9..3d7191ca 100644 --- a/app/app_config.go +++ b/app/app_config.go @@ -14,7 +14,6 @@ import ( bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1" circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1" consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1" - crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1" distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1" evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1" feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1" @@ -54,8 +53,6 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" _ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" - _ "github.com/cosmos/cosmos-sdk/x/crisis" // import for side-effects - crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" _ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" @@ -99,7 +96,6 @@ var ( slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, - crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, @@ -155,7 +151,6 @@ var ( endBlockers = []string{ // cosmos sdk modules - crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, feegrant.ModuleName, @@ -178,6 +173,7 @@ var ( // NOTE: upgrade module is required to be prioritized preBlockers = []string{ upgradetypes.ModuleName, + authtypes.ModuleName, // this line is used by starport scaffolding # stargate/app/preBlockers } @@ -239,6 +235,9 @@ var ( Config: appconfig.WrapAny(&authmodulev1.Module{ Bech32Prefix: lcfg.AccountAddressPrefix, ModuleAccountPermissions: moduleAccPerms, + // Cosmos SDK 0.53.x new feature - unordered transactions + // "Fire-and-forget" submission model with timeout_timestamp as TTL/replay protection + EnableUnorderedTransactions: true, // By default modules authority is the governance module. This is configurable with the following: // Authority: "group", // A custom module authority can be set using a module name // Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address @@ -314,10 +313,6 @@ var ( Name: govtypes.ModuleName, Config: appconfig.WrapAny(&govmodulev1.Module{}), }, - { - Name: crisistypes.ModuleName, - Config: appconfig.WrapAny(&crisismodulev1.Module{}), - }, { Name: consensustypes.ModuleName, Config: appconfig.WrapAny(&consensusmodulev1.Module{}), diff --git a/app/export.go b/app/export.go index e6934aa3..28a217a7 100644 --- a/app/export.go +++ b/app/export.go @@ -69,8 +69,7 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str allowedAddrsMap[addr] = true } - /* Just to be safe, assert the invariants on current state. */ - app.CrisisKeeper.AssertInvariants(ctx) + // NOTE: x/crisis is removed, so invariants are not asserted here. /* Handle fee distribution state. */ diff --git a/app/ibc.go b/app/ibc.go index 0f89f3d9..11be8939 100644 --- a/app/ibc.go +++ b/app/ibc.go @@ -140,7 +140,7 @@ func (app *App) registerIBCModules( ibcRouterV2 := ibcapi.NewRouter() // Wasm module - wasmStackIBCHandler, err := app.registerWasmModules(appOpts, ibcRouterV2, wasmOpts...) + wasmStackIBCHandler, err := app.registerWasmModules(appOpts, wasmOpts...) if err != nil { return err } @@ -224,7 +224,17 @@ func (app *App) registerIBCModules( app.ibcRouter = ibcRouter ibcRouterV2 = ibcRouterV2. - AddRoute(ibctransfertypes.PortID, ibcv2transferStack) + AddRoute(ibctransfertypes.PortID, ibcv2transferStack). + AddPrefixRoute(wasmkeeper.PortIDPrefixV2, wasmkeeper.NewIBC2Handler(app.WasmKeeper)) + + // Additional IBC v2 modules can be registered here. + if v := appOpts.Get(IBCModuleRegisterFnOptionV2); v != nil { + if registerFn, ok := v.(func(router *ibcapi.Router)); ok { + registerFn(ibcRouterV2) + } else { + return errors.New("invalid IBC v2 module register function option") + } + } app.IBCKeeper.SetRouterV2(ibcRouterV2) clientKeeper := app.IBCKeeper.ClientKeeper diff --git a/app/options.go b/app/options.go index 143ac324..6345c911 100644 --- a/app/options.go +++ b/app/options.go @@ -2,12 +2,15 @@ package app import ( ibcporttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" + ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api" ) const ( - IBCModuleRegisterFnOption = "ibc_module_register_fn" + IBCModuleRegisterFnOption = "ibc_module_register_fn" + IBCModuleRegisterFnOptionV2 = "ibc_module_register_fn_v2" - FlagWasmHomeDir = "wasm-homedir" + FlagWasmHomeDir = "wasm-homedir" ) type IBCModuleRegisterFn func(router *ibcporttypes.Router) +type IBCModuleRegisterFnV2 func(router *ibcapi.Router) diff --git a/app/sim_bench_test.go b/app/sim_bench_test.go index f2e4ff92..a4c1866c 100644 --- a/app/sim_bench_test.go +++ b/app/sim_bench_test.go @@ -1,11 +1,9 @@ package app_test import ( - "fmt" "os" "testing" - cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -53,7 +51,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { bApp.BaseApp, simtestutil.AppStateFn(bApp.AppCodec(), bApp.SimulationManager(), bApp.DefaultGenesis()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(bApp, bApp.AppCodec(), config, bApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), @@ -109,7 +107,7 @@ func BenchmarkInvariants(b *testing.B) { bApp.BaseApp, simtestutil.AppStateFn(bApp.AppCodec(), bApp.SimulationManager(), bApp.DefaultGenesis()), simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(bApp, bApp.AppCodec(), config, bApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), @@ -128,21 +126,6 @@ func BenchmarkInvariants(b *testing.B) { simtestutil.PrintStats(db) } - ctx := bApp.NewContextLegacy(true, cmtproto.Header{Height: bApp.LastBlockHeight() + 1}) - - // 3. Benchmark each invariant separately - // - // NOTE: We use the crisis keeper as it has all the invariants registered with - // their respective metadata which makes it useful for testing/benchmarking. - for _, cr := range bApp.CrisisKeeper.Routes() { - cr := cr - b.Run(fmt.Sprintf("%s/%s", cr.ModuleName, cr.Route), func(b *testing.B) { - if res, stop := cr.Invar(ctx); stop { - b.Fatalf( - "broken invariant at block %d of %d\n%s", - ctx.BlockHeight()-1, config.NumBlocks, res, - ) - } - }) - } + // NOTE: x/crisis is removed, so invariant benchmarks are not available. + b.Skip("x/crisis disabled; invariants benchmark not available") } diff --git a/app/sim_test.go b/app/sim_test.go index 09b1239c..e727bc2f 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -99,7 +99,7 @@ func BenchmarkSimulation(b *testing.B) { bApp.BaseApp, simtestutil.AppStateFn(bApp.AppCodec(), bApp.SimulationManager(), bApp.DefaultGenesis()), simulationtypes.RandomAccounts, - simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(bApp, bApp.AppCodec(), config, bApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), @@ -144,7 +144,7 @@ func TestAppImportExport(t *testing.T) { bApp.BaseApp, simtestutil.AppStateFn(bApp.AppCodec(), bApp.SimulationManager(), bApp.DefaultGenesis()), simulationtypes.RandomAccounts, - simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(bApp, bApp.AppCodec(), config, bApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), @@ -267,7 +267,7 @@ func TestAppSimulationAfterImport(t *testing.T) { bApp.BaseApp, simtestutil.AppStateFn(bApp.AppCodec(), bApp.SimulationManager(), bApp.DefaultGenesis()), simulationtypes.RandomAccounts, - simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(bApp, bApp.AppCodec(), config, bApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), @@ -318,7 +318,7 @@ func TestAppSimulationAfterImport(t *testing.T) { newApp.BaseApp, simtestutil.AppStateFn(bApp.AppCodec(), bApp.SimulationManager(), bApp.DefaultGenesis()), simulationtypes.RandomAccounts, - simtestutil.SimulationOperations(newApp, newApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(newApp, newApp.AppCodec(), config, newApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), @@ -404,7 +404,7 @@ func TestAppStateDeterminism(t *testing.T) { bApp.DefaultGenesis(), ), simulationtypes.RandomAccounts, - simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + simtestutil.BuildSimulationOperations(bApp, bApp.AppCodec(), config, bApp.TxConfig()), app.BlockedAddresses(), config, bApp.AppCodec(), diff --git a/app/test_helpers.go b/app/test_helpers.go index a7de7062..05f4cdb8 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -15,6 +15,8 @@ import ( "cosmossdk.io/log" sdkmath "cosmossdk.io/math" pruningtypes "cosmossdk.io/store/pruning/types" + "cosmossdk.io/store/snapshots" + snapshottypes "cosmossdk.io/store/snapshots/types" abci "github.com/cometbft/cometbft/abci/types" cmttypes "github.com/cometbft/cometbft/types" @@ -47,9 +49,11 @@ import ( wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" ibcporttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" + ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api" lcfg "github.com/LumeraProtocol/lumera/config" ibcmock "github.com/LumeraProtocol/lumera/tests/ibctesting/mock" + mockv2 "github.com/LumeraProtocol/lumera/tests/ibctesting/mock/v2" claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" ) @@ -93,7 +97,6 @@ func NewTestApp( &app.SlashingKeeper, &app.MintKeeper, &app.GovKeeper, - &app.CrisisKeeper, &app.UpgradeKeeper, &app.ParamsKeeper, &app.AuthzKeeper, @@ -197,6 +200,8 @@ func setup(t testing.TB, chainID string, withGenesis bool, invCheckPeriod uint, require.NoError(t, err) t.Cleanup(func() { snapshotDB.Close() }) require.NoError(t, err) + snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) + require.NoError(t, err) appOptions := make(simtestutil.AppOptionsMap, 0) appOptions[flags.FlagHome] = nodeHome // ensure unique folder @@ -206,8 +211,21 @@ func setup(t testing.TB, chainID string, withGenesis bool, invCheckPeriod uint, // Register the mock IBC module for testing ibcRouter.AddRoute(MockPort, ibcmock.NewMockIBCModule(nil, MockPort)) } + appOptions[IBCModuleRegisterFnOptionV2] = func(ibcRouter *ibcapi.Router) { + ibcRouter.AddRoute(mockv2.PortIDA, mockv2.NewIBCModule()) + ibcRouter.AddRoute(mockv2.PortIDB, mockv2.NewIBCModule()) + } - app := New(log.NewNopLogger(), db, nil, true, appOptions, wasmOpts, bam.SetChainID(chainID)) + app := New( + log.NewNopLogger(), + db, + nil, + true, + appOptions, + wasmOpts, + bam.SetChainID(chainID), + bam.SetSnapshot(snapshotStore, snapshottypes.SnapshotOptions{KeepRecent: 2}), + ) if withGenesis { return app, app.DefaultGenesis() } diff --git a/app/upgrades/params/params.go b/app/upgrades/params/params.go index 4b22ca68..5c48e408 100644 --- a/app/upgrades/params/params.go +++ b/app/upgrades/params/params.go @@ -3,6 +3,8 @@ package params import ( "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/types/module" + consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" actionmodulekeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper" sntypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types" @@ -18,6 +20,8 @@ type AppUpgradeParams struct { // Keepers required by custom upgrade handlers. These are populated by the app // at startup (before state load) so upgrade handlers can safely perform // bespoke store migrations beyond RunMigrations. - ActionKeeper *actionmodulekeeper.Keeper - SupernodeKeeper sntypes.SupernodeKeeper + ActionKeeper *actionmodulekeeper.Keeper + SupernodeKeeper sntypes.SupernodeKeeper + ParamsKeeper *paramskeeper.Keeper + ConsensusParamsKeeper *consensuskeeper.Keeper } diff --git a/app/upgrades/upgrades.go b/app/upgrades/upgrades.go index 363ba60a..135c6bc0 100644 --- a/app/upgrades/upgrades.go +++ b/app/upgrades/upgrades.go @@ -15,21 +15,23 @@ import ( upgrade_v1_8_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_0" upgrade_v1_8_4 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_4" upgrade_v1_9_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_9_0" + upgrade_v1_10_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_10_0" ) -// ====================================================================================================================== +// ================================================================================================================================= // Upgrade overview: -// ====================================================================================================================== -// | Name | Handler | Store changes | Notes -// | v1.6.1 | custom | none | Adds action module consensus version after migrations -// | v1.7.0 | standard | none | Migrations only -// | v1.7.2 | standard | none | Migrations only -// | v1.8.0 | standard | testnet/devnet: add PFM, drop NFT | Store upgrade gated to non-mainnet; handler is migrations only -// | v1.8.4 | standard | mainnet: add PFM, drop NFT | Store upgrade gated to mainnet; handler is migrations only -// | v1.8.5 | standard | none | Migrations only -// | v1.9.0 | custom | none | Backfills action/supernode secondary indices -// | v1.9.1 | standard | none | Migrations only -// ====================================================================================================================== +// ================================================================================================================================= +// | Name | Handler | Store changes | Notes +// | v1.6.1 | custom | none | Adds action module consensus version after migrations +// | v1.7.0 | standard | none | Migrations only +// | v1.7.2 | standard | none | Migrations only +// | v1.8.0 | standard | testnet/devnet: add PFM, drop NFT | Store upgrade gated to non-mainnet; handler is migrations only +// | v1.8.4 | standard | mainnet: add PFM, drop NFT | Store upgrade gated to mainnet; handler is migrations only +// | v1.8.5 | standard | none | Migrations only +// | v1.9.0 | custom | none | Backfills action/supernode secondary indices +// | v1.9.1 | standard | none | Migrations only +// | v1.10.0 | custom | drop crisis | Migrate consensus params from x/params to x/consensus; remove x/crisis +// ================================================================================================================================= type UpgradeConfig struct { StoreUpgrade *storetypes.StoreUpgrades @@ -44,6 +46,7 @@ const ( upgradeNameV191 = "v1.9.1" ) +// List of all known upgrade names, in chronological order. var upgradeNames = []string{ upgrade_v1_6_1.UpgradeName, upgradeNameV170, @@ -53,6 +56,7 @@ var upgradeNames = []string{ upgradeNameV185, upgrade_v1_9_0.UpgradeName, upgradeNameV191, + upgrade_v1_10_0.UpgradeName, } var NoUpgradeConfig = UpgradeConfig{ @@ -107,6 +111,11 @@ func SetupUpgrades(upgradeName string, params appParams.AppUpgradeParams) (Upgra return UpgradeConfig{ Handler: standardUpgradeHandler(upgradeNameV191, params), }, true + case upgrade_v1_10_0.UpgradeName: + return UpgradeConfig{ + StoreUpgrade: &upgrade_v1_10_0.StoreUpgrades, + Handler: upgrade_v1_10_0.CreateUpgradeHandler(params), + }, true // add future upgrades here default: diff --git a/app/upgrades/upgrades_test.go b/app/upgrades/upgrades_test.go index 9231d7aa..5cba46e0 100644 --- a/app/upgrades/upgrades_test.go +++ b/app/upgrades/upgrades_test.go @@ -15,7 +15,9 @@ import ( upgrade_v1_8_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_0" upgrade_v1_8_4 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_4" upgrade_v1_9_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_9_0" + upgrade_v1_10_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_10_0" actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" ) func TestUpgradeNamesOrder(t *testing.T) { @@ -28,6 +30,7 @@ func TestUpgradeNamesOrder(t *testing.T) { upgradeNameV185, upgrade_v1_9_0.UpgradeName, upgradeNameV191, + upgrade_v1_10_0.UpgradeName, } require.Equal(t, expected, upgradeNames, "upgradeNames should stay in ascending order") } @@ -63,13 +66,17 @@ func TestSetupUpgradesAndHandlers(t *testing.T) { "store upgrade presence mismatch for %s on %s", upgradeName, tt.chainID, ) + if upgradeName == upgrade_v1_10_0.UpgradeName && config.StoreUpgrade != nil { + require.Contains(t, config.StoreUpgrade.Deleted, crisistypes.StoreKey, "v1.10.0 should delete crisis store key") + } + if config.Handler == nil { continue } // v1.9.0 requires full keeper wiring; exercising it here would require // a full app harness. This test only verifies registration and gating. - if upgradeName == upgrade_v1_9_0.UpgradeName { + if upgradeName == upgrade_v1_9_0.UpgradeName || upgradeName == upgrade_v1_10_0.UpgradeName { continue } @@ -82,6 +89,7 @@ func TestSetupUpgradesAndHandlers(t *testing.T) { _, ok := vm[actiontypes.ModuleName] require.True(t, ok, "v1.6.1 should set action module version") } + } }) } @@ -111,6 +119,8 @@ func expectStoreUpgrade(upgradeName, chainID string) bool { return IsTestnet(chainID) || IsDevnet(chainID) case upgrade_v1_8_4.UpgradeName: return IsMainnet(chainID) + case upgrade_v1_10_0.UpgradeName: + return true default: return false } diff --git a/app/upgrades/v1_10_0/store.go b/app/upgrades/v1_10_0/store.go new file mode 100644 index 00000000..b26804f9 --- /dev/null +++ b/app/upgrades/v1_10_0/store.go @@ -0,0 +1,11 @@ +package v1_10_0 + +import ( + storetypes "cosmossdk.io/store/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" +) + +// StoreUpgrades defines store changes for v1.10.0. +var StoreUpgrades = storetypes.StoreUpgrades{ + Deleted: []string{crisistypes.StoreKey}, +} diff --git a/app/upgrades/v1_10_0/upgrade.go b/app/upgrades/v1_10_0/upgrade.go new file mode 100644 index 00000000..f8b36533 --- /dev/null +++ b/app/upgrades/v1_10_0/upgrade.go @@ -0,0 +1,52 @@ +package v1_10_0 + +import ( + "context" + "fmt" + + upgradetypes "cosmossdk.io/x/upgrade/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + + appParams "github.com/LumeraProtocol/lumera/app/upgrades/params" +) + +// UpgradeName is the on-chain name used for this upgrade. +const UpgradeName = "v1.10.0" + +// CreateUpgradeHandler migrates consensus params from x/params to x/consensus +// and then runs module migrations. +func CreateUpgradeHandler(p appParams.AppUpgradeParams) upgradetypes.UpgradeHandler { + return func(goCtx context.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + p.Logger.Info(fmt.Sprintf("Starting upgrade %s...", UpgradeName)) + + ctx := sdk.UnwrapSDKContext(goCtx) + + if p.ParamsKeeper == nil || p.ConsensusParamsKeeper == nil { + return nil, fmt.Errorf("%s upgrade requires ParamsKeeper and ConsensusParamsKeeper", UpgradeName) + } + + // Use the legacy baseapp paramspace to read existing consensus params from x/params. + // This is required for in-place upgrades where consensus params were historically stored in x/params. + legacySubspace := p.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()) + // Migrate consensus params into x/consensus (ConsensusParamsKeeper), which is collections-backed in v0.53+. + if err := baseapp.MigrateParams(ctx, legacySubspace, p.ConsensusParamsKeeper.ParamsStore); err != nil { + return nil, fmt.Errorf("failed to migrate consensus params: %w", err) + } + + // Run all module migrations after consensus params have been moved. + p.Logger.Info("Running module migrations...") + newVM, err := p.ModuleManager.RunMigrations(ctx, p.Configurator, fromVM) + if err != nil { + p.Logger.Error("Failed to run migrations", "error", err) + return nil, fmt.Errorf("failed to run migrations: %w", err) + } + p.Logger.Info("Module migrations completed.") + + p.Logger.Info(fmt.Sprintf("Successfully completed upgrade %s", UpgradeName)) + return newVM, nil + } +} diff --git a/app/wasm.go b/app/wasm.go index 7c41fb47..1f661aab 100644 --- a/app/wasm.go +++ b/app/wasm.go @@ -18,7 +18,6 @@ import ( distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/gogoproto/proto" - ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api" ) func uint32Ptr(v uint32) *uint32 { @@ -28,7 +27,6 @@ func uint32Ptr(v uint32) *uint32 { // registerWasmModules register CosmWasm keepers and non dependency inject modules. func (app *App) registerWasmModules( appOpts servertypes.AppOptions, - ibcRouterV2 *ibcapi.Router, wasmOpts ...wasmkeeper.Option, ) (*wasm.IBCHandler, error) { // set up non depinject support modules store keys @@ -74,6 +72,7 @@ func (app *App) registerWasmModules( distrkeeper.NewQuerier(app.DistrKeeper), app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, + app.IBCKeeper.ChannelKeeperV2, app.TransferKeeper, app.MsgServiceRouter(), app.GRPCQueryRouter(), @@ -82,7 +81,6 @@ func (app *App) registerWasmModules( vmConfig, capabilities, authority, - ibcRouterV2, wasmOpts..., ) app.WasmKeeper = &wasmKeeper @@ -133,7 +131,9 @@ func (app *App) registerWasmModules( wasmStackIBCHandler := wasm.NewIBCHandler( app.WasmKeeper, app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.ChannelKeeper) + app.TransferKeeper, + app.IBCKeeper.ChannelKeeper, + ) return &wasmStackIBCHandler, nil } diff --git a/cmd/lumera/cmd/commands.go b/cmd/lumera/cmd/commands.go index 48e58400..ee70a253 100644 --- a/cmd/lumera/cmd/commands.go +++ b/cmd/lumera/cmd/commands.go @@ -23,7 +23,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/CosmWasm/wasmd/x/wasm" @@ -66,7 +65,6 @@ func initRootCmd( } func addModuleInitFlags(startCmd *cobra.Command) { - crisis.AddModuleInitFlags(startCmd) wasm.AddModuleInitFlags(startCmd) } diff --git a/cmd/lumera/cmd/root.go b/cmd/lumera/cmd/root.go index 9c3177b0..4c00b16a 100644 --- a/cmd/lumera/cmd/root.go +++ b/cmd/lumera/cmd/root.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth/tx" authtxconfig "github.com/cosmos/cosmos-sdk/x/auth/tx/config" "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -32,6 +33,9 @@ import ( // NewRootCmd creates a new root command for lumera. It is called once in the main function. func NewRootCmd() *cobra.Command { + // Ensure SDK placeholders use the Lumera daemon name. + version.AppName = app.Name + "d" + var ( autoCliOpts autocli.AppOptions moduleBasicManager module.BasicManager diff --git a/cmd/lumera/cmd/testnet.go b/cmd/lumera/cmd/testnet.go index bf51ed31..ce96c1f3 100644 --- a/cmd/lumera/cmd/testnet.go +++ b/cmd/lumera/cmd/testnet.go @@ -36,7 +36,6 @@ import ( "github.com/cosmos/cosmos-sdk/version" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -244,6 +243,12 @@ func initTestnetFiles( nodeIDs := make([]string, args.numValidators) valPubKeys := make([]cryptotypes.PubKey, args.numValidators) + // Disable state sync for local testnets. + nodeConfig.StateSync.Enable = false + nodeConfig.StateSync.RPCServers = nil + nodeConfig.StateSync.TrustHeight = 0 + nodeConfig.StateSync.TrustHash = "" + appConfig := srvconfig.DefaultConfig() appConfig.MinGasPrices = args.minGasPrices appConfig.API.Enable = true @@ -487,14 +492,6 @@ func initGenFiles( } appGenState[govtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&govGenState) - // set the crisis module constant fee denom - var crisisGenState crisistypes.GenesisState - clientCtx.Codec.MustUnmarshalJSON(appGenState[crisistypes.ModuleName], &crisisGenState) - if crisisGenState.ConstantFee.Amount.IsPositive() || crisisGenState.ConstantFee.Denom != "" { - crisisGenState.ConstantFee = sdk.NewCoin(lcfg.ChainDenom, crisisGenState.ConstantFee.Amount) - } - appGenState[crisistypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&crisisGenState) - // set the accounts in the genesis state var authGenState authtypes.GenesisState clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState) diff --git a/config/config.go b/config/config.go index 3c458a3f..83c7d3f4 100644 --- a/config/config.go +++ b/config/config.go @@ -43,6 +43,9 @@ func SetupConfig() { // Set and seal config config := sdk.GetConfig() + // Keep SDK fallback in sync with chain denom. + sdk.DefaultBondDenom = ChainDenom + // Set the chain coin type config.SetCoinType(ChainCoinType) diff --git a/devnet/go.mod b/devnet/go.mod index 46cdb225..447afd22 100644 --- a/devnet/go.mod +++ b/devnet/go.mod @@ -7,7 +7,6 @@ replace ( // Comment lines with github.com/LumeraProtocol/ before releasing // github.com/LumeraProtocol/lumera => .. //github.com/LumeraProtocol/sdk-go => ../../sdk-go - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.50.14 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 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 @@ -19,19 +18,19 @@ require ( cosmossdk.io/math v1.5.3 github.com/LumeraProtocol/lumera v1.9.1 github.com/LumeraProtocol/sdk-go v1.0.6 - github.com/cosmos/cosmos-sdk v0.53.0 - github.com/cosmos/ibc-go/v10 v10.3.0 + github.com/cosmos/cosmos-sdk v0.53.5 + github.com/cosmos/ibc-go/v10 v10.5.0 github.com/stretchr/testify v1.11.1 go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cosmossdk.io/collections v1.3.0 // indirect + cosmossdk.io/collections v1.3.1 // indirect cosmossdk.io/core v0.11.3 // indirect - cosmossdk.io/depinject v1.2.0 // indirect + cosmossdk.io/depinject v1.2.1 // indirect cosmossdk.io/errors v1.0.2 // indirect - cosmossdk.io/log v1.6.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/tx v0.14.0 // indirect @@ -48,8 +47,8 @@ require ( 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.1 // indirect - github.com/bytedance/sonic/loader v0.3.0 // 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 @@ -59,23 +58,23 @@ 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.18 // 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.2 // indirect + github.com/cosmos/cosmos-db v1.1.3 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.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.0 // indirect + github.com/cosmos/gogoproto v1.7.2 // indirect github.com/cosmos/iavl v1.2.4 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.14.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.1.1 // indirect + 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 @@ -84,7 +83,7 @@ require ( 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.32.0 // indirect + github.com/getsentry/sentry-go v0.35.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 @@ -93,8 +92,7 @@ require ( github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.5 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // 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 @@ -140,10 +138,10 @@ require ( 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.22.0 // indirect + github.com/prometheus/client_golang v1.23.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.65.0 // indirect + github.com/prometheus/procfs v0.16.1 // 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 @@ -161,14 +159,16 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.14.3 // indirect + github.com/zondax/ledger-go v1.0.1 // indirect go.etcd.io/bbolt v1.4.0-alpha.1 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/arch v0.15.0 // indirect + golang.org/x/arch v0.17.0 // indirect golang.org/x/crypto v0.43.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect @@ -176,7 +176,7 @@ require ( golang.org/x/sys v0.37.0 // indirect golang.org/x/term v0.36.0 // indirect golang.org/x/text v0.30.0 // indirect - google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // 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/grpc v1.77.0 // indirect @@ -186,5 +186,5 @@ require ( lukechampine.com/blake3 v1.4.1 // indirect nhooyr.io/websocket v1.8.17 // indirect pgregory.net/rapid v1.2.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/devnet/go.sum b/devnet/go.sum index 3634f9d3..ded2db5a 100644 --- a/devnet/go.sum +++ b/devnet/go.sum @@ -21,8 +21,8 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW 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.0 h1:Pd8P1s9WkcrBE2n/PhAwKsdrR35V3Sg2II9B+ndM3CU= -cloud.google.com/go/auth v0.16.0/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +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/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= @@ -31,7 +31,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.37.0 h1:XxtZlXYkZXub3LNaLu90TTemcFqIU1yZ4E4q9VlR39A= +cloud.google.com/go/compute v1.38.0 h1:MilCLYQW2m7Dku8hRIIKo4r0oKastlD74sSu16riYKs= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -56,16 +56,16 @@ 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.8.0.20250402172810-41e3e9d004a1 h1:nlMUeKu6CGrO7Gxt5S31qT3g27CHmBJHsZPjqHApVTI= cosmossdk.io/client/v2 v2.0.0-beta.8.0.20250402172810-41e3e9d004a1/go.mod h1:xgv0ejeOk5yeDraPW5tv+PfBkCDt4yYa/+u45MyP+bM= -cosmossdk.io/collections v1.3.0 h1:RUY23xXBy/bu5oSHZ5y+mkJRyA4ZboKDO4Yvx4+g2uc= -cosmossdk.io/collections v1.3.0/go.mod h1:cqVpBMDGEYhuNmNSXIOmqpnQ7Eav43hpJIetzLuEkns= +cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= +cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= 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.0 h1:6NW/FSK1IkWTrX7XxUpBmX1QMBozpEI9SsWkKTBc5zw= -cosmossdk.io/depinject v1.2.0/go.mod h1:pvitjtUxZZZTQESKNS9KhGjWVslJZxtO9VooRJYyPjk= +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/log v1.6.0 h1:SJIOmJ059wi1piyRgNRXKXhlDXGqnB5eQwhcZKv2tOk= -cosmossdk.io/log v1.6.0/go.mod h1:5cXXBvfBkR2/BcXmosdCSLXllvgSjphrrDVdfVRmBGM= +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= cosmossdk.io/math v1.5.3/go.mod h1:uqcZv7vexnhMFJF+6zh9EWdm/+Ylyln34IvPnBauPCQ= cosmossdk.io/schema v1.1.0 h1:mmpuz3dzouCoyjjcMcA/xHBEmMChN+EHh8EHxHRHhzE= @@ -158,10 +158,10 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E= github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= -github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +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/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.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= @@ -172,10 +172,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.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= -github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +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/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= @@ -227,8 +227,8 @@ 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.18 h1:1ZHYMdu0S75YxFM13LlPXnOwiIpUW5z9TKMQtTIALpw= -github.com/cometbft/cometbft v0.38.18/go.mod h1:PlOQgf3jQorep+g6oVnJgtP65TJvBJoLiXjGaMdNxBE= +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-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/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -239,29 +239,29 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.1.2 h1:KZm4xLlPp6rLkyIOmPOhh+XDK9oH1++pNH/csLdX0Dk= -github.com/cosmos/cosmos-db v1.1.2/go.mod h1:dMg2gav979Ig2N076POEw4CEKbCsieaOfDWSfFZxs8M= +github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= +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.50.14 h1:G8CtGHFWbExa+ZpVOVAb4kFmko/R30igsYOwyzRMtgY= -github.com/cosmos/cosmos-sdk v0.50.14/go.mod h1:hrWEFMU1eoXqLJeE6VVESpJDQH67FS1nnMrQIjO2daw= +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/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= -github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= +github.com/cosmos/gogoproto v1.7.2 h1:5G25McIraOC0mRFv9TVO139Uh3OklV2hczr13KKVHCA= +github.com/cosmos/gogoproto v1.7.2/go.mod h1:8S7w53P1Y1cHwND64o0BnArT6RmdgIvsBuco6uTllsk= github.com/cosmos/iavl v1.2.4 h1:IHUrG8dkyueKEY72y92jajrizbkZKPZbMmG14QzsEkw= github.com/cosmos/iavl v1.2.4/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10 v10.1.0 h1:epKcbFAeWRRw1i1jZnYzLIEm9sgUPaL1RftuRjjUKGw= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10 v10.1.0/go.mod h1:S4ZQwf5/LhpOi8JXSAese/6QQDk87nTdicJPlZ5q9UQ= -github.com/cosmos/ibc-go/v10 v10.3.0 h1:w5DkHih8qn15deAeFoTk778WJU+xC1krJ5kDnicfUBc= -github.com/cosmos/ibc-go/v10 v10.3.0/go.mod h1:CthaR7n4d23PJJ7wZHegmNgbVcLXCQql7EwHrAXnMtw= +github.com/cosmos/ibc-go/v10 v10.5.0 h1:NI+cX04fXdu9JfP0V0GYeRi1ENa7PPdq0BYtVYo8Zrs= +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.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= -github.com/cosmos/ledger-cosmos-go v0.14.0/go.mod h1:E07xCWSBl3mTGofZ2QnL4cIUzMbbGVyik84QYKbX3RA= +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/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/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -281,12 +281,11 @@ github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs= github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= +github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM= github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -296,7 +295,6 @@ github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vma github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= @@ -337,8 +335,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.32.0 h1:YKs+//QmwE3DcYtfKRH8/KyOOF/I6Qnx7qYGNHCGmCY= -github.com/getsentry/sentry-go v0.32.0/go.mod h1:CYNcMMz73YigoHljQRG+qPF+eMq8gG72XcGN/p71BAY= +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/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= @@ -400,14 +398,12 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -458,7 +454,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -492,8 +487,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= -github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= +github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -587,8 +582,8 @@ 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/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= -github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +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= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -641,8 +636,8 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/linxGnu/grocksdb v1.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs= github.com/linxGnu/grocksdb v1.9.8/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LFV4wIZuHk= github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -699,8 +694,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -771,8 +766,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= +github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -788,8 +783,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.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= 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= @@ -797,8 +792,8 @@ 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.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= 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= @@ -875,6 +870,8 @@ 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.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= @@ -903,10 +900,12 @@ 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/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= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= -github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +github.com/zondax/ledger-go v1.0.1 h1:Ks/2tz/dOF+dbRynfZ0dEhcdL1lqw43Sa0zMXHpQ3aQ= +github.com/zondax/ledger-go v1.0.1/go.mod h1:j7IgMY39f30apthJYMd1YsHZRqdyu4KbVmUp0nU78X0= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.4.0-alpha.1 h1:3yrqQzbRRPFPdOMWS/QQIVxVnzSkAZQYeWlZFv1kbj4= go.etcd.io/bbolt v1.4.0-alpha.1/go.mod h1:S/Z/Nm3iuOnyO1W4XuFfPci51Gj6F1Hv0z8hisyYYOw= @@ -925,8 +924,8 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ 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/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +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= @@ -960,10 +959,12 @@ 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/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.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +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-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= @@ -1179,7 +1180,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1222,8 +1222,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb 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= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1311,8 +1311,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.229.0 h1:p98ymMtqeJ5i3lIBMj5MpR9kzIIgzpHHh8vQ+vgAzx8= -google.golang.org/api v0.229.0/go.mod h1:wyDfmq5g1wYJWn29O22FDWN48P7Xcz0xz+LBpptYvB0= +google.golang.org/api v0.247.0 h1:tSd/e0QrUlLsrwMKmkbQhYVa109qIintOls2Wh6bngc= +google.golang.org/api v0.247.0/go.mod h1:r1qZOPmxXffXg6xS5uhx16Fa/UFY8QU/K4bfKrnvovM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1363,8 +1363,8 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78= -google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= +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= @@ -1463,6 +1463,6 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/docs/lumeraid/ibc.md b/docs/lumeraid/ibc.md index 058b7315..5b577875 100644 --- a/docs/lumeraid/ibc.md +++ b/docs/lumeraid/ibc.md @@ -1,251 +1,16 @@ -# Proposal: Upgrading Lumera IBC to v2 (ibc-go v10) and Cross-Chain Service Integration +# Benefits of Upgrading IBC for Lumera -## Background and Rationale +## Benefits of upgrading to IBC v2 (IBC-Go v10) -Lumera’s blockchain currently uses the Cosmos **IBC-Go v8** implementation (IBC spec v1) for inter-chain communication. We propose upgrading to **IBC-Go v10** which introduces **IBC v2** support, while retaining backward compatibility with IBC v1 (classic). IBC v2 (launching with Cosmos SDK 0.50) significantly simplifies the IBC protocol without sacrificing functionality. By upgrading, Lumera can leverage improved cross-chain composability, more flexible packet handling, and better performance for interchain interactions. This upgrade will position Lumera to connect more easily with diverse blockchains (Cosmos chains and beyond) and to expose its unique services (Cascade, Sense, Inference, NFT metadata) to the broader interchain ecosystem. +- **Backward compatibility**: Keep IBC v1 channels while enabling IBC v2, so Lumera can upgrade without forcing counterparties to move immediately. +- **Simplified handshakes**: Reduce connection and channel setup time, lowering relayer overhead and speeding new integrations. +- **Unified routing**: Support multiple Lumera services (Cascade, Sense, Inference, NFT metadata) over a single connection, improving composability and reducing channel sprawl. +- **Payload flexibility**: Allow app-specific encodings and multi-action workflows (e.g., payment + service request in one flow) with less protocol friction. +- **Faster feature adoption**: Enable ICA, queries, and cross-chain calls without reworking the IBC stack as new apps are added. +- **Lower maintenance risk**: Trim the IBC module stack, reducing upgrade risk during the Cosmos SDK 0.53.5 transition while improving long-term scalability. -Key motivations for the upgrade include: +## Benefits of upgrading to IBC-Go v10.5.0 -- **Enhanced Cross-Chain Compatibility**: IBC v2 reduces handshake complexity, making it easier to connect with non-Cosmos ecosystems (e.g. Ethereum, Solana). This broadens Lumera’s potential integration partners. -- **Future-Proofing**: Aligning with the latest interchain standards ensures Lumera remains compatible with upcoming Cosmos SDK improvements and IBC features (like cross-chain smart contract calls). -- **Facilitating New Services**: IBC v2’s design is more accommodating to custom application protocols, which is critical for Lumera to offer storage, AI, and NFT services over IBC channels. - -In summary, upgrading to IBC-Go v10 (IBC v2) will modernize Lumera’s interop layer, simplify cross-chain interactions, and enable Lumera to act as a provider of advanced interchain services. - -## Technical Upgrade Plan (IBC-Go v8 to v10) - -Upgrading the IBC module requires careful changes to Lumera’s codebase and configuration. Below we detail the specific technical steps and modifications needed for moving from ibc-go v8 (IBC v1) to ibc-go v10 (IBC v2): - -### Dependency and Module Updates - -- **Bump IBC-Go Version**: Update Lumera’s Go modules to use ibc-go/v10 (replacing any v8 references). -- **Remove Capability Module**: IBC v2 no longer uses the Cosmos SDK Capability keeper for channel scoping. We will remove the capabilitykeeper from the app, including any scoped keepers for IBC ports. This cleans up app.go by dropping the CapabilityKeeper and all Scoped*Keeper instances related to IBC. -- **Remove Legacy Client Proposal Handler**: Eliminate the registration of the legacy 02-Client proposal handler in governance. In app.go, the upgrade client proposal route (used for updating IBC clients in IBC v1) should be removed, as IBC v2 handles client updates differently. -- **Integrate New Light Clients**: Register the updated light client modules with the IBC client keeper. For example, instantiate the Tendermint light client module via ibctm.NewLightClientModule and add it to the client router. Do the same for any other client types in use (e.g., 08-wasm if Lumera supports Wasm-based clients). This ensures Lumera’s IBC can support the new client abstractions (and any future clients like Ethereum light clients). -- **IBC Module Interface Changes**: Update any IBC keeper constructor calls to match new function signatures in v10. For instance, the IBC keeper and routing setup might now require fewer parameters (since capability and fee middleware are removed) and use a unified router abstraction for channels. - -### IBC Application Stack Adjustments - -- **IBC Transfer Module (ICS-20) v2**: Wire up the new transfer v2 stack for token transfers. The ibc-transfer module in v10 has a revised implementation (transferv2) to work with IBC v2. In Lumera’s app.go, instead of the old transfer.NewIBCModule, use transferv2.NewIBCModule(app.TransferKeeper) and register it on the IBC router. This ensures that fungible token transfers use the IBC v2 packet format and routing. -- **Remove Fee Middleware (ICS-29)**: In IBC-Go v10, the fee middleware (ICS-29) is no longer wired in the same way. The migration guidelines explicitly instruct chains to remove the ibc-fee module from the stack. Accordingly, delete any IBCFeeKeeper initialization and omit wrapping IBC modules with ibcfee.NewIBCMiddleware. (Relayer incentivization can be revisited later if needed via updated middleware patterns, but for now v2 simplifies the stack.) -- **Callbacks Middleware**: The IBC Callbacks middleware module has moved into the core ibc-go module and its initialization signature has changed. We will import ibccallbacks/v10 and wrap it appropriately around the transfer module if those hooks are needed (ensuring it uses the new ChannelKeeperV2 where required). -- **Interchain Accounts (ICS-27) Modules**: Lumera’s Interchain Accounts host/controller modules should be updated to the v10 API. In practice, this means using the latest icahost and icacontroller implementations and removing any dummy modules or fee wrapping. For example, previously a “no-authz” dummy module and fee middleware wrapped the ICA controller – these should be simplified to just icacontroller.NewIBCMiddleware(app.ICAControllerKeeper). Likewise, instantiate the ICA host with icahost.NewIBCModule alone (no fee wrapper). This aligns ICA with IBC v2’s streamlined channel management. - -### Configuration and State Considerations - -- **Genesis / AppState**: No explicit genesis field changes are expected solely for IBC v2, since the upgrade is mainly code-level. However, because we remove the Capability module, we should ensure that the on-chain capability store (if present) can be left inert or safely migrated. The upgrade handler can simply drop capability references since IBC channel locking will be handled via the new router logic. -- **Version Negotiation**: IBC-Go v10 introduces an application version negotiation interface for handshake (the NegotiateAppVersion method). Ensure Lumera’s custom IBC app modules (if any) implement this if needed, to agree on versions during channel setup. The standard modules (transfer, ICA, etc.) already handle this. -- **Backward Compatibility Mode**: Out of the box, ibc-go v10 supports both IBC v1 (classic) and v2 protocols for interoperability. We will configure the IBC keeper to support connections with IBC v1 chains. This means Lumera can still open **IBC Classic channels** to chains that have not yet upgraded, ensuring continuity of existing connections. No special config is required beyond not disabling the legacy channel handshake logic present in ibc-go v10 (it remains enabled by default to maintain compatibility [ccvalidators.com] (https://ccvalidators.com/blog/ibc-eureka-the-endgame-of-blockchain-interoperability/)). -- **Testing the Upgrade Path**: Write an upgrade handler (if using Cosmos SDK in-place upgrade) to perform any needed state migrations. This includes removing the now-unused fee module account permission (if defined) and possibly clearing capability indices. We will simulate an upgrade in a dev environment to ensure that after restarting with the new binary, all IBC connections and channels are functional. - -### Validation and Testing - -After implementing the above changes, thorough testing is essential: - -- **Unit Tests**: Run the IBC module’s test suite and add new tests for the modified handshake. Test that opening a channel to a known IBC v1 counterparty works (the handshake should gracefully fall back to v1). -- **Integration Tests**: Set up a local testnet with two Lumera nodes using the new code and attempt to establish IBC connectivity with another chain (or a loopback connection). Validate that ICS-20 token transfers still succeed end-to-end. -- **Relayer Compatibility**: Test with the common IBC relayer (e.g. Hermes or Go Relayer) to ensure it can relay packets to/from Lumera after the upgrade. Relayers may need minor config updates (like recognizing the new channel version string for v2 channels), so we’ll verify this in advance. -- **Performance Benchmarking**: Compare the handshake time and packet throughput before vs. after. We expect improved performance (faster channel setup due to fewer steps). Any issues will be addressed before mainnet deployment. - -By completing these technical steps, Lumera’s codebase will be ready to run IBC v2, unlocking the new capabilities while remaining compatible with existing IBC networks. - -## Benefits of Upgrading to IBC v2 - -Upgrading to IBC v2 (ibc-go v10) offers several **concrete benefits** for Lumera, improving both the developer experience and cross-chain functionality: - -- **Simplified Handshake & Improved Performance**: IBC v2 reduces the connection handshake from a 10-step process (4 steps each for connection and channel, plus client setup) to just 3 steps. This streamlined startup means faster time-to-connect and less overhead for relayers. It also condenses channels and connections into a single abstraction (the new Router), eliminating the lengthy channel open/confirm dance. The result is quicker integration with other chains and lower latency for starting cross-chain operations. -- **Greater Composability and Upgradability**: In IBC v2, all applications run over a single connection, with dynamic routing by port ID. This means Lumera and a counterparty chain can use one connection to support multiple services or module interactions simultaneously, without needing separate channels for each service. New IBC applications (or new versions) can be added without coordinating a new channel handshake, greatly improving extensibility. For example, Lumera could add a new interchain service post-upgrade and immediately route packets over the existing connection. This unified routing model also avoids the fragmentation of multiple channels and the reliance on off-chain “canonical channel” conventions. -- **Custom Packet Flexibility (Payloads)**: IBC v2 introduces a Payload abstraction in packets. Instead of a single opaque bytes field tied to a specific port/channel, a packet can carry a list of payloads, each with its own destination port, app version, and encoding type. This unlocks flexibility for custom packet designs. Lumera can define custom packet types for its services (if needed) with domain-specific encoding (e.g., using efficient binary codecs or Ethereum ABI encoding for certain interactions). The payload structure even allows combining multiple operations in one packet (e.g., a token transfer plus a callback invocation in one go), enabling atomic cross-chain composability in future releases. In short, Lumera gains more control over how data is packaged and interpreted across chains. -- **Advanced IBC Features Availability**: By moving to the latest IBC implementation, Lumera can easily adopt new IBC features such as Interchain Accounts, Interchain Queries, and upcoming cross-chain contract calls. These existed in IBC v1 but are further refined or easier to use in v2. For instance, Interchain Accounts (ICS-27) allow a chain to control an account on another chain via IBC, which Lumera can use to let other chains invoke its services (or vice versa). Cross-Chain Queries (ICS-31/32) enable direct reading of state from another chain over IBC, useful for fetching NFT metadata or verification results from Lumera. Upgrading ensures Lumera is fully compatible with these modules, which improves cross-chain composability (chains can seamlessly incorporate Lumera’s functionality into their own workflows). -- **Performance and Scalability**: Beyond handshake improvements, IBC v2 is designed with broader ecosystem scalability in mind. The lighter protocol is more amenable to varied environments (even non-Tendermint chains), meaning Lumera can potentially handle more connections in parallel with less overhead. The elimination of redundant fields (like port IDs in the packet, and using only timestamps for timeouts) trims packet size and verification work, which could slightly improve throughput and reduce gas costs per packet on Lumera. -- **Cross-Chain Service Enablement**: Perhaps most importantly, IBC v2 better enables cross-chain services – a core goal for Lumera. With the new capabilities, Lumera can serve as an interchain utility chain providing storage and AI services. For example, improved routing means a single IBC connection to another chain can carry both token transfers and service requests back-and-forth, making it easier to compose multi-step cross-chain transactions (e.g., sending payment and a service request together). This composability was more clunky in IBC v1, where separate channels or sequential transactions were needed. - -In summary, upgrading to IBC v2 brings Lumera speed, flexibility, and access to richer interchain functionality. It lays a strong foundation for Lumera to not just participate in the interchain, but to become a **key service provider** within it, thanks to these improvements in protocol design and capabilities. - -## Exposing Lumera Features as IBC Services - -One of the strategic advantages of upgrading is the ability to expose Lumera’s unique features – **Cascade** (distributed storage), **Sense** (near-duplicate NFT detection), **Inference** (AI/ML agents), and **NFT Metadata** services – as **IBC-compatible services**. This means other blockchains can seamlessly invoke Lumera’s capabilities through standard IBC channels and packets. Below we propose how each feature can be integrated into the IBC framework: - -### Cascade: Distributed Storage Service - -Cascade is Lumera’s distributed, permanent storage protocol for NFT data, built on RaptorQ fountain codes and a Kademlia DHT. It breaks files into redundant chunks and stores them across the network, ensuring durable NFT storage. To offer Cascade as an interchain service, we can leverage IBC in the following ways: - -- **IBC Application Module for Storage**: Implement a custom IBC application (port) on Lumera named, for example, "cascade" or "storage". External chains can open an IBC channel to this port. Through this channel, they send storage requests as IBC packets (containing the data or references to data that needs storage). Lumera’s module on receiving a request will process it by encoding the asset into chunks and storing it via Cascade’s logic. Upon success, Lumera can return an acknowledgement packet with a **storage receipt** – e.g., a content ID or storage tx hash. -- **Data Transfer Considerations**: NFT images or files can be large, so the design must handle chunking. IBC v2’s packet payload improvements allow flexible encoding; we could define a chunked transfer protocol (sending multiple ordered packets carrying file chunks) under the Cascade channel. Alternatively, the requesting chain might first upload the asset to a known location (or send via ICS-20 if it’s tokenized), and then just send a reference (like a hash or URL) to Lumera for retrieval. Lumera’s Cascade module could have the capability to fetch external data given a reference (if security permits) or rely on the relayer to carry the actual payload. -- **Interchain Accounts Alternative**: Another approach is to utilize ICS-27 (Interchain Accounts). A chain could create an account on Lumera and invoke a MsgStoreFile transaction on Lumera through that account. The Cascade logic would execute as if the user directly submitted it on Lumera. The result (e.g., a stored file ID) would be committed to Lumera’s state. The requesting chain can then query this via an interchain query or wait for the transaction result in the acknowledgement. Using ICS-27 ensures we reuse Lumera’s existing transaction flow, though it requires the counterparty chain to support the controller side of interchain accounts. -- **Benefits**: By exposing Cascade over IBC, any NFT-centric chain in the Cosmos ecosystem (and beyond) can utilize permanent, decentralized storage for their NFT media. This mitigates the common problem of NFT assets disappearing from centralized hosts. Lumera could charge fees in PSTL (Pastel token) or another token for storage, possibly handled via an ICS-20 transfer accompanying the request (e.g., attach payment and the store request in one flow). IBC v2’s multi-payload packets might even allow combining payment and request in one packet in the future. - -### Sense: Near-Duplicate NFT Detection - -Sense is Lumera’s AI-driven protocol for near-duplicate NFT detection and rareness scoring. It generates a fingerprint vector for an image and compares it against a database to produce a Relative Rareness Score (0% = identical, 100% = completely unique). To provide Sense as an IBC service: - -- **IBC Request/Response Workflow**: Similar to Cascade, define an IBC application port (e.g., "sense"). Other chains (especially NFT marketplaces or minting platforms) can send a SenseRequest packet containing either the NFT data (image) or a fingerprint of the image. Lumera’s Sense module, upon receiving the request, computes the rareness score by comparing the NFT’s fingerprint against its extensive dataset (which includes NFTs from Pastel/Lumera and possibly other sources). It then returns the result in the packet acknowledgement – e.g., the score and perhaps a list of any detected duplicates or their IDs. -- **Data Input Options**: If sending full image data over IBC is too heavy, an alternative is to require the requesting chain to store the image via Cascade first, then send a Sense request referencing the stored image’s content ID. Since Lumera would then have the image data internally, the Sense module can access it directly for analysis. This two-step approach (store, then analyze) can be orchestrated via IBC: first an ICS-27 call or Cascade packet to store, then an ack or subsequent message triggers Sense. We can also consider allowing a perceptual hash or fingerprint vector to be sent instead of the raw image (if the external chain can compute the same fingerprint algorithm). However, given Sense’s sophisticated deep learning model (10,000+ dimensional fingerprint), it may be preferable to let Lumera compute it for consistency. -- **Interchain Account / Query Integration**: A chain could use an interchain account to call a MsgCheckImage on Lumera (passing an image hash or ID), which triggers Sense. The result could be written to Lumera’s state (e.g., as an event or a temporary record). The requesting chain could then use ICS-31 (cross-chain query) to read the result back if not present in the ack. Alternatively, the transaction’s success ack could carry the primary result. -- **Benefits**: Exposing Sense via IBC means any NFT minting operation on any chain can vet the uniqueness of the NFT before finalizing a mint. For example, an NFT marketplace chain could, upon mint, automatically query Lumera’s Sense service to ensure the content isn’t a copy of an existing NFT. This enhances trust and provenance across the interchain NFT ecosystem. Lumera’s service would effectively act as a decentralized plagiarism checker for digital art, accessible through a trust-minimized channel. This also drives usage of Lumera’s AI capabilities, potentially with fee payment attached per request (which could be handled via a token transfer or deduction of credits – see below). - -### Inference: AI Agents - -**Inference** is Lumera’s AI/LLM layer that brings advanced machine learning functionalities (like language models and AI-driven analysis) into the network. It integrates with providers such as OpenAI, Anthropic, and others to enable intelligent data processing and content generation in dApps. To make Inference available to other chains via IBC: - -- **Unified Service Interface**: Provide an IBC port (e.g., "inference"). Other chains can send AI task requests to this port. A request might specify the type of model or service (e.g., “run text through GPT-4 for summarization” or “classify image for NSFW content”), along with the input data or reference. Lumera’s Inference module would receive the task, route it to an appropriate supernode or external API as configured (Lumera leverages specialized nodes and possibly off-chain APIs for AI), then return the result. -- **Request Payload Format**: Because inference tasks can vary widely, we’d design a flexible message schema – including fields like model_type (or model ID), parameters, and payload. IBC v2’s ability to handle different encoding types is useful here: for instance, we might use JSON or MsgPack encoding for AI requests for readability, or a binary format if needed. The response might be textual (for chatbot replies, etc.) or binary data (for images or other media generated). Splitting large responses over multiple packets may be needed for very large outputs. -- **Stateful vs Stateless Agents**: If Lumera supports stateful AI agents (e.g., an agent that maintains context over multiple calls), we could implement a session identifier in the requests. This would allow a chain to initiate an AI agent session and continue feeding it inputs via subsequent IBC messages. However, managing long-lived sessions over IBC can be complex (timeouts, ordering, etc.), so initially we may focus on stateless query-style requests (each request yields an independent result). -- **Payment and Access Control**: The Inference protocol on Lumera uses a credit system for users (buying inference credits with PSTL). For cross-chain use, Lumera could require that the calling account (or chain) has sufficient credits or attaches payment. One approach is to use ICS-20 token transfers alongside the request: for example, a chain could escrow some PSTL on Lumera or include a fee in the request packet (if we extend the packet format to carry a fee, or simply do two IBC operations back-to-back: one token transfer, one inference request). Another approach is ICS-27: an interchain account from the requester could hold PSTL and spend the credits when making the call on Lumera’s chain. -- **Benefits**: By offering AI as a service, Lumera can become the AI co-processor for the interchain. Chains that lack the resources or desire to integrate large AI models can offload tasks to Lumera. For example, a social media chain might use Lumera to perform content moderation (by sending images/text for analysis), or a DeFi chain might use it for AI-based risk assessments. All of this can happen trustlessly via IBC. Lumera’s inference service thus expands the realm of what cross-chain applications can do, bringing Web2 AI power into Web3 ecosystems without centralized intermediaries. - -### NFT Metadata: Interchain Metadata Hub - -Lumera can also position itself as a metadata repository and verification layer for NFTs across chains. NFT metadata includes attributes, provenance info, and ownership records that might benefit from being standardized or permanently stored. - -- **Metadata Storage and Retrieval**: Lumera could maintain a registry of NFT metadata that is submitted to it via IBC. For example, when an NFT is minted on Chain A, it could send the metadata (properties, description, etc.) to Lumera for permanent storage (possibly alongside the asset itself via Cascade). Lumera would index this under a composite key (like /). Other chains could later query this metadata to verify an NFT’s details or to display them consistently. -- **Authenticity and Provenance Service**: Because Lumera can aggregate NFT information from multiple chains, it could serve as an authentication oracle. Via IBC, a chain could ask Lumera questions like “Does NFT X on chain A have a valid registration and what’s its metadata hash?” and Lumera can respond with the canonical data. This can prevent malicious actors from forging NFT details on another chain – since Lumera’s records (if widely accepted) become a source of truth. Essentially, Lumera acts as a trustless NFT metadata catalogue for the interchain. -- **Using IBC Features**: Implementing this may use a mix of ICS-27 and ICS-31. To register metadata, an interchain account on Lumera could submit a transaction (MsgRegisterMetadata) carrying the NFT’s info (or a hash of it plus a link to full content stored via Cascade). The transaction would commit the data on Lumera. Then, to retrieve metadata, ICS-31 cross-chain queries could allow any chain to fetch that data by key. If ICS-31 is not yet widely available, we could alternatively allow a direct query request packet (similar to how Sense returns a score) where a chain sends a MetadataQuery packet and Lumera replies with the data in the ack. -- **Integration with Cascade and Sense**: These services complement each other. For instance, upon storing an image via Cascade, Lumera can automatically generate a fingerprint and update the Sense index. Similarly, when metadata is registered, Lumera can ensure the corresponding asset is stored and link them. Other chains might simply call a higher-level “Register NFT” IBC method that triggers storing the asset (Cascade), storing metadata, and running Sense detection – all coordinated on Lumera’s side. Thanks to IBC v2’s design, such a complex flow could be done over one robust connection and even in one combined packet in the future (leveraging multiple payloads for different apps in one atomic submission). -- **Benefits**: Chains get immutable storage and verification of their NFT metadata, enhancing security (no more lost metadata if source chain data is pruned or altered). It fosters an interoperable NFT ecosystem: NFTs on different chains can be verified against a common reference point (Lumera), enabling cross-chain NFT marketplaces or bridges to trust the metadata consistency. Lumera in turn becomes a critical infrastructure node for NFTs, increasing usage of its network and token. - -In all of the above, the overarching idea is to transform Lumera into a suite of interchain services accessible via standard IBC channels. Each service (storage, duplicate detection, AI compute, metadata registry) would be exposed in a modular way, either through distinct IBC application ports or via general frameworks like interchain accounts. The upgrade to IBC v2 greatly aids this by making it simpler to manage multiple services over IBC and by providing the necessary flexibility in packet handling. - -## Staged Deployment Plan and Backward Compatibility - -Upgrading a live blockchain and rolling out new cross-chain services is a complex process. We propose a **phased deployment plan** to ensure a smooth transition: - -1. **Development and Internal Testing**: -In this initial phase, the dev team will implement the ibc-go v10 changes on a development branch. Extensive testing (unit tests, simulation, local networks) is conducted as described earlier. The team will also write migration scripts or an upgrade handler to automate state changes (e.g., removing module accounts for fee, capability cleanup). We will verify that a node can upgrade from the old binary to the new one without issues, and that core functionality (transactions, existing modules) remains unaffected. This phase is strictly internal and uses no external connections – focusing on code stability. -2. **Testnet Deployment (IBC v2 readiness)**: -Once confident, we will deploy the new version to a Lumera testnet. If an official public testnet exists, coordinate a specific upgrade height via governance or simply relaunch the testnet if ephemeral. On this testnet, we will: - - **Connect with Counterparty Chains**: Establish IBC connections with other testnets (e.g., Cosmos Hub’s testnet, Osmosis testnet) to ensure interoperability. This tests backward compatibility: Lumera (v2) should successfully open channels with v1 counterparties, proving that relayers and handshake downgrading work. - - **Try New Features**: If feasible, spin up a small dummy chain (or use an existing one) to act as a client of Lumera’s services. For example, demonstrate an NFT stored on Chain A being sent to Lumera for Cascade storage and Sense analysis, all on testnet. This will likely involve deploying and testing ICS-27 and ICS-31 functionality in a controlled setting. - - **Bug Fixes**: Use the findings from testnet to fix any issues. For instance, if relayers encountered errors with the new handshake, adjust parameters or inform relayer developers. Monitor the network for any instability introduced by the new code. -3. **Audit and Review (Optional)**: -Given the scope of changes (IBC being critical infrastructure), it may be prudent to have an **external audit** of the upgrade implementation, especially the custom logic for new service modules. Auditors would review the IBC upgrade diff as well as the new IBC application modules for Cascade, Sense, etc. This can run in parallel with extended testnet runs. Community testing and bug bounty programs on the testnet could further harden the code. -4. **Mainnet Upgrade Preparation**: -Prior to scheduling the upgrade on mainnet, coordinate with all stakeholders: - - **Validator Coordination**: Communicate the planned upgrade (block height or governance proposal) well in advance. Provide upgrade instructions and binaries to validators. Emphasize that this upgrade is significant (new IBC version) and encourage them to test their nodes on the testnet or a dry-run. - - **Relayer Coordination**: Reach out to major relayer operators in the Cosmos ecosystem (who facilitate Lumera’s IBC transactions) and inform them of the upgrade timeline. Since ibc-go v10 still supports IBC classic, relayers can continue operating normally for existing channels. However, to use the new IBC v2 features (like connecting to Ethereum via ZK light clients, etc.), they might need to update their relayer software to versions that know about IBC v2. We ensure that at least one well-maintained relayer (like Hermes) has a release supporting ibc-go v10. - - **Governance Proposal**: If Lumera uses on-chain governance for upgrades, draft a proposal describing the upgrade (including benefits like those outlined above). Highlight that from an operations perspective, nothing drastic will change initially – e.g., “IBC will continue to function as before for users” to alleviate concerns. Garner support by outlining new possibilities post-upgrade. -5. **Mainnet Upgrade Execution**: -At the scheduled time (or height), the Lumera mainnet will undergo the upgrade. Validators will switch to the new binary containing ibc-go v10. Post-upgrade: - - **Stability Checks**: Confirm that the chain produces blocks and that all modules (bank, staking, etc.) are running fine. Then specifically check the IBC module: all existing IBC channels and clients should be listed and active. Because we removed the capability module, we will verify that existing channel state is accessible (ibc-go v10 should internally manage channel references now). If any existing channel is non-functional, we might coordinate with the connected chain to reopen a connection using the new protocol, but this is unlikely since backward support is in place. - - **Backward Compatibility**: Ensure that **IBC Classic channels continue seamlessly**. According to IBC developers, Cosmos chains upgrading to v2 see no interruption in normal IBC operations – light clients still verify proofs, relayers still relay packets in the same way. We will test a token transfer over an old channel as soon as the chain is up to confirm this. In the unlikely event of an issue (say, the channel capability was lost), our fallback plan would involve using governance or admin authority to recreate channel bindings or ask users to migrate to a new channel. However, given the design of ibc-go v10, such disruption is not expected. - - **Monitoring**: Closely monitor the mempool and blockchain for any IBC errors, and watch relayer logs. It’s critical to catch any unexpected bugs early. We’ll also keep communication open with relayers for quick troubleshooting. -6. **Phased Rollout of New Services**: -With the core upgrade live, we can begin enabling the new IBC services of Lumera in phases: - - **Enable ICS-27 Interchain Accounts**: Activate the ICA host module on Lumera via a parameter change or simply by usage (if compiled in, it may be live by default). Announce that other chains can now open interchain accounts on Lumera. Initially, whitelist some partner chains to try out controlling Lumera accounts to use Cascade or Sense. This careful approach ensures the feature is used in a controlled manner before broad exposure. - - **Offer Cascade and Sense on Testnet/Mainnet**: Possibly launch a beta program where select projects integrate with Cascade or Sense via IBC. For example, an NFT marketplace could try storing their new mints on Lumera and retrieving the Sense score. Their feedback will help refine the modules. On-chain, this might involve opening dedicated IBC channels for those services (if not using ICA). We will monitor these channels for correct behavior (packet flow, acknowledgements). Over time, as confidence grows, make these services publicly available to any chain that connects. - - **Documentation and SDKs**: To encourage adoption, produce documentation and possibly SDK support for Lumera’s IBC endpoints (e.g., a developer guide on how another chain can send a Cascade storage request, including code examples). This will likely be done as we enable the services. - - **Inference Service Rollout**: The AI inference service might be introduced a bit later given its complexity. We may run a pilot where Lumera connects with a specific chain (or an application) that wants to leverage AI. During this stage, we’ll fine-tune pricing, performance, and security (since calling external AI APIs has different considerations). Once stable, open it up as an interchain service similar to Cascade and Sense. - - **NFT Metadata and Query Services**: Establish Lumera as an interchain NFT metadata hub by onboarding a few chains to push their metadata to Lumera. Ensure that our cross-chain query implementation (if using ICS-31) is working so those chains can fetch the info. Over time, advertise this as a general service. -7. **Post-Upgrade Evaluation and Maintenance**: -After full deployment, conduct an evaluation of the upgrade’s impact: - - **Performance Metrics**: Review if block processing times for IBC transactions improved and if the throughput of IBC packets increased. Check if relayer fees or latencies dropped due to the more efficient protocol. - - **Reliability**: Gather data on any IBC packet failures or unexpected behavior. If the new multi-app single-connection approach caused any hiccups, patch as needed. For instance, ensure that if one service’s logic fails, it doesn’t block the whole connection’s packets (the router should isolate apps by port). - - **Backward Compatibility Period**: Plan to support IBC classic channels for as long as needed. Cosmos chains will gradually all upgrade to v2, but in the interim, Lumera may operate with some classic channels. We’ll maintain code paths for IBC v1 as provided by ibc-go v10 until we are sure they are no longer used. Thereafter, we might deprecate those for cleanliness (perhaps in a future release). - - **Security Monitoring**: New features mean new surface area. Keep a close watch on cross-chain transactions invoking Lumera’s services to detect any abuse or vulnerabilities (e.g., denial-of-service via spammy requests, or attempts to exploit the AI services). Rate limiting or fee requirements may be adjusted based on real usage patterns. - -Throughout this process, **communication is key**. We will keep the Lumera community and partners informed at each stage, with clear documentation of changes. By proceeding methodically through testnet trials, mainnet upgrade, and gradual feature rollout, we aim to minimize disruptions and ensure that the transition to IBC v2 and the launch of cross-chain services are successful. Lumera will emerge from this process not only up-to-date with the latest interchain protocol, but positioned as a **leader in cross-chain utility**, providing valuable services across the interchain ecosystem. - -## Setting Up IBC Communication with Other Chains - -After Lumera is upgraded to use IBC-Go v10 (IBC v2), establishing connections with other chains requires configuring ports, using relayers, and setting up IBC clients, connections, and channels. Here's a step-by-step guide: - -### ✅ Prerequisites (for Lumera and the remote chain) - -- Both chains must: - - Be running Cosmos SDK with IBC-Go (v1 or v2). - - Enable required IBC modules in `app.go`. - - Be publicly accessible via RPC, GRPC, and P2P ports. - - Have relayer access (Hermes or Go Relayer). - -### 🔧 Step 1: Configure IBC Ports and Applications in `app.go` - -```go -ibcRouter.AddRoute("transfer", transferIBCModule) -ibcRouter.AddRoute("cascade", cascadeIBCModule) -ibcRouter.AddRoute("sense", senseIBCModule) -ibcRouter.AddRoute("inference", inferenceIBCModule) -ibcRouter.AddRoute(icacontrollertypes.ModuleName, icacontrollerIBCModule) -ibcRouter.AddRoute(icahosttypes.ModuleName, icahostIBCModule) -``` - -### 🔁 Step 2: Relayer Configuration (Hermes example) - -#### Create Hermes config - -The official website for the Hermes IBC Relayer is [hermes.informal.systems](https://hermes.informal.systems). -```toml -[[chains]] -id = "lumera" -rpc_addr = "http://:26657" -grpc_addr = "http://:9090" -websocket_addr = "ws://:26657/websocket" -account_prefix = "lum" # or "tP" for testnet -... - -[[chains]] -id = "osmosis-1" -rpc_addr = "https://rpc-osmosis.blockapsis.com:443" -grpc_addr = "https://grpc-osmosis.blockapsis.com:443" -websocket_addr = "wss://rpc-osmosis.blockapsis.com/websocket" -account_prefix = "osmo" -... -``` - -#### Add keys - -```bash -hermes keys add --chain lumera --mnemonic-file lumera.mnemonic -hermes keys add --chain osmosis-1 --mnemonic-file osmosis.mnemonic -``` - -### 🔌 Step 3: Create IBC Client, Connection, Channel with Osmosis - -```bash -# Create client -hermes create client --host-chain lumera --counterparty-chain osmosis-1 - -# Create connection -hermes create connection --a-chain lumera --b-chain osmosis-1 - -# Create channel for ICS-20 -hermes create channel --a-chain lumera --a-port transfer --b-chain osmosis-1 --b-port transfer --order unordered --channel-version transfer - -# Or for a custom service (e.g., cascade) -hermes create channel --a-chain lumera --a-port cascade --b-chain osmosis-1 --b-port cascade --order ordered --channel-version 1 -``` - -### 🧪 Step 4: Test Packet Relay - -- Send a transaction (ICS-20, Cascade request, etc.) -- Observe relayer processing packet and acknowledgment - -### 📦 Step 5: Optional — Set Up Interchain Accounts (ICS-27) - -An **Interchain Account** allows Chain A (*the controller chain*) to: - -- Create and control an account on Chain B (*the host chain*) -- Submit arbitrary Cosmos SDK messages (like MsgSend, MsgDelegate, or even custom messages) -- Do this over IBC, securely and permissionlessly - -So instead of Chain A asking users to send tokens or interact with Chain B manually, Chain A can act on their behalf directly on Chain B. -For example, some other chain could create an ICA on Lumera, then invoke MsgStoreFile (Cascade), MsgAnalyzeImage (Sense) or MsgRunInference (Inference). - -1. **Create ICA channel**: - - ```bash - hermes create channel --a-port icacontroller --b-port icahost --order ordered --channel-version icacontroller-1 - ``` - -2. Send `MsgSendTx` from controller chain to Lumera via ICA -3. Lumera processes and emits event or result - -### ✅ Summary -| Task | Who | Command / Config | -|------|-----|------------------| -| Enable IBC apps | Lumera devs | `app.go`, add routes | -| Run relayer | Operator | Hermes / Go Relayer setup | -| Add keys | Operator | `hermes keys add` | -| Open connection/channel | Operator | Hermes CLI | -| Test services | Any | Send IBC tx, confirm ack | - -These steps ensure a smooth and secure IBC setup for cross-chain communication between Lumera and partner chains like Osmosis. \ No newline at end of file +- **Upstream fixes**: Pick up v10-series fixes and maintenance improvements, reducing the risk of carrying known IBC bugs. +- **Developer ergonomics**: Use newer helper APIs (including v1/v2 event parsing) to reduce custom code in Lumera. +- **Ecosystem alignment**: Stay on the latest v10 patch level for relayer compatibility and support. diff --git a/go.mod b/go.mod index 7e8f800d..33564546 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/LumeraProtocol/lumera go 1.25.5 replace ( - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.50.14 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 // replace broken goleveldb @@ -13,35 +12,34 @@ replace ( require ( cosmossdk.io/api v0.9.2 - cosmossdk.io/client/v2 v2.0.0-beta.8.0.20250402172810-41e3e9d004a1 - cosmossdk.io/collections v1.3.0 + cosmossdk.io/client/v2 v2.0.0-beta.11 + cosmossdk.io/collections v1.3.1 cosmossdk.io/core v0.11.3 - cosmossdk.io/depinject v1.2.0 + cosmossdk.io/depinject v1.2.1 cosmossdk.io/errors v1.0.2 - cosmossdk.io/log v1.6.0 + cosmossdk.io/log v1.6.1 cosmossdk.io/math v1.5.3 cosmossdk.io/store v1.1.2 cosmossdk.io/tools/confix v0.1.2 - cosmossdk.io/x/circuit v0.1.1 - cosmossdk.io/x/evidence v0.1.1 - cosmossdk.io/x/feegrant v0.1.1 + cosmossdk.io/x/circuit v0.2.0 + cosmossdk.io/x/evidence v0.2.0 + cosmossdk.io/x/feegrant v0.2.0 cosmossdk.io/x/tx v0.14.0 cosmossdk.io/x/upgrade v0.2.0 - github.com/CosmWasm/wasmd v0.55.0-ibc2.0 - github.com/CosmWasm/wasmvm/v3 v3.0.0-ibc2.0 + github.com/CosmWasm/wasmd v0.61.6 + github.com/CosmWasm/wasmvm/v3 v3.0.2 github.com/DataDog/zstd v1.5.7 github.com/Masterminds/semver/v3 v3.3.1 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce - github.com/cometbft/cometbft v0.38.18 + github.com/cometbft/cometbft v0.38.20 github.com/cosmos/btcutil v1.0.5 - github.com/cosmos/cosmos-db v1.1.2 + github.com/cosmos/cosmos-db v1.1.3 github.com/cosmos/cosmos-proto v1.0.0-beta.5 - github.com/cosmos/cosmos-sdk v0.53.0 + github.com/cosmos/cosmos-sdk v0.53.5 github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/gogoproto v1.7.0 + github.com/cosmos/gogoproto v1.7.2 github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10 v10.1.0 - github.com/cosmos/ibc-go/v10 v10.3.0 - github.com/golang/mock v1.6.0 + github.com/cosmos/ibc-go/v10 v10.5.0 github.com/golang/protobuf v1.5.4 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -51,11 +49,11 @@ require ( github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 go.uber.org/mock v0.6.0 - golang.org/x/crypto v0.43.0 - golang.org/x/sync v0.17.0 + golang.org/x/crypto v0.47.0 + golang.org/x/sync v0.19.0 google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/protobuf v1.36.11 gotest.tools/v3 v3.5.2 lukechampine.com/blake3 v1.4.1 lukechampine.com/uint128 v1.3.0 @@ -79,7 +77,7 @@ require ( buf.build/go/standard v0.1.0 // indirect cel.dev/expr v0.24.0 // indirect cloud.google.com/go v0.120.0 // indirect - cloud.google.com/go/auth v0.16.0 // indirect + cloud.google.com/go/auth v0.16.4 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.5.2 // indirect @@ -119,7 +117,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.2.0 // indirect - github.com/bits-and-blooms/bitset v1.22.0 // indirect + github.com/bits-and-blooms/bitset v1.24.3 // indirect github.com/bkielbasa/cyclop v1.2.3 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect github.com/bombsimon/wsl/v4 v4.5.0 // indirect @@ -131,8 +129,8 @@ require ( github.com/butuzov/ireturn v0.3.1 // indirect github.com/butuzov/mirror v1.3.0 // indirect github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.14.1 // indirect - github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/bytedance/sonic v1.14.2 // indirect + github.com/bytedance/sonic/loader v0.4.0 // indirect github.com/catenacyber/perfsprint v0.8.2 // indirect github.com/ccojocar/zxcvbn-go v1.0.2 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -155,9 +153,9 @@ require ( github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/iavl v1.2.4 // 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.14.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.16.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/creachadair/atomicfile v0.3.1 // indirect github.com/creachadair/tomledit v0.0.24 // indirect @@ -169,7 +167,7 @@ require ( github.com/denis-tingaikin/go-header v0.5.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.1.1 // indirect + github.com/dgraph-io/ristretto v0.2.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/cli v28.4.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect @@ -190,7 +188,7 @@ require ( github.com/firefart/nonamedreturns v1.0.5 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/getsentry/sentry-go v0.32.0 // indirect + github.com/getsentry/sentry-go v0.35.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/ghostiam/protogetter v0.3.9 // indirect github.com/go-chi/chi/v5 v5.2.3 // indirect @@ -212,13 +210,12 @@ require ( github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/gobwas/ws v1.2.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.5 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect github.com/golangci/go-printf-func-name v0.1.0 // indirect @@ -239,7 +236,7 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect - github.com/googleapis/gax-go/v2 v2.14.1 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/gordonklaus/ineffassign v0.1.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/websocket v1.5.3 // indirect @@ -251,7 +248,7 @@ require ( 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-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.8 // indirect + github.com/hashicorp/go-getter v1.7.9 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect @@ -304,10 +301,10 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mdp/qrterminal/v3 v3.2.1 // indirect github.com/mgechev/revive v1.7.0 // indirect github.com/minio/highwayhash v1.0.3 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.2 // indirect github.com/moricho/tparallel v0.3.2 // indirect @@ -331,10 +328,10 @@ require ( github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polyfloyd/go-errorlint v1.7.1 // indirect - github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 // indirect github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -360,7 +357,7 @@ require ( github.com/securego/gosec/v2 v2.22.2 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/segmentio/encoding v0.5.3 // indirect - github.com/shamaton/msgpack/v2 v2.2.0 // indirect + github.com/shamaton/msgpack/v2 v2.2.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/tenv v1.12.1 // indirect @@ -386,7 +383,7 @@ require ( github.com/tomarrell/wrapcheck/v2 v2.10.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ulikunitz/xz v0.5.11 // indirect + github.com/ulikunitz/xz v0.5.14 // indirect github.com/ultraware/funlen v0.2.0 // indirect github.com/ultraware/whitespace v0.2.0 // indirect github.com/uudashr/gocognit v1.2.0 // indirect @@ -396,8 +393,9 @@ require ( github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.3.0 // indirect github.com/ykadowak/zerologlint v0.1.5 // indirect + github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.14.3 // indirect + github.com/zondax/ledger-go v1.0.1 // indirect gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.13.0 // indirect go-simpler.org/sloglint v0.9.0 // indirect @@ -409,7 +407,7 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect @@ -419,21 +417,22 @@ require ( go.uber.org/automaxprocs v1.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/v3 v3.0.4 // indirect - golang.org/x/arch v0.15.0 // indirect + golang.org/x/arch v0.17.0 // indirect golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect golang.org/x/oauth2 v0.32.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/text v0.30.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.37.0 // indirect - google.golang.org/api v0.229.0 // indirect - google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/tools v0.40.0 // indirect + google.golang.org/api v0.247.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/grpc/cmd/protoc-gen-go-grpc v1.1.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -443,7 +442,8 @@ require ( mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect nhooyr.io/websocket v1.8.17 // indirect pluginrpc.com/pluginrpc v0.5.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + rsc.io/qr v0.2.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) tool ( diff --git a/go.sum b/go.sum index 0f845f7a..d7483dad 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,8 @@ cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVo cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= -cloud.google.com/go/auth v0.16.0 h1:Pd8P1s9WkcrBE2n/PhAwKsdrR35V3Sg2II9B+ndM3CU= -cloud.google.com/go/auth v0.16.0/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +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/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/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= @@ -648,18 +648,18 @@ connectrpc.com/otelconnect v0.8.0 h1:a4qrN4H8aEE2jAoCxheZYYfEjXMgVPyL9OzPQLBEFXU connectrpc.com/otelconnect v0.8.0/go.mod h1:AEkVLjCPXra+ObGFCOClcJkNjS7zPaQSqvO0lCyjfZc= 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.8.0.20250402172810-41e3e9d004a1 h1:nlMUeKu6CGrO7Gxt5S31qT3g27CHmBJHsZPjqHApVTI= -cosmossdk.io/client/v2 v2.0.0-beta.8.0.20250402172810-41e3e9d004a1/go.mod h1:xgv0ejeOk5yeDraPW5tv+PfBkCDt4yYa/+u45MyP+bM= -cosmossdk.io/collections v1.3.0 h1:RUY23xXBy/bu5oSHZ5y+mkJRyA4ZboKDO4Yvx4+g2uc= -cosmossdk.io/collections v1.3.0/go.mod h1:cqVpBMDGEYhuNmNSXIOmqpnQ7Eav43hpJIetzLuEkns= +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/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= -cosmossdk.io/depinject v1.2.0 h1:6NW/FSK1IkWTrX7XxUpBmX1QMBozpEI9SsWkKTBc5zw= -cosmossdk.io/depinject v1.2.0/go.mod h1:pvitjtUxZZZTQESKNS9KhGjWVslJZxtO9VooRJYyPjk= +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/log v1.6.0 h1:SJIOmJ059wi1piyRgNRXKXhlDXGqnB5eQwhcZKv2tOk= -cosmossdk.io/log v1.6.0/go.mod h1:5cXXBvfBkR2/BcXmosdCSLXllvgSjphrrDVdfVRmBGM= +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= cosmossdk.io/math v1.5.3/go.mod h1:uqcZv7vexnhMFJF+6zh9EWdm/+Ylyln34IvPnBauPCQ= cosmossdk.io/schema v1.1.0 h1:mmpuz3dzouCoyjjcMcA/xHBEmMChN+EHh8EHxHRHhzE= @@ -668,12 +668,12 @@ cosmossdk.io/store v1.1.2 h1:3HOZG8+CuThREKv6cn3WSohAc6yccxO3hLzwK6rBC7o= cosmossdk.io/store v1.1.2/go.mod h1:60rAGzTHevGm592kFhiUVkNC9w7gooSEn5iUBPzHQ6A= cosmossdk.io/tools/confix v0.1.2 h1:2hoM1oFCNisd0ltSAAZw2i4ponARPmlhuNu3yy0VwI4= cosmossdk.io/tools/confix v0.1.2/go.mod h1:7XfcbK9sC/KNgVGxgLM0BrFbVcR/+6Dg7MFfpx7duYo= -cosmossdk.io/x/circuit v0.1.1 h1:KPJCnLChWrxD4jLwUiuQaf5mFD/1m7Omyo7oooefBVQ= -cosmossdk.io/x/circuit v0.1.1/go.mod h1:B6f/urRuQH8gjt4eLIXfZJucrbreuYrKh5CSjaOxr+Q= -cosmossdk.io/x/evidence v0.1.1 h1:Ks+BLTa3uftFpElLTDp9L76t2b58htjVbSZ86aoK/E4= -cosmossdk.io/x/evidence v0.1.1/go.mod h1:OoDsWlbtuyqS70LY51aX8FBTvguQqvFrt78qL7UzeNc= -cosmossdk.io/x/feegrant v0.1.1 h1:EKFWOeo/pup0yF0svDisWWKAA9Zags6Zd0P3nRvVvw8= -cosmossdk.io/x/feegrant v0.1.1/go.mod h1:2GjVVxX6G2fta8LWj7pC/ytHjryA6MHAJroBWHFNiEQ= +cosmossdk.io/x/circuit v0.2.0 h1:RJPMBQWCQU77EcM9HDTBnqRhq21fcUxgWZl7BZylJZo= +cosmossdk.io/x/circuit v0.2.0/go.mod h1:CjiGXDeZs64nMv0fG+QmvGVTcn7n3Sv4cDszMRR2JqU= +cosmossdk.io/x/evidence v0.2.0 h1:o72zbmgCM7U0v7z7b0XnMB+NqX0tFamqb1HHkQbhrZ0= +cosmossdk.io/x/evidence v0.2.0/go.mod h1:zx/Xqy+hnGVzkqVuVuvmP9KsO6YCl4SfbAetYi+k+sE= +cosmossdk.io/x/feegrant v0.2.0 h1:oq3WVpoJdxko/XgWmpib63V1mYy9ZQN/1qxDajwGzJ8= +cosmossdk.io/x/feegrant v0.2.0/go.mod h1:9CutZbmhulk/Yo6tQSVD5LG8Lk40ZAQ1OX4d1CODWAE= cosmossdk.io/x/tx v0.14.0 h1:hB3O25kIcyDW/7kMTLMaO8Ripj3yqs5imceVd6c/heA= cosmossdk.io/x/tx v0.14.0/go.mod h1:Tn30rSRA1PRfdGB3Yz55W4Sn6EIutr9xtMKSHij+9PM= cosmossdk.io/x/upgrade v0.2.0 h1:ZHy0xny3wBCSLomyhE06+UmQHWO8cYlVYjfFAJxjz5g= @@ -703,10 +703,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CosmWasm/wasmd v0.55.0-ibc2.0 h1:9bH+QDnSGxmZhjSykLYGtW4sltzGFFVm10Awk683q2Y= -github.com/CosmWasm/wasmd v0.55.0-ibc2.0/go.mod h1:c9l+eycjUB2zNVLIGjAXd7QrFEbxVTEa1Fh1Mx74VwQ= -github.com/CosmWasm/wasmvm/v3 v3.0.0-ibc2.0 h1:QoagSm5iYuRSPYDxgRxsa6hVfDppUp4+bOwY7bDuMO0= -github.com/CosmWasm/wasmvm/v3 v3.0.0-ibc2.0/go.mod h1:oknpb1bFERvvKcY7vHRp1F/Y/z66xVrsl7n9uWkOAlM= +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/Crocmagnon/fatcontext v0.7.1 h1:SC/VIbRRZQeQWj/TcQBS6JmrXcfA+BU4OGSVUt54PjM= github.com/Crocmagnon/fatcontext v0.7.1/go.mod h1:1wMvv3NXEBJucFGfwOJBxSVWcoIO6emV215SMkW9MFU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= @@ -802,8 +802,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E= github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= -github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +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/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w= github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= @@ -818,8 +818,8 @@ github.com/breml/errchkjson v0.4.0 h1:gftf6uWZMtIa/Is3XJgibewBm2ksAQSY/kABDNFTAd github.com/breml/errchkjson v0.4.0/go.mod h1:AuBOSTHyLSaaAFlWsRSuRBIroCh3eh7ZHh5YeelDIk8= 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/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +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.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -845,10 +845,10 @@ github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc= github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI= 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.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= -github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +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/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/catenacyber/perfsprint v0.8.2 h1:+o9zVmCSVa7M4MvabsWvESEhpsMkhfE7k0sHNGL95yw= github.com/catenacyber/perfsprint v0.8.2/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM= @@ -924,8 +924,8 @@ 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.18 h1:1ZHYMdu0S75YxFM13LlPXnOwiIpUW5z9TKMQtTIALpw= -github.com/cometbft/cometbft v0.38.18/go.mod h1:PlOQgf3jQorep+g6oVnJgtP65TJvBJoLiXjGaMdNxBE= +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-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/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -944,29 +944,29 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.1.2 h1:KZm4xLlPp6rLkyIOmPOhh+XDK9oH1++pNH/csLdX0Dk= -github.com/cosmos/cosmos-db v1.1.2/go.mod h1:dMg2gav979Ig2N076POEw4CEKbCsieaOfDWSfFZxs8M= +github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= +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.50.14 h1:G8CtGHFWbExa+ZpVOVAb4kFmko/R30igsYOwyzRMtgY= -github.com/cosmos/cosmos-sdk v0.50.14/go.mod h1:hrWEFMU1eoXqLJeE6VVESpJDQH67FS1nnMrQIjO2daw= +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/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= -github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= -github.com/cosmos/iavl v1.2.4 h1:IHUrG8dkyueKEY72y92jajrizbkZKPZbMmG14QzsEkw= -github.com/cosmos/iavl v1.2.4/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw= +github.com/cosmos/gogoproto v1.7.2 h1:5G25McIraOC0mRFv9TVO139Uh3OklV2hczr13KKVHCA= +github.com/cosmos/gogoproto v1.7.2/go.mod h1:8S7w53P1Y1cHwND64o0BnArT6RmdgIvsBuco6uTllsk= +github.com/cosmos/iavl v1.2.6 h1:Hs3LndJbkIB+rEvToKJFXZvKo6Vy0Ex1SJ54hhtioIs= +github.com/cosmos/iavl v1.2.6/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10 v10.1.0 h1:epKcbFAeWRRw1i1jZnYzLIEm9sgUPaL1RftuRjjUKGw= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10 v10.1.0/go.mod h1:S4ZQwf5/LhpOi8JXSAese/6QQDk87nTdicJPlZ5q9UQ= -github.com/cosmos/ibc-go/v10 v10.3.0 h1:w5DkHih8qn15deAeFoTk778WJU+xC1krJ5kDnicfUBc= -github.com/cosmos/ibc-go/v10 v10.3.0/go.mod h1:CthaR7n4d23PJJ7wZHegmNgbVcLXCQql7EwHrAXnMtw= +github.com/cosmos/ibc-go/v10 v10.5.0 h1:NI+cX04fXdu9JfP0V0GYeRi1ENa7PPdq0BYtVYo8Zrs= +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.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= -github.com/cosmos/ledger-cosmos-go v0.14.0/go.mod h1:E07xCWSBl3mTGofZ2QnL4cIUzMbbGVyik84QYKbX3RA= +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/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/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= @@ -1001,10 +1001,9 @@ github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs= github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= +github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -1083,8 +1082,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/getsentry/sentry-go v0.32.0 h1:YKs+//QmwE3DcYtfKRH8/KyOOF/I6Qnx7qYGNHCGmCY= -github.com/getsentry/sentry-go v0.32.0/go.mod h1:CYNcMMz73YigoHljQRG+qPF+eMq8gG72XcGN/p71BAY= +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/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghostiam/protogetter v0.3.9 h1:j+zlLLWzqLay22Cz/aYwTHKQ88GE2DQ6GkWSYFOI4lQ= @@ -1169,15 +1168,12 @@ github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUW github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +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/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 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= @@ -1204,8 +1200,9 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -1344,8 +1341,8 @@ github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqE github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= -github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= +github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -1396,8 +1393,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.8 h1:mshVHx1Fto0/MydBekWan5zUipGq7jO0novchgMmSiY= -github.com/hashicorp/go-getter v1.7.8/go.mod h1:2c6CboOEb9jG6YvmC9xdD+tyAFsrUaJPedwXDGr0TM4= +github.com/hashicorp/go-getter v1.7.9 h1:G9gcjrDixz7glqJ+ll5IWvggSBR+R0B54DSRt4qfdC4= +github.com/hashicorp/go-getter v1.7.9/go.mod h1:dyFCmT1AQkDfOIt9NH8pw9XBDqNrIKJT5ylbpi7zPNE= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -1468,8 +1465,8 @@ github.com/jdx/go-netrc v1.0.0/go.mod h1:Gh9eFQJnoTNIRHXl2j5bJXA1u84hQWJWgGh569z github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= -github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +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/jhump/protoreflect/v2 v2.0.0-beta.2 h1:qZU+rEZUOYTz1Bnhi3xbwn+VxdXkLVeEpAeZzVXLY88= github.com/jhump/protoreflect/v2 v2.0.0-beta.2/go.mod h1:4tnOYkB/mq7QTyS3YKtVtNrJv4Psqout8HA1U+hZtgM= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -1571,8 +1568,8 @@ github.com/linxGnu/grocksdb v1.9.8/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LF github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= @@ -1604,6 +1601,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mdp/qrterminal/v3 v3.2.1 h1:6+yQjiiOsSuXT5n9/m60E54vdgFsw0zhADHhHLrFet4= +github.com/mdp/qrterminal/v3 v3.2.1/go.mod h1:jOTmXvnBsMy5xqLniO0R++Jmjs2sTm9dFSuQ5kpz/SU= github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY= github.com/mgechev/revive v1.7.0/go.mod h1:qZnwcNhoguE58dfi96IJeSTPeZQejNeoMQLUZGi4SW4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -1616,8 +1615,6 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= -github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -1666,8 +1663,8 @@ github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3L github.com/nunnatsa/ginkgolinter v0.19.1 h1:mjwbOlDQxZi9Cal+KfbEJTCz327OLNfwNvoZ70NJ+c4= github.com/nunnatsa/ginkgolinter v0.19.1/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -1759,8 +1756,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1777,8 +1774,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.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +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/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= @@ -1786,8 +1783,8 @@ 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.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 h1:+Wl/0aFp0hpuHM3H//KMft64WQ1yX9LdJY64Qm/gFCo= github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI= github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= @@ -1854,8 +1851,8 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/encoding v0.5.3 h1:OjMgICtcSFuNvQCdwqMCv9Tg7lEOXGwm1J5RPQccx6w= github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= -github.com/shamaton/msgpack/v2 v2.2.0 h1:IP1m01pHwCrMa6ZccP9B3bqxEMKMSmMVAVKk54g3L/Y= -github.com/shamaton/msgpack/v2 v2.2.0/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= +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/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -1925,6 +1922,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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= @@ -1962,8 +1960,8 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= -github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg= +github.com/ulikunitz/xz v0.5.14/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI= github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA= github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g= @@ -1994,10 +1992,12 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +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= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= -github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +github.com/zondax/ledger-go v1.0.1 h1:Ks/2tz/dOF+dbRynfZ0dEhcdL1lqw43Sa0zMXHpQ3aQ= +github.com/zondax/ledger-go v1.0.1/go.mod h1:j7IgMY39f30apthJYMd1YsHZRqdyu4KbVmUp0nU78X0= gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= @@ -2033,8 +2033,8 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ 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/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +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= @@ -2080,10 +2080,12 @@ 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/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.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +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= @@ -2105,8 +2107,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +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/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2175,8 +2177,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +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/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= @@ -2253,8 +2255,8 @@ 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.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= 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= @@ -2308,8 +2310,8 @@ 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.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +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/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= @@ -2409,7 +2411,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2425,11 +2426,11 @@ 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.29.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.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8= -golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= 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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -2445,8 +2446,8 @@ 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.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +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/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= @@ -2468,8 +2469,8 @@ 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.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +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/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= @@ -2477,8 +2478,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2561,8 +2562,8 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +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/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -2643,8 +2644,8 @@ google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/ google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= -google.golang.org/api v0.229.0 h1:p98ymMtqeJ5i3lIBMj5MpR9kzIIgzpHHh8vQ+vgAzx8= -google.golang.org/api v0.229.0/go.mod h1:wyDfmq5g1wYJWn29O22FDWN48P7Xcz0xz+LBpptYvB0= +google.golang.org/api v0.247.0 h1:tSd/e0QrUlLsrwMKmkbQhYVa109qIintOls2Wh6bngc= +google.golang.org/api v0.247.0/go.mod h1:r1qZOPmxXffXg6xS5uhx16Fa/UFY8QU/K4bfKrnvovM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2790,8 +2791,8 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78= -google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= +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= @@ -2866,8 +2867,8 @@ google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2959,9 +2960,11 @@ pluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo= pluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= +rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/tests/ibctesting/events.go b/tests/ibctesting/events.go index 5457c020..db4d30c4 100644 --- a/tests/ibctesting/events.go +++ b/tests/ibctesting/events.go @@ -6,49 +6,10 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - gogoproto "github.com/cosmos/gogoproto/proto" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" ) -// TODO: Remove this once it's implemented in the `ibc-go`. -// https://github.com/cosmos/ibc-go/issues/8284 -// -// ParsePacketsFromEventsV2 parses events emitted from a MsgRecvPacket and returns -// all the packets found. -// Returns an error if no packet is found. -func ParsePacketsFromEventsV2(eventType string, events []abci.Event) ([]channeltypesv2.Packet, error) { - ferr := func(err error) ([]channeltypesv2.Packet, error) { - return nil, fmt.Errorf("ParsePacketsFromEventsV2: %w", err) - } - var packets []channeltypesv2.Packet - for _, ev := range events { - if ev.Type == eventType { - for _, attr := range ev.Attributes { - switch attr.Key { - case channeltypesv2.AttributeKeyEncodedPacketHex: - data, err := hex.DecodeString(attr.Value) - if err != nil { - return ferr(err) - } - var packet channeltypesv2.Packet - err = gogoproto.Unmarshal(data, &packet) - if err != nil { - return ferr(err) - } - packets = append(packets, packet) - - default: - continue - } - } - } - } - return packets, nil -} - - // ParseAckFromEventsV2 parses events emitted from a MsgRecvPacket and returns the // acknowledgement. func ParseAckFromEventsV2(events []abci.Event) ([]byte, error) { diff --git a/tests/ibctesting/events_test.go b/tests/ibctesting/events_test.go index 728ba84c..b026174c 100644 --- a/tests/ibctesting/events_test.go +++ b/tests/ibctesting/events_test.go @@ -4,16 +4,22 @@ import ( "encoding/hex" "testing" + "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/require" abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" ibctst "github.com/cosmos/ibc-go/v10/testing" + + mockv1 "github.com/LumeraProtocol/lumera/tests/ibctesting/mock" + mockv2 "github.com/LumeraProtocol/lumera/tests/ibctesting/mock/v2" ) -func TestParsePacketsFromEvents(t *testing.T) { +func TestParseV1PacketsFromEvents(t *testing.T) { testCases := []struct { name string events []abci.Event @@ -112,7 +118,7 @@ func TestParsePacketsFromEvents(t *testing.T) { DestinationPort: "dstPort", DestinationChannel: "dstChannel", Data: []byte("data1"), - TimeoutHeight: types.Height{ + TimeoutHeight: clienttypes.Height{ RevisionNumber: 1, RevisionHeight: 2, }, @@ -125,7 +131,7 @@ func TestParsePacketsFromEvents(t *testing.T) { DestinationPort: "dstPort", DestinationChannel: "dstChannel", Data: []byte("data2"), - TimeoutHeight: types.Height{ + TimeoutHeight: clienttypes.Height{ RevisionNumber: 1, RevisionHeight: 3, }, @@ -199,7 +205,7 @@ func TestParsePacketsFromEvents(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - allPackets, err := ibctst.ParsePacketsFromEvents(channeltypes.EventTypeSendPacket, tc.events) + allPackets, err := ibctst.ParseIBCV1Packets(channeltypes.EventTypeSendPacket, tc.events) if tc.expectedError == "" { require.NoError(t, err) @@ -208,7 +214,7 @@ func TestParsePacketsFromEvents(t *testing.T) { require.ErrorContains(t, err, tc.expectedError) } - firstPacket, err := ibctst.ParsePacketFromEvents(tc.events) + firstPacket, err := ibctst.ParseV1PacketFromEvents(tc.events) if tc.expectedError == "" { require.NoError(t, err) @@ -219,3 +225,167 @@ func TestParsePacketsFromEvents(t *testing.T) { }) } } + +func TestParseV2PacketsFromEvents(t *testing.T) { + testCases := []struct { + name string + eventType string + events []abci.Event + expectedPackets []channeltypesv2.Packet + expectedError string + }{ + { + name: "success: One v2 packet without payload + One v2 packet with payload", + eventType: channeltypesv2.EventTypeRecvPacket, + events: []abci.Event{ + { + Type: "xxx", + }, + { + Type: channeltypesv2.EventTypeRecvPacket, + Attributes: []abci.EventAttribute{ + { + Key: channeltypesv2.AttributeKeySequence, + Value: "42", + }, + { + Key: channeltypesv2.AttributeKeySrcClient, + Value: "srcClient", + }, + { + Key: channeltypesv2.AttributeKeyDstClient, + Value: "destClient", + }, + { + Key: channeltypesv2.AttributeKeyTimeoutTimestamp, + Value: "1283798137", + }, + }, + }, + { + Type: "yyy", + }, + { + Type: channeltypesv2.EventTypeRecvPacket, + // If AttributeKeyEncodedPacketHex is present, other attributes are ignored. + Attributes: []abci.EventAttribute{ + { + Key: channeltypesv2.AttributeKeySequence, + Value: "43", + }, + { + Key: channeltypesv2.AttributeKeySrcClient, + Value: "srcClient-2", + }, + { + Key: channeltypesv2.AttributeKeyDstClient, + Value: "destClient-2", + }, + { + Key: channeltypesv2.AttributeKeyTimeoutTimestamp, + Value: "12837997475", + }, + { + Key: channeltypesv2.AttributeKeyEncodedPacketHex, + Value: func() string { + payload := mockv2.NewMockPayload(mockv2.ModuleNameA, mockv2.ModuleNameB) + packet := channeltypesv2.NewPacket(44, "srcClient", "destClient", 19474197444, payload) + encodedPacket, err := proto.Marshal(&packet) + if err != nil { + panic(err) + } + return hex.EncodeToString(encodedPacket) + }(), + }, + }, + }, + }, + expectedPackets: []channeltypesv2.Packet{ + { + Sequence: 42, + SourceClient: "srcClient", + DestinationClient: "destClient", + TimeoutTimestamp: 1283798137, + }, + { + Sequence: 44, + SourceClient: "srcClient", + DestinationClient: "destClient", + TimeoutTimestamp: 19474197444, + Payloads: []channeltypesv2.Payload{ + { + SourcePort: mockv2.ModuleNameA, + DestinationPort: mockv2.ModuleNameB, + Version: mockv1.Version, + Encoding: transfertypes.EncodingProtobuf, + Value: mockv1.MockPacketData, + }, + }, + }, + }, + }, + + { + name: "fail: no events", + eventType: channeltypesv2.EventTypeSendPacket, + events: []abci.Event{}, + expectedError: "no IBC v2 packets found in events", + }, + { + name: "fail: events without packet", + eventType: channeltypesv2.EventTypeSendPacket, + events: []abci.Event{ + { + Type: "xxx", + }, + { + Type: "yyy", + }, + }, + expectedError: "no IBC v2 packets found in events", + }, + { + name: "fail: event packet with invalid AttributeKeySequence", + eventType: channeltypesv2.EventTypeSendPacket, + events: []abci.Event{ + { + Type: channeltypesv2.EventTypeSendPacket, + Attributes: []abci.EventAttribute{ + { + Key: channeltypesv2.AttributeKeySequence, + Value: "x", + }, + }, + }, + }, + expectedError: "strconv.ParseUint: parsing \"x\": invalid syntax", + }, + { + name: "fail: event packet with invalid AttributeKeyTimeoutHeight", + eventType: channeltypesv2.EventTypeSendPacket, + events: []abci.Event{ + { + Type: channeltypesv2.EventTypeSendPacket, + Attributes: []abci.EventAttribute{ + { + Key: channeltypesv2.AttributeKeyTimeoutTimestamp, + Value: "x", + }, + }, + }, + }, + expectedError: "strconv.ParseUint: parsing \"x\": invalid syntax", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + packets, err := ibctst.ParseIBCV2Packets(tc.eventType, tc.events) + if tc.expectedError != "" { + require.ErrorContains(t, err, tc.expectedError) + return + } + require.NoError(t, err) + require.Equal(t, tc.expectedPackets, packets) + }) + } +} diff --git a/tests/ibctesting/mock/ibcmodule.go b/tests/ibctesting/mock/ibcmodule.go index 3ca4845a..32b8e060 100644 --- a/tests/ibctesting/mock/ibcmodule.go +++ b/tests/ibctesting/mock/ibcmodule.go @@ -31,6 +31,7 @@ var ( MockApplicationCallbackError error = &applicationCallbackError{} _ porttypes.IBCModule = &MockIBCModule{} + _ porttypes.PacketDataUnmarshaler = &MockIBCModule{} _ ibcexported.Path = KeyPath{} _ ibcexported.Height = Height{} ) @@ -63,7 +64,7 @@ func (m *MockIBCModule) OnChanOpenInit(ctx sdk.Context, order channeltypes.Order version = Version } - if m.IBCApp != nil && m.IBCApp.OnChanOpenInit != nil { + if m.IBCApp != nil { return m.IBCApp.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, counterparty, version) } return version, nil @@ -72,7 +73,7 @@ func (m *MockIBCModule) OnChanOpenInit(ctx sdk.Context, order channeltypes.Order func (m *MockIBCModule) OnChanOpenTry(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, counterparty channeltypes.Counterparty, counterpartyVersion string) (string, error) { - if m.IBCApp != nil && m.IBCApp.OnChanOpenTry != nil { + if m.IBCApp != nil { return m.IBCApp.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, counterparty, counterpartyVersion) } @@ -80,7 +81,7 @@ func (m *MockIBCModule) OnChanOpenTry(ctx sdk.Context, order channeltypes.Order, } func (m *MockIBCModule) OnChanOpenAck(ctx sdk.Context, portID, channelID, counterpartyChannelID, counterpartyVersion string) error { - if m.IBCApp != nil && m.IBCApp.OnChanOpenAck != nil { + if m.IBCApp != nil { return m.IBCApp.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) } @@ -88,7 +89,7 @@ func (m *MockIBCModule) OnChanOpenAck(ctx sdk.Context, portID, channelID, counte } func (m *MockIBCModule) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) error { - if m.IBCApp != nil && m.IBCApp.OnChanOpenConfirm != nil { + if m.IBCApp != nil { return m.IBCApp.OnChanOpenConfirm(ctx, portID, channelID) } @@ -96,11 +97,15 @@ func (m *MockIBCModule) OnChanOpenConfirm(ctx sdk.Context, portID, channelID str } func (m *MockIBCModule) OnChanCloseInit(ctx sdk.Context, portID, channelID string) error { - return m.IBCApp.OnChanCloseInit(ctx, portID, channelID) + if m.IBCApp != nil { + return m.IBCApp.OnChanCloseInit(ctx, portID, channelID) + } + + return nil } func (m *MockIBCModule) OnChanCloseConfirm(ctx sdk.Context, portID, channelID string) error { - if m.IBCApp != nil && m.IBCApp.OnChanCloseConfirm != nil { + if m.IBCApp != nil { return m.IBCApp.OnChanCloseConfirm(ctx, portID, channelID) } @@ -108,7 +113,7 @@ func (m *MockIBCModule) OnChanCloseConfirm(ctx sdk.Context, portID, channelID st } func (m *MockIBCModule) OnRecvPacket(ctx sdk.Context, channelVersion string, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement { - if m.IBCApp != nil && m.IBCApp.OnRecvPacket != nil { + if m.IBCApp != nil { return m.IBCApp.OnRecvPacket(ctx, channelVersion, packet, relayer) } @@ -124,7 +129,7 @@ func (m *MockIBCModule) OnRecvPacket(ctx sdk.Context, channelVersion string, pac } func (m *MockIBCModule) OnAcknowledgementPacket(ctx sdk.Context, channelVersion string, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error { - if m.IBCApp != nil && m.IBCApp.OnAcknowledgementPacket != nil { + if m.IBCApp != nil { return m.IBCApp.OnAcknowledgementPacket(ctx, channelVersion, packet, acknowledgement, relayer) } @@ -133,7 +138,7 @@ func (m *MockIBCModule) OnAcknowledgementPacket(ctx sdk.Context, channelVersion } func (m *MockIBCModule) OnTimeoutPacket(ctx sdk.Context, channelVersion string, packet channeltypes.Packet, relayer sdk.AccAddress) error { - if m.IBCApp != nil && m.IBCApp.OnTimeoutPacket != nil { + if m.IBCApp != nil { return m.IBCApp.OnTimeoutPacket(ctx, channelVersion, packet, relayer) } @@ -167,4 +172,3 @@ func (KeyPath) Empty() bool { type Height struct { ibcexported.Height } - diff --git a/tests/ibctesting/mock/mock_callbacks.go b/tests/ibctesting/mock/mock_callbacks.go index 4a9302a4..4afdd4c8 100644 --- a/tests/ibctesting/mock/mock_callbacks.go +++ b/tests/ibctesting/mock/mock_callbacks.go @@ -40,8 +40,10 @@ type MockWasmEngine struct { IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) IBCSourceCallbackFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCSourceCallbackMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) IBCDestinationCallbackFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCDestinationCallbackMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) + IBC2PacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2AcknowledgeMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) IBC2PacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2PacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) IBC2PacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2PacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) + IBC2PacketSendFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2PacketSendMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) PinFn func(checksum wasmvm.Checksum) error UnpinFn func(checksum wasmvm.Checksum) error GetMetricsFn func() (*wasmvmtypes.Metrics, error) @@ -153,12 +155,19 @@ func (m MockWasmEngine) IBCDestinationCallback(codeID wasmvm.Checksum, env wasmv } func (m *MockWasmEngine) IBC2PacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2PacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) { - if m.IBCPacketReceiveFn == nil { + if m.IBC2PacketReceiveFn == nil { panic("not supposed to be called!") } return m.IBC2PacketReceiveFn(codeID, env, msg, store, goapi, querier, gasMeter, gasLimit, deserCost) } +func (m *MockWasmEngine) IBC2PacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2AcknowledgeMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) { + if m.IBC2PacketAckFn == nil { + panic("not supposed to be called!") + } + return m.IBC2PacketAckFn(codeID, env, msg, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + func (m *MockWasmEngine) IBC2PacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2PacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) { if m.IBC2PacketTimeoutFn == nil { panic("not supposed to be called!") @@ -166,6 +175,13 @@ func (m *MockWasmEngine) IBC2PacketTimeout(codeID wasmvm.Checksum, env wasmvmtyp return m.IBC2PacketTimeoutFn(codeID, env, msg, store, goapi, querier, gasMeter, gasLimit, deserCost) } +func (m *MockWasmEngine) IBC2PacketSend(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBC2PacketSendMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResult, uint64, error) { + if m.IBC2PacketSendFn == nil { + panic("not supposed to be called!") + } + return m.IBC2PacketSendFn(codeID, env, msg, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + func (m *MockWasmEngine) StoreCode(codeID wasmvm.WasmCode, gasLimit uint64) (wasmvm.Checksum, uint64, error) { if m.StoreCodeFn == nil { panic("not supposed to be called!") @@ -223,7 +239,7 @@ func (m *MockWasmEngine) Migrate(codeID wasmvm.Checksum, env wasmvmtypes.Env, mi } func (m *MockWasmEngine) MigrateWithInfo(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, migrateInfo wasmvmtypes.MigrateInfo, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.ContractResult, uint64, error) { - if m.MigrateFn == nil { + if m.MigrateWithInfoFn == nil { panic("not supposed to be called!") } return m.MigrateWithInfoFn(codeID, env, migrateMsg, migrateInfo, store, goapi, querier, gasMeter, gasLimit, deserCost) diff --git a/tests/ibctesting/mock/v2/ibc_app.go b/tests/ibctesting/mock/v2/ibc_app.go new file mode 100644 index 00000000..9999e3bd --- /dev/null +++ b/tests/ibctesting/mock/v2/ibc_app.go @@ -0,0 +1,14 @@ +package mock + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" +) + +type IBCApp struct { + OnSendPacket func(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error + OnRecvPacket func(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult + OnTimeoutPacket func(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) error + OnAcknowledgementPacket func(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, acknowledgement []byte, relayer sdk.AccAddress) error +} diff --git a/tests/ibctesting/mock/v2/ibc_module.go b/tests/ibctesting/mock/v2/ibc_module.go new file mode 100644 index 00000000..5d5ffcbc --- /dev/null +++ b/tests/ibctesting/mock/v2/ibc_module.go @@ -0,0 +1,72 @@ +package mock + +import ( + "bytes" + + sdk "github.com/cosmos/cosmos-sdk/types" + + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/ibc-go/v10/modules/core/api" + + mockv1 "github.com/LumeraProtocol/lumera/tests/ibctesting/mock" +) + +var _ api.IBCModule = (*IBCModule)(nil) + +const ( + ModuleNameA = ModuleName + "A" + ModuleNameB = ModuleName + "B" + PortIDA = ModuleNameA + PortIDB = ModuleNameB +) + +// IBCModule is a mock implementation of the IBCModule interface +// which delegates calls to the underlying IBCApp. +type IBCModule struct { + IBCApp *IBCApp +} + +// NewIBCModule creates a new IBCModule with an underlying mock IBC application. +func NewIBCModule() IBCModule { + return IBCModule{ + IBCApp: &IBCApp{}, + } +} + +func (im IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, data channeltypesv2.Payload, signer sdk.AccAddress) error { + if im.IBCApp.OnSendPacket != nil { + return im.IBCApp.OnSendPacket(ctx, sourceChannel, destinationChannel, sequence, data, signer) + } + return nil +} + +func (im IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { + if im.IBCApp.OnRecvPacket != nil { + return im.IBCApp.OnRecvPacket(ctx, sourceChannel, destinationChannel, sequence, payload, relayer) + } + if bytes.Equal(payload.Value, mockv1.MockPacketData) { + return MockRecvPacketResult + } + return channeltypesv2.RecvPacketResult{Status: channeltypesv2.PacketStatus_Failure} +} + +func (im IBCModule) OnAcknowledgementPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, acknowledgement []byte, payload channeltypesv2.Payload, relayer sdk.AccAddress) error { + if im.IBCApp.OnAcknowledgementPacket != nil { + return im.IBCApp.OnAcknowledgementPacket(ctx, sourceChannel, destinationChannel, sequence, payload, acknowledgement, relayer) + } + return nil +} + +func (im IBCModule) OnTimeoutPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) error { + if im.IBCApp.OnTimeoutPacket != nil { + return im.IBCApp.OnTimeoutPacket(ctx, sourceChannel, destinationChannel, sequence, payload, relayer) + } + return nil +} + +func (IBCModule) UnmarshalPacketData(payload channeltypesv2.Payload) (any, error) { + if bytes.Equal(payload.Value, mockv1.MockPacketData) { + return mockv1.MockPacketData, nil + } + return nil, mockv1.MockApplicationCallbackError +} diff --git a/tests/ibctesting/mock/v2/mock.go b/tests/ibctesting/mock/v2/mock.go new file mode 100644 index 00000000..6721c419 --- /dev/null +++ b/tests/ibctesting/mock/v2/mock.go @@ -0,0 +1,37 @@ +package mock + +import ( + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + + mockv1 "github.com/LumeraProtocol/lumera/tests/ibctesting/mock" +) + +const ( + ModuleName = "mockv2" +) + +var MockRecvPacketResult = channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Success, + Acknowledgement: mockv1.MockAcknowledgement.Acknowledgement(), +} + +func NewMockPayload(sourcePort, destPort string) channeltypesv2.Payload { + return channeltypesv2.Payload{ + SourcePort: sourcePort, + DestinationPort: destPort, + Encoding: transfertypes.EncodingProtobuf, + Value: mockv1.MockPacketData, + Version: mockv1.Version, + } +} + +func NewErrorMockPayload(sourcePort, destPort string) channeltypesv2.Payload { + return channeltypesv2.Payload{ + SourcePort: sourcePort, + DestinationPort: destPort, + Encoding: transfertypes.EncodingProtobuf, + Value: mockv1.MockFailPacketData, + Version: mockv1.Version, + } +} diff --git a/tests/ibctesting/wasm.go b/tests/ibctesting/wasm.go index fdd8b804..061ea98f 100644 --- a/tests/ibctesting/wasm.go +++ b/tests/ibctesting/wasm.go @@ -40,10 +40,10 @@ type PendingAckPacketV2 struct { } func (chain *TestChain) CaptureIBCEvents(result *abci.ExecTxResult) { - toSend, _ := ibctst.ParsePacketsFromEvents(channeltypes.EventTypeSendPacket, result.Events) + toSend, _ := ibctst.ParseIBCV1Packets(channeltypes.EventTypeSendPacket, result.Events) // IBCv1 and IBCv2 `EventTypeSendPacket` are the same - // and the [`ParsePacketsFromEvents`] parses both of them as they were IBCv1 + // and ParseIBCV1Packets parses both of them as they were IBCv1 // so we have to filter them here. // // While parsing IBC2 events in IBC1 context the only overlapping event is the @@ -64,8 +64,13 @@ func (chain *TestChain) CaptureIBCEvents(result *abci.ExecTxResult) { } func (chain *TestChain) CaptureIBCEventsV2(result *abci.ExecTxResult) { - toSend, err := ParsePacketsFromEventsV2(channeltypesv2.EventTypeSendPacket, result.Events) - require.NoError(chain, err) + toSend, err := ibctst.ParseIBCV2Packets(channeltypesv2.EventTypeSendPacket, result.Events) + if err != nil { + if err.Error() == "no IBC v2 packets found in events" { + return + } + require.NoError(chain, err) + } if len(toSend) > 0 { // Keep a queue on the chain that we can relay in tests *chain.PendingSendPacketsV2 = append(*chain.PendingSendPacketsV2, toSend...) @@ -324,4 +329,3 @@ func CloseChannel(coord *Coordinator, path *Path) { _, err = dst.Chain.SendMsgs(msg) require.NoError(coord, err) } - diff --git a/tests/integration/msg_claim_integration_test.go b/tests/integration/msg_claim_integration_test.go deleted file mode 100644 index 931d77a1..00000000 --- a/tests/integration/msg_claim_integration_test.go +++ /dev/null @@ -1,222 +0,0 @@ -package integration_test - -import ( - "testing" - "time" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/suite" - - lcfg "github.com/LumeraProtocol/lumera/config" - "github.com/LumeraProtocol/lumera/x/claim/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -type MsgClaimIntegrationTestSuite struct { - suite.Suite - keeper keeper.Keeper - ctx sdk.Context - validPubKey string - validSig string - oldAddress string - newAddress string - msgServer types.MsgServer -} - -func (s *MsgClaimIntegrationTestSuite) SetupTest() { - k, ctx := keepertest.ClaimKeeper(s.T(), "") - s.keeper = k - s.ctx = ctx - s.msgServer = keeper.NewMsgServerImpl(k) - - // Set up valid test data - s.validPubKey = "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12" - s.validSig = "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3" - s.oldAddress = "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc" - s.newAddress = "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp" - - // Set up module parameters - params := types.DefaultParams() - params.EnableClaims = true - params.MaxClaimsPerBlock = 10 - params.ClaimEndTime = time.Now().Add(time.Hour).Unix() - s.Require().NoError(s.keeper.SetParams(ctx, params)) -} - -func (s *MsgClaimIntegrationTestSuite) TestClaimIntegration() { - - testAmount := int64(1_000_000) // Amount to be claimed in test cases - validFee := sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, int64(1_000))) - testCases := []struct { - name string - setup func() - msg *types.MsgClaim - expErr bool - errString string - }{ - { - name: "successful claim", - setup: func() { - // Create and store claim record - claimRecord := types.ClaimRecord{ - OldAddress: s.oldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err := s.keeper.SetClaimRecord(s.ctx, claimRecord) - s.Require().NoError(err) - - // Fund module account - err = s.keeper.GetBankKeeper().MintCoins(s.ctx, types.ModuleName, claimRecord.Balance) - s.Require().NoError(err) - }, - msg: &types.MsgClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - }, - expErr: false, - }, - { - name: "claim already processed", - setup: func() { - // Create and store claimed record - claimRecord := types.ClaimRecord{ - OldAddress: s.oldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: true, - ClaimTime: time.Now().Add(-15).Unix(), - } - err := s.keeper.SetClaimRecord(s.ctx, claimRecord) - s.Require().NoError(err) - }, - msg: &types.MsgClaim{ - OldAddress: s.oldAddress, - NewAddress: s.newAddress, - PubKey: s.validPubKey, - Signature: s.validSig, - }, - expErr: true, - errString: "claim already claimed", - }, - { - name: "claim not found", - setup: func() {}, // No setup needed - claim record doesn't exist - msg: &types.MsgClaim{ - OldAddress: "NonExistentAddress", - NewAddress: s.newAddress, - PubKey: s.validPubKey, - Signature: s.validSig, - }, - expErr: true, - errString: "claim not found", - }, - { - name: "claims disabled", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = false - s.Require().NoError(s.keeper.SetParams(s.ctx, params)) - - // Add a claim record to ensure the check happens before record lookup - claimRecord := types.ClaimRecord{ - OldAddress: s.oldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err := s.keeper.SetClaimRecord(s.ctx, claimRecord) - s.Require().NoError(err) - }, - msg: &types.MsgClaim{ - OldAddress: s.oldAddress, - NewAddress: s.newAddress, - PubKey: s.validPubKey, - Signature: s.validSig, - }, - expErr: true, - errString: "claim is disabled", - }, - { - name: "invalid signature", - setup: func() { - claimRecord := types.ClaimRecord{ - OldAddress: s.oldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err := s.keeper.SetClaimRecord(s.ctx, claimRecord) - s.Require().NoError(err) - }, - msg: &types.MsgClaim{ - OldAddress: s.oldAddress, - NewAddress: s.newAddress, - PubKey: s.validPubKey, - Signature: "invalid_signature", - }, - expErr: true, - errString: "invalid signature", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // Reset state for each test case - if tc.setup != nil { - tc.setup() - } - - // Execute claim - - // Set fee in context - s.ctx = s.ctx.WithValue(types.ClaimTxFee, validFee) - resp, err := s.msgServer.Claim(s.ctx, tc.msg) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errString) - s.Require().Nil(resp) - - // For error cases, verify record state only if it's expected to exist - if tc.name != "claim not found" { - record, found, err := s.keeper.GetClaimRecord(s.ctx, tc.msg.OldAddress) - s.Require().NoError(err) - s.Require().True(found) - if tc.name == "claim already processed" { - s.Require().True(record.Claimed) - } else { - s.Require().False(record.Claimed) - } - } - } else { - s.Require().NoError(err) - s.Require().NotNil(resp) - - // Verify claim record is updated - record, found, err := s.keeper.GetClaimRecord(s.ctx, tc.msg.OldAddress) - s.Require().NoError(err) - s.Require().True(found) - s.Require().True(record.Claimed) - s.Require().NotEqual(time.Time{}, record.ClaimTime) - - // Verify events were emitted - events := s.ctx.EventManager().Events() - s.Require().NotEmpty(events) - - found = false - for _, event := range events { - if event.Type == types.EventTypeClaimProcessed { - found = true - break - } - } - s.Require().True(found, "claim_processed event not found") - } - }) - } -} - -func TestMsgClaimIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(MsgClaimIntegrationTestSuite)) -} diff --git a/tests/integration/staking/unbonding_test.go b/tests/integration/staking/unbonding_test.go index 4bd80dc5..b8e466c9 100644 --- a/tests/integration/staking/unbonding_test.go +++ b/tests/integration/staking/unbonding_test.go @@ -8,7 +8,7 @@ import ( "cosmossdk.io/math" - "github.com/golang/mock/gomock" + "go.uber.org/mock/gomock" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/tests/integration/update_params_integration_test.go b/tests/integration/update_params_integration_test.go deleted file mode 100644 index 038eeed5..00000000 --- a/tests/integration/update_params_integration_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package integration_test - -import ( - "testing" - "time" - - "cosmossdk.io/math" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/stretchr/testify/suite" - - sdk "github.com/cosmos/cosmos-sdk/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - "github.com/LumeraProtocol/lumera/app" - claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" -) - -type IntegrationTestSuite struct { - suite.Suite - app *app.App - ctx sdk.Context - proposer sdk.AccAddress - voter sdk.AccAddress -} - -func (s *IntegrationTestSuite) SetupTest() { - s.app = app.Setup(s.T()) - s.Require().NotNil(s.app, "App initialization failed") - - s.ctx = s.app.BaseApp.NewContext(false) - s.ctx = s.ctx.WithBlockHeader(tmproto.Header{ - Height: 1, - Time: time.Now().UTC(), - ChainID: "test-chain", - }) - - s.proposer = sdk.AccAddress([]byte("proposer___________")) - s.voter = sdk.AccAddress([]byte("voter_____________")) - - s.app.AuthKeeper.SetAccount(s.ctx, s.app.AuthKeeper.NewAccountWithAddress(s.ctx, s.proposer)) - s.app.AuthKeeper.SetAccount(s.ctx, s.app.AuthKeeper.NewAccountWithAddress(s.ctx, s.voter)) - - proposerCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 1_000_000_000)) - voterCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 1_000_000_000)) - - err := s.app.BankKeeper.MintCoins(s.ctx, minttypes.ModuleName, proposerCoins.Add(voterCoins...)) - s.Require().NoError(err, "Failed to mint coins") - - err = s.app.BankKeeper.SendCoinsFromModuleToAccount(s.ctx, minttypes.ModuleName, s.proposer, proposerCoins) - s.Require().NoError(err, "Failed to send coins to proposer") - err = s.app.BankKeeper.SendCoinsFromModuleToAccount(s.ctx, minttypes.ModuleName, s.voter, voterCoins) - s.Require().NoError(err, "Failed to send coins to voter") - - valPubKey := ed25519.GenPrivKey().PubKey() - valAddr := sdk.ValAddress(s.voter) - validator, err := stakingtypes.NewValidator( - valAddr.String(), - valPubKey, - stakingtypes.Description{}, - ) - s.Require().NoError(err, "Failed to create validator") - - validator.Status = stakingtypes.Bonded - validator.Tokens = math.NewInt(1000000000) - validator.DelegatorShares = math.LegacyNewDec(1000000000) - s.app.StakingKeeper.SetValidator(s.ctx, validator) - - delegation := stakingtypes.NewDelegation(s.voter.String(), valAddr.String(), math.LegacyNewDec(1000000000)) - s.app.StakingKeeper.SetDelegation(s.ctx, delegation) - - s.app.StakingKeeper.SetValidatorByPowerIndex(s.ctx, validator) - - govParams := govv1.DefaultParams() - err = s.app.GovKeeper.Params.Set(s.ctx, govParams) - s.Require().NoError(err, "Failed to set governance parameters") - - claimParams := claimtypes.DefaultParams() - s.app.ClaimKeeper.SetParams(s.ctx, claimParams) -} - -func (s *IntegrationTestSuite) TestUpdateParamsProposal() { - initialParams := s.app.ClaimKeeper.GetParams(s.ctx) - govParams, err := s.app.GovKeeper.Params.Get(s.ctx) - s.Require().NoError(err, "Failed to get governance parameters") - - newParams := claimtypes.NewParams( - !initialParams.EnableClaims, - time.Unix(initialParams.ClaimEndTime, 0).Add(time.Hour).Unix(), - initialParams.MaxClaimsPerBlock+1, - ) - - paramChangeMsg := &claimtypes.MsgUpdateParams{ - Authority: s.app.GovKeeper.GetAuthority(), - Params: newParams, - } - - proposal, err := s.app.GovKeeper.SubmitProposal( - s.ctx, - []sdk.Msg{paramChangeMsg}, - "ipfs://CID", - "Update claim parameters", - "This proposal updates the claim module parameters", - s.proposer, - false, - ) - s.Require().NoError(err, "Failed to submit proposal") - - depositAmount := govParams.MinDeposit - err = s.app.BankKeeper.SendCoinsFromAccountToModule(s.ctx, s.proposer, govtypes.ModuleName, depositAmount) - s.Require().NoError(err, "Failed to send deposit") - - votingPeriodStart, err := s.app.GovKeeper.AddDeposit(s.ctx, proposal.Id, s.proposer, depositAmount) - s.Require().NoError(err, "Failed to add deposit") - s.Require().True(votingPeriodStart, "Proposal should enter voting period") - - proposal, err = s.app.GovKeeper.Proposals.Get(s.ctx, proposal.Id) - s.Require().NoError(err, "Failed to get proposal") - s.Require().Equal(govv1.StatusVotingPeriod, proposal.Status, "Proposal should be in voting period") - - err = s.app.GovKeeper.AddVote( - s.ctx, - proposal.Id, - s.voter, - govv1.NewNonSplitVoteOption(govv1.OptionYes), - "", - ) - s.Require().NoError(err, "Failed to add vote") - - s.ctx = s.ctx.WithBlockTime(proposal.VotingEndTime.Add(time.Hour)) - s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) - - _, burnDeposits, _, err := s.app.GovKeeper.Tally(s.ctx, proposal) - s.Require().NoError(err, "Failed to tally votes") - - proposal.Status = govv1.StatusPassed - err = s.app.GovKeeper.SetProposal(s.ctx, proposal) - s.Require().NoError(err, "Failed to set proposal status") - - proposal, err = s.app.GovKeeper.Proposals.Get(s.ctx, proposal.Id) - s.Require().NoError(err, "Failed to get proposal after processing") - - if burnDeposits { - err = s.app.GovKeeper.DeleteAndBurnDeposits(s.ctx, proposal.Id) - s.Require().NoError(err, "Failed to burn deposits") - } else { - err = s.app.GovKeeper.RefundAndDeleteDeposits(s.ctx, proposal.Id) - s.Require().NoError(err, "Failed to refund deposits") - } - - s.Require().Equal(govv1.StatusPassed, proposal.Status, "Proposal should have passed") - - msg := proposal.Messages[0].GetCachedValue().(*claimtypes.MsgUpdateParams) - s.app.ClaimKeeper.SetParams(s.ctx, msg.Params) - s.Require().NoError(err, "Failed to update claim parameters") - - updatedParams := s.app.ClaimKeeper.GetParams(s.ctx) - s.Require().Equal(msg.Params, updatedParams, "Parameters were not updated correctly") -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} diff --git a/tests/integration/wasm/common_test.go b/tests/integration/wasm/common_test.go index 7fd3603c..4a23782a 100644 --- a/tests/integration/wasm/common_test.go +++ b/tests/integration/wasm/common_test.go @@ -46,8 +46,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/crisis" - crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" "github.com/cosmos/cosmos-sdk/x/distribution" distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -251,7 +249,6 @@ var moduleBasics = module.NewBasicManager( paramsclient.ProposalHandler, }), params.AppModuleBasic{}, - crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, ibc.AppModuleBasic{}, upgrade.AppModuleBasic{}, @@ -268,7 +265,6 @@ func MakeEncodingConfig(t testing.TB) moduletestutil.TestEncodingConfig { mint.AppModule{}, slashing.AppModule{}, gov.AppModule{}, - crisis.AppModule{}, ibc.AppModule{}, ibctransfer.AppModule{}, vesting.AppModule{}, @@ -365,7 +361,6 @@ func createTestInput( minttypes.ModuleName, distributiontypes.ModuleName, slashingtypes.ModuleName, - crisistypes.ModuleName, ibctransfertypes.ModuleName, ibcexported.ModuleName, govtypes.ModuleName, @@ -481,6 +476,7 @@ func createTestInput( distributionkeeper.NewQuerier(distKeeper), ibcKeeper.ChannelKeeper, // ICS4Wrapper ibcKeeper.ChannelKeeper, + ibcKeeper.ChannelKeeperV2, ibcmock.MockIBCTransferKeeper{}, msgRouter, querier, @@ -489,7 +485,6 @@ func createTestInput( vmConfig, availableCapabilities, authtypes.NewModuleAddress(govtypes.ModuleName).String(), - nil, opts..., ) require.NoError(t, keeper.SetParams(ctx, wasmtypes.DefaultParams())) @@ -799,4 +794,4 @@ func keyPubAddr() (crypto.PrivKey, sdk.AccAddress) { pub := key.PubKey() addr := sdk.AccAddress(pub.Address()) return key, addr -} \ No newline at end of file +} diff --git a/tests/integration/wasm/genesis_test.go b/tests/integration/wasm/genesis_test.go new file mode 100644 index 00000000..d094f0bd --- /dev/null +++ b/tests/integration/wasm/genesis_test.go @@ -0,0 +1,103 @@ +package wasm_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func TestInitGenesis(t *testing.T) { + data := setupTest(t) + + deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) + topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) + creator := data.faucet.NewFundedRandomAccount(data.ctx, deposit.Add(deposit...)...) + fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...) + + msg := types.MsgStoreCode{ + Sender: creator.String(), + WASMByteCode: testContract, + } + h := data.msgServiceRouter.Handler(&msg) + q := data.grpcQueryRouter + + err := msg.ValidateBasic() + require.NoError(t, err) + + res, err := h(data.ctx, &msg) + require.NoError(t, err) + assertStoreCodeResponse(t, res.Data, 1) + + _, bob := keyPubAddr() + initMsg := initMsg{ + Verifier: fred, + Beneficiary: bob, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + instMsg := types.MsgInstantiateContract{ + Sender: creator.String(), + CodeID: firstCodeID, + Msg: initMsgBz, + Funds: deposit, + Label: "testing", + } + h = data.msgServiceRouter.Handler(&instMsg) + res, err = h(data.ctx, &instMsg) + require.NoError(t, err) + contractBech32Addr := parseInitResponse(t, res.Data) + + execMsg := types.MsgExecuteContract{ + Sender: fred.String(), + Contract: contractBech32Addr, + Msg: []byte(`{"release":{}}`), + Funds: topUp, + } + h = data.msgServiceRouter.Handler(&execMsg) + res, err = h(data.ctx, &execMsg) + require.NoError(t, err) + // from https://github.com/CosmWasm/cosmwasm/blob/master/contracts/hackatom/src/contract.rs#L167 + assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa}) + + // ensure all contract state is as after init + assertCodeList(t, q, data.ctx, 1, data.encConf.Codec) + assertCodeBytes(t, q, data.ctx, 1, testContract, data.encConf.Codec) + + assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr}, data.encConf.Codec) + assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator, data.encConf.Codec) + assertContractState(t, q, data.ctx, contractBech32Addr, state{ + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), + }, data.encConf.Codec) + + // export into genstate + genState := wasmkeeper.ExportGenesis(data.ctx, &data.keeper) + + // create new app to import genstate into + newData := setupTest(t) + q2 := newData.grpcQueryRouter + + // initialize new app with genstate + _, err = wasmkeeper.InitGenesis(newData.ctx, &newData.keeper, *genState) + require.NoError(t, err) + + // run same checks again on newdata, to make sure it was reinitialized correctly + assertCodeList(t, q2, newData.ctx, 1, data.encConf.Codec) + assertCodeBytes(t, q2, newData.ctx, 1, testContract, data.encConf.Codec) + + assertContractList(t, q2, newData.ctx, 1, []string{contractBech32Addr}, data.encConf.Codec) + assertContractInfo(t, q2, newData.ctx, contractBech32Addr, 1, creator, data.encConf.Codec) + assertContractState(t, q2, newData.ctx, contractBech32Addr, state{ + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), + }, data.encConf.Codec) +} diff --git a/tests/integration/wasm/ibc_integration_test.go b/tests/integration/wasm/ibc_integration_test.go index fea36aec..c3a13480 100644 --- a/tests/integration/wasm/ibc_integration_test.go +++ b/tests/integration/wasm/ibc_integration_test.go @@ -397,10 +397,10 @@ func TestIBCAsyncAck(t *testing.T) { path = ibctesting.NewPath(chainA, chainB) ) path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ - PortID: sourcePortID, Version: "ibc-reflect-v1", Order: channeltypes.UNORDERED, + PortID: sourcePortID, Version: "ibc-reflect-v1", Order: channeltypes.ORDERED, } path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{ - PortID: counterpartPortID, Version: "ibc-reflect-v1", Order: channeltypes.UNORDERED, + PortID: counterpartPortID, Version: "ibc-reflect-v1", Order: channeltypes.ORDERED, } path.SetupConnections() diff --git a/tests/integration/wasm/migrations_integration_test.go b/tests/integration/wasm/migrations_integration_test.go new file mode 100644 index 00000000..9810a9f1 --- /dev/null +++ b/tests/integration/wasm/migrations_integration_test.go @@ -0,0 +1,128 @@ +package wasm_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + upgradetypes "cosmossdk.io/x/upgrade/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/CosmWasm/wasmd/x/wasm/types" + + "github.com/LumeraProtocol/lumera/app" +) + +func TestModuleMigrations(t *testing.T) { + wasmApp := app.Setup(t) + + upgradeHandler := func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + return wasmApp.ModuleManager.RunMigrations(ctx, wasmApp.Configurator(), fromVM) + } + + specs := map[string]struct { + setup func(ctx sdk.Context) + startVersion uint64 + exp types.Params + }{ + "fresh from genesis": { + startVersion: wasmApp.ModuleManager.GetVersionMap()[types.ModuleName], // latest + setup: func(ctx sdk.Context) {}, + exp: types.DefaultParams(), + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx, _ := wasmApp.BaseApp.NewContext(false).CacheContext() + spec.setup(ctx) + + fromVM, err := wasmApp.UpgradeKeeper.GetModuleVersionMap(ctx) + require.NoError(t, err) + fromVM[types.ModuleName] = spec.startVersion + _, err = upgradeHandler(ctx, upgradetypes.Plan{Name: "testing"}, fromVM) + require.NoError(t, err) + + // when + gotVM, err := wasmApp.ModuleManager.RunMigrations(ctx, wasmApp.Configurator(), fromVM) + + // then + require.NoError(t, err) + var expModuleVersion uint64 = 4 + assert.Equal(t, expModuleVersion, gotVM[types.ModuleName]) + gotParams := wasmApp.WasmKeeper.GetParams(ctx) + assert.Equal(t, spec.exp, gotParams) + }) + } +} + +func TestAccessConfigMigrations(t *testing.T) { + address := sdk.AccAddress(make([]byte, types.ContractAddrLen)) + + wasmApp := app.Setup(t) + + upgradeHandler := func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + return wasmApp.ModuleManager.RunMigrations(ctx, wasmApp.Configurator(), fromVM) + } + + ctx, _ := wasmApp.BaseApp.NewContext(false).CacheContext() + + // any address permission + code1, err := storeCode(ctx, wasmApp, types.AccessTypeAnyOfAddresses.With(address)) + require.NoError(t, err) + + // allow everybody permission + code2, err := storeCode(ctx, wasmApp, types.AllowEverybody) + require.NoError(t, err) + + // allow nobody permission + code3, err := storeCode(ctx, wasmApp, types.AllowNobody) + require.NoError(t, err) + + fromVM, err := wasmApp.UpgradeKeeper.GetModuleVersionMap(ctx) + require.NoError(t, err) + fromVM[types.ModuleName] = wasmApp.ModuleManager.GetVersionMap()[types.ModuleName] + _, err = upgradeHandler(ctx, upgradetypes.Plan{Name: "testing"}, fromVM) + require.NoError(t, err) + + // when + gotVM, err := wasmApp.ModuleManager.RunMigrations(ctx, wasmApp.Configurator(), fromVM) + + // then + require.NoError(t, err) + var expModuleVersion uint64 = 4 + assert.Equal(t, expModuleVersion, gotVM[types.ModuleName]) + + // any address was not migrated + assert.Equal(t, types.AccessTypeAnyOfAddresses.With(address), wasmApp.WasmKeeper.GetCodeInfo(ctx, code1).InstantiateConfig) + + // allow everybody was not migrated + assert.Equal(t, types.AllowEverybody, wasmApp.WasmKeeper.GetCodeInfo(ctx, code2).InstantiateConfig) + + // allow nobody was not migrated + assert.Equal(t, types.AllowNobody, wasmApp.WasmKeeper.GetCodeInfo(ctx, code3).InstantiateConfig) +} + +func storeCode(ctx sdk.Context, wasmApp *app.App, instantiatePermission types.AccessConfig) (codeID uint64, err error) { + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = testContract + m.InstantiatePermission = &instantiatePermission + _, sender := keyPubAddr() + m.Sender = sender.String() + }) + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + if err != nil { + return + } + + var result types.MsgStoreCodeResponse + err = wasmApp.AppCodec().Unmarshal(rsp.Data, &result) + if err != nil { + return + } + + codeID = result.CodeID + return +} diff --git a/tests/integration/wasm/module_test.go b/tests/integration/wasm/module_test.go new file mode 100644 index 00000000..67c0e223 --- /dev/null +++ b/tests/integration/wasm/module_test.go @@ -0,0 +1,670 @@ +package wasm_test + +import ( + "bytes" + "encoding/json" + "os" + "strings" + "testing" + + abci "github.com/cometbft/cometbft/abci/types" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/cosmos/cosmos-sdk/types/module" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + + "github.com/CosmWasm/wasmd/x/wasm" + "github.com/CosmWasm/wasmd/x/wasm/exported" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/keeper/testdata" + v2 "github.com/CosmWasm/wasmd/x/wasm/migrations/v2" + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +const firstCodeID = 1 + +type mockSubspace struct { + ps v2.Params +} + +func newMockSubspace(ps v2.Params) mockSubspace { + return mockSubspace{ps: ps} +} + +func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) { + *ps.(*v2.Params) = ms.ps +} + +type testData struct { + module wasm.AppModule + ctx sdk.Context + acctKeeper authkeeper.AccountKeeper + keeper wasmkeeper.Keeper + bankKeeper bankkeeper.Keeper + stakingKeeper *stakingkeeper.Keeper + faucet *wasmkeeper.TestFaucet + grpcQueryRouter *baseapp.GRPCQueryRouter + msgServiceRouter *baseapp.MsgServiceRouter + encConf moduletestutil.TestEncodingConfig +} + +func setupTest(t *testing.T) testData { + t.Helper() + DefaultParams := v2.Params{ + CodeUploadAccess: v2.AccessConfig{Permission: v2.AccessTypeEverybody}, + InstantiateDefaultPermission: v2.AccessTypeEverybody, + } + + ctx, keepers := CreateTestInput(t, false, []string{ + "iterator", "staking", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "cosmwasm_1_3", + "cosmwasm_1_4", "cosmwasm_2_0", "cosmwasm_2_1", "cosmwasm_2_2", "ibc2", + }) + encConf := MakeEncodingConfig(t) + queryRouter := baseapp.NewGRPCQueryRouter() + serviceRouter := baseapp.NewMsgServiceRouter() + queryRouter.SetInterfaceRegistry(encConf.InterfaceRegistry) + serviceRouter.SetInterfaceRegistry(encConf.InterfaceRegistry) + data := testData{ + module: wasm.NewAppModule(encConf.Codec, keepers.WasmKeeper, keepers.StakingKeeper, keepers.AccountKeeper, keepers.BankKeeper, nil, newMockSubspace(DefaultParams)), + ctx: ctx, + acctKeeper: keepers.AccountKeeper, + keeper: *keepers.WasmKeeper, + bankKeeper: keepers.BankKeeper, + stakingKeeper: keepers.StakingKeeper, + faucet: keepers.Faucet, + grpcQueryRouter: queryRouter, + msgServiceRouter: serviceRouter, + encConf: encConf, + } + data.module.RegisterServices(module.NewConfigurator(encConf.Codec, serviceRouter, queryRouter)) + return data +} + +func mustLoad(path string) []byte { + bz, err := os.ReadFile(path) + if err != nil { + panic(err) + } + return bz +} + +var ( + addrAcc1 = func() sdk.AccAddress { + _, addr := keyPubAddr() + return addr + }() + addr1 = addrAcc1.String() + testContract = mustLoad(GetTestDataFilePath("hackatom.wasm")) + maskContract = testdata.ReflectContractWasm() + oldContract = mustLoad(GetTestDataFilePath("escrow_0.7.wasm")) +) + +func TestStoreCodeSimulation(t *testing.T) { + data := setupTest(t) + data.ctx = data.ctx.WithExecMode(sdk.ExecModeSimulate) + + msg := &types.MsgStoreCode{ + Sender: addr1, + WASMByteCode: testContract, + } + + h := data.msgServiceRouter.Handler(msg) + + _, err := h(data.ctx, msg) + require.NoError(t, err) +} + +func TestHandleCreate(t *testing.T) { + cases := map[string]struct { + msg sdk.Msg + isValid bool + }{ + "empty": { + msg: &types.MsgStoreCode{}, + isValid: false, + }, + "invalid wasm": { + msg: &types.MsgStoreCode{ + Sender: addr1, + WASMByteCode: []byte("foobar"), + }, + isValid: false, + }, + "valid wasm": { + msg: &types.MsgStoreCode{ + Sender: addr1, + WASMByteCode: testContract, + }, + isValid: true, + }, + "other valid wasm": { + msg: &types.MsgStoreCode{ + Sender: addr1, + WASMByteCode: maskContract, + }, + isValid: true, + }, + "old wasm (0.7)": { + msg: &types.MsgStoreCode{ + Sender: addr1, + WASMByteCode: oldContract, + }, + isValid: false, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + data := setupTest(t) + + h := data.msgServiceRouter.Handler(tc.msg) + // q := data.grpcQueryRouter.Route(sdk.MsgTypeURL(tc.msg)) + q := data.grpcQueryRouter + + res, err := h(data.ctx, tc.msg) + if !tc.isValid { + require.Error(t, err, "%#v", res) + assertCodeList(t, q, data.ctx, 0, data.encConf.Codec) + assertCodeBytes(t, q, data.ctx, 1, nil, data.encConf.Codec) + return + } + require.NoError(t, err) + assertCodeList(t, q, data.ctx, 1, data.encConf.Codec) + }) + } +} + +type initMsg struct { + Verifier sdk.AccAddress `json:"verifier"` + Beneficiary sdk.AccAddress `json:"beneficiary"` +} + +type state struct { + Verifier string `json:"verifier"` + Beneficiary string `json:"beneficiary"` + Funder string `json:"funder"` +} + +func TestHandleInstantiate(t *testing.T) { + data := setupTest(t) + creator := data.faucet.NewFundedRandomAccount(data.ctx, sdk.NewInt64Coin("denom", 100000)) + + msg := &types.MsgStoreCode{ + Sender: creator.String(), + WASMByteCode: testContract, + } + + h := data.msgServiceRouter.Handler(msg) + q := data.grpcQueryRouter + + res, err := h(data.ctx, msg) + require.NoError(t, err) + assertStoreCodeResponse(t, res.Data, 1) + + _, bob := keyPubAddr() + _, fred := keyPubAddr() + + initPayload := initMsg{ + Verifier: fred, + Beneficiary: bob, + } + initMsgBz, err := json.Marshal(initPayload) + require.NoError(t, err) + + // create with no balance is also legal + initMsg := &types.MsgInstantiateContract{ + Sender: creator.String(), + CodeID: firstCodeID, + Msg: initMsgBz, + Funds: nil, + Label: "testing", + } + h = data.msgServiceRouter.Handler(initMsg) + res, err = h(data.ctx, initMsg) + require.NoError(t, err) + contractBech32Addr := parseInitResponse(t, res.Data) + + // this should be standard x/wasm init event, nothing from contract + require.Equal(t, 2, len(res.Events), prettyEvents(res.Events)) + require.Equal(t, "instantiate", res.Events[0].Type) + require.Equal(t, "wasm", res.Events[1].Type) + assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[1].Attributes[0]) + + assertCodeList(t, q, data.ctx, 1, data.encConf.Codec) + assertCodeBytes(t, q, data.ctx, 1, testContract, data.encConf.Codec) + + assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr}, data.encConf.Codec) + assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator, data.encConf.Codec) + assertContractState(t, q, data.ctx, contractBech32Addr, state{ + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), + }, data.encConf.Codec) +} + +func TestHandleExecute(t *testing.T) { + data := setupTest(t) + + deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) + topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) + + creator := data.faucet.NewFundedRandomAccount(data.ctx, deposit.Add(deposit...)...) + fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...) + + msg := &types.MsgStoreCode{ + Sender: creator.String(), + WASMByteCode: testContract, + } + h := data.msgServiceRouter.Handler(msg) + q := data.grpcQueryRouter + res, err := h(data.ctx, msg) + require.NoError(t, err) + assertStoreCodeResponse(t, res.Data, 1) + + _, bob := keyPubAddr() + initMsg := initMsg{ + Verifier: fred, + Beneficiary: bob, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + initCmd := &types.MsgInstantiateContract{ + Sender: creator.String(), + CodeID: firstCodeID, + Msg: initMsgBz, + Funds: deposit, + Label: "testing", + } + h = data.msgServiceRouter.Handler(initCmd) + res, err = h(data.ctx, initCmd) + require.NoError(t, err) + contractBech32Addr := parseInitResponse(t, res.Data) + + // this should be standard x/wasm message event, init event, plus a bank send event (2), with no custom contract events + require.Equal(t, 5, len(res.Events), prettyEvents(res.Events)) + require.Equal(t, "coin_spent", res.Events[0].Type) + require.Equal(t, "coin_received", res.Events[1].Type) + require.Equal(t, "transfer", res.Events[2].Type) + require.Equal(t, "instantiate", res.Events[3].Type) + require.Equal(t, "wasm", res.Events[4].Type) + assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[4].Attributes[0]) + + // ensure bob doesn't exist + bobAcct := data.acctKeeper.GetAccount(data.ctx, bob) + require.Nil(t, bobAcct) + + // ensure funder has reduced balance + creatorAcct := data.acctKeeper.GetAccount(data.ctx, creator) + require.NotNil(t, creatorAcct) + // we started at 2*deposit, should have spent one above + assert.Equal(t, deposit, data.bankKeeper.GetAllBalances(data.ctx, creatorAcct.GetAddress())) + + // ensure contract has updated balance + contractAddr, _ := sdk.AccAddressFromBech32(contractBech32Addr) + contractAcct := data.acctKeeper.GetAccount(data.ctx, contractAddr) + require.NotNil(t, contractAcct) + assert.Equal(t, deposit, data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress())) + + execCmd := &types.MsgExecuteContract{ + Sender: fred.String(), + Contract: contractBech32Addr, + Msg: []byte(`{"release":{}}`), + Funds: topUp, + } + h = data.msgServiceRouter.Handler(execCmd) + res, err = h(data.ctx, execCmd) + require.NoError(t, err) + // from https://github.com/CosmWasm/cosmwasm/blob/master/contracts/hackatom/src/contract.rs#L167 + assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa}) + + // this should be standard message event, plus x/wasm init event, plus 2 bank send event, plus a special event from the contract + require.Equal(t, 9, len(res.Events), prettyEvents(res.Events)) + + assert.Equal(t, "coin_spent", res.Events[0].Type) + assert.Equal(t, "coin_received", res.Events[1].Type) + + require.Equal(t, "transfer", res.Events[2].Type) + require.Len(t, res.Events[2].Attributes, 3) + assertAttribute(t, "recipient", contractBech32Addr, res.Events[2].Attributes[0]) + assertAttribute(t, "sender", fred.String(), res.Events[2].Attributes[1]) + assertAttribute(t, "amount", "5000denom", res.Events[2].Attributes[2]) + + assert.Equal(t, "execute", res.Events[3].Type) + + // custom contract event attribute + assert.Equal(t, "wasm", res.Events[4].Type) + assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[4].Attributes[0]) + assertAttribute(t, "action", "release", res.Events[4].Attributes[1]) + // custom contract event + assert.Equal(t, "wasm-hackatom", res.Events[5].Type) + assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[5].Attributes[0]) + assertAttribute(t, "action", "release", res.Events[5].Attributes[1]) + // second transfer (this without conflicting message) + assert.Equal(t, "coin_spent", res.Events[6].Type) + assert.Equal(t, "coin_received", res.Events[7].Type) + + assert.Equal(t, "transfer", res.Events[8].Type) + assertAttribute(t, "recipient", bob.String(), res.Events[8].Attributes[0]) + assertAttribute(t, "sender", contractBech32Addr, res.Events[8].Attributes[1]) + assertAttribute(t, "amount", "105000denom", res.Events[8].Attributes[2]) + // finally, standard x/wasm tag + + // ensure bob now exists and got both payments released + bobAcct = data.acctKeeper.GetAccount(data.ctx, bob) + require.NotNil(t, bobAcct) + balance := data.bankKeeper.GetAllBalances(data.ctx, bobAcct.GetAddress()) + assert.Equal(t, deposit.Add(topUp...), balance) + + // ensure contract has updated balance + + contractAcct = data.acctKeeper.GetAccount(data.ctx, contractAddr) + require.NotNil(t, contractAcct) + assert.Equal(t, sdk.Coins{}, data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress())) + + // ensure all contract state is as after init + assertCodeList(t, q, data.ctx, 1, data.encConf.Codec) + assertCodeBytes(t, q, data.ctx, 1, testContract, data.encConf.Codec) + + assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr}, data.encConf.Codec) + assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator, data.encConf.Codec) + assertContractState(t, q, data.ctx, contractBech32Addr, state{ + Verifier: fred.String(), + Beneficiary: bob.String(), + Funder: creator.String(), + }, data.encConf.Codec) +} + +func TestHandleExecuteEscrow(t *testing.T) { + data := setupTest(t) + + deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) + topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) + creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len)) + data.faucet.Fund(data.ctx, creator, sdk.NewInt64Coin("denom", 100000)) + fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...) + + msg := &types.MsgStoreCode{ + Sender: creator.String(), + WASMByteCode: testContract, + } + + h := data.msgServiceRouter.Handler(msg) + _, err := h(data.ctx, msg) + require.NoError(t, err) + + _, bob := keyPubAddr() + initMsg := map[string]interface{}{ + "verifier": fred.String(), + "beneficiary": bob.String(), + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + initCmd := types.MsgInstantiateContract{ + Sender: creator.String(), + CodeID: firstCodeID, + Msg: initMsgBz, + Funds: deposit, + Label: "testing", + } + h = data.msgServiceRouter.Handler(&initCmd) + res, err := h(data.ctx, &initCmd) + require.NoError(t, err) + contractBech32Addr := parseInitResponse(t, res.Data) + handleMsg := map[string]interface{}{ + "release": map[string]interface{}{}, + } + handleMsgBz, err := json.Marshal(handleMsg) + require.NoError(t, err) + + execCmd := types.MsgExecuteContract{ + Sender: fred.String(), + Contract: contractBech32Addr, + Msg: handleMsgBz, + Funds: topUp, + } + h = data.msgServiceRouter.Handler(&execCmd) + res, err = h(data.ctx, &execCmd) + require.NoError(t, err) + // from https://github.com/CosmWasm/cosmwasm/blob/master/contracts/hackatom/src/contract.rs#L167 + assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa}) + + // ensure bob now exists and got both payments released + bobAcct := data.acctKeeper.GetAccount(data.ctx, bob) + require.NotNil(t, bobAcct) + balance := data.bankKeeper.GetAllBalances(data.ctx, bobAcct.GetAddress()) + assert.Equal(t, deposit.Add(topUp...), balance) + + // ensure contract has updated balance + contractAddr, _ := sdk.AccAddressFromBech32(contractBech32Addr) + contractAcct := data.acctKeeper.GetAccount(data.ctx, contractAddr) + require.NotNil(t, contractAcct) + assert.Equal(t, sdk.Coins{}, data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress())) +} + +func TestReadNodeConfig(t *testing.T) { + withViper := func(s string) *viper.Viper { + v := viper.New() + v.SetConfigType("toml") + require.NoError(t, v.ReadConfig(strings.NewReader(s))) + return v + } + var one uint64 = 1 + defaults := types.DefaultNodeConfig() + + specs := map[string]struct { + src servertypes.AppOptions + exp types.NodeConfig + }{ + "set query gas limit via opts": { + src: AppOptionsMock{ + "wasm.query_gas_limit": 1, + }, + exp: types.NodeConfig{ + SmartQueryGasLimit: 1, + MemoryCacheSize: defaults.MemoryCacheSize, + }, + }, + "set cache via opts": { + src: AppOptionsMock{ + "wasm.memory_cache_size": 2, + }, + exp: types.NodeConfig{ + MemoryCacheSize: 2, + SmartQueryGasLimit: defaults.SmartQueryGasLimit, + }, + }, + "set debug via opts": { + src: AppOptionsMock{ + "trace": true, + }, + exp: types.NodeConfig{ + SmartQueryGasLimit: defaults.SmartQueryGasLimit, + MemoryCacheSize: defaults.MemoryCacheSize, + ContractDebugMode: true, + }, + }, + "all defaults when no options set": { + src: AppOptionsMock{}, + exp: defaults, + }, + "default config template values": { + src: withViper(types.DefaultConfigTemplate()), + exp: defaults, + }, + "custom config template values": { + src: withViper(types.ConfigTemplate(types.NodeConfig{ + SimulationGasLimit: &one, + SmartQueryGasLimit: 2, + MemoryCacheSize: 3, + })), + exp: types.NodeConfig{ + SimulationGasLimit: &one, + SmartQueryGasLimit: 2, + MemoryCacheSize: 3, + ContractDebugMode: false, + }, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + got, err := wasm.ReadNodeConfig(spec.src) + require.NoError(t, err) + assert.Equal(t, spec.exp, got) + }) + } +} + +type AppOptionsMock map[string]interface{} + +func (a AppOptionsMock) Get(s string) interface{} { + return a[s] +} + +type prettyEvent struct { + Type string + Attr []sdk.Attribute +} + +func prettyEvents(evts []abci.Event) string { + res := make([]prettyEvent, len(evts)) + for i, e := range evts { + res[i] = prettyEvent{ + Type: e.Type, + Attr: prettyAttrs(e.Attributes), + } + } + bz, err := json.MarshalIndent(res, "", " ") + if err != nil { + panic(err) + } + return string(bz) +} + +func prettyAttrs(attrs []abci.EventAttribute) []sdk.Attribute { + pretty := make([]sdk.Attribute, len(attrs)) + for i, a := range attrs { + pretty[i] = prettyAttr(a) + } + return pretty +} + +func prettyAttr(attr abci.EventAttribute) sdk.Attribute { + return sdk.NewAttribute(attr.Key, attr.Value) +} + +func assertAttribute(t *testing.T, key, value string, attr abci.EventAttribute) { + t.Helper() + assert.Equal(t, key, attr.Key, prettyAttr(attr)) + assert.Equal(t, value, attr.Value, prettyAttr(attr)) +} + +func assertCodeList(t *testing.T, q *baseapp.GRPCQueryRouter, ctx sdk.Context, expectedNum int, marshaler codec.Codec) { + t.Helper() + path := "/cosmwasm.wasm.v1.Query/Codes" + resp, sdkerr := q.Route(path)(ctx, &abci.RequestQuery{Path: path}) + require.NoError(t, sdkerr) + require.True(t, resp.IsOK()) + + bz := resp.Value + if len(bz) == 0 { + require.Equal(t, expectedNum, 0) + return + } + + var res types.QueryCodesResponse + require.NoError(t, marshaler.Unmarshal(bz, &res)) + assert.Equal(t, expectedNum, len(res.CodeInfos)) +} + +func assertCodeBytes(t *testing.T, q *baseapp.GRPCQueryRouter, ctx sdk.Context, codeID uint64, expectedBytes []byte, marshaler codec.Codec) { + t.Helper() + bz, err := marshaler.Marshal(&types.QueryCodeRequest{CodeId: codeID}) + require.NoError(t, err) + + path := "/cosmwasm.wasm.v1.Query/Code" + resp, err := q.Route(path)(ctx, &abci.RequestQuery{Path: path, Data: bz}) + if len(expectedBytes) == 0 { + require.Equal(t, types.ErrNoSuchCodeFn(codeID).Wrapf("code id %d", codeID).Error(), err.Error()) + return + } + require.NoError(t, err) + require.True(t, resp.IsOK()) + bz = resp.Value + + var rsp types.QueryCodeResponse + require.NoError(t, marshaler.Unmarshal(bz, &rsp)) + assert.Equal(t, expectedBytes, rsp.Data) +} + +func assertContractList(t *testing.T, q *baseapp.GRPCQueryRouter, ctx sdk.Context, codeID uint64, expContractAddrs []string, marshaler codec.Codec) { + t.Helper() + bz, err := marshaler.Marshal(&types.QueryContractsByCodeRequest{CodeId: codeID}) + require.NoError(t, err) + + path := "/cosmwasm.wasm.v1.Query/ContractsByCode" + resp, sdkerr := q.Route(path)(ctx, &abci.RequestQuery{Path: path, Data: bz}) + if len(expContractAddrs) == 0 { + assert.ErrorIs(t, err, types.ErrNotFound) + return + } + require.NoError(t, sdkerr) + require.True(t, resp.IsOK()) + bz = resp.Value + + var rsp types.QueryContractsByCodeResponse + require.NoError(t, marshaler.Unmarshal(bz, &rsp)) + + hasAddrs := make([]string, len(rsp.Contracts)) + for i, r := range rsp.Contracts { //nolint:gosimple + hasAddrs[i] = r + } + assert.Equal(t, expContractAddrs, hasAddrs) +} + +func assertContractState(t *testing.T, q *baseapp.GRPCQueryRouter, ctx sdk.Context, contractBech32Addr string, expected state, marshaler codec.Codec) { + t.Helper() + bz, err := marshaler.Marshal(&types.QueryRawContractStateRequest{Address: contractBech32Addr, QueryData: []byte("config")}) + require.NoError(t, err) + + path := "/cosmwasm.wasm.v1.Query/RawContractState" + resp, sdkerr := q.Route(path)(ctx, &abci.RequestQuery{Path: path, Data: bz}) + require.NoError(t, sdkerr) + require.True(t, resp.IsOK()) + bz = resp.Value + + var rsp types.QueryRawContractStateResponse + require.NoError(t, marshaler.Unmarshal(bz, &rsp)) + expectedBz, err := json.Marshal(expected) + require.NoError(t, err) + assert.Equal(t, expectedBz, rsp.Data) +} + +func assertContractInfo(t *testing.T, q *baseapp.GRPCQueryRouter, ctx sdk.Context, contractBech32Addr string, codeID uint64, creator sdk.AccAddress, marshaler codec.Codec) { + t.Helper() + bz, err := marshaler.Marshal(&types.QueryContractInfoRequest{Address: contractBech32Addr}) + require.NoError(t, err) + + path := "/cosmwasm.wasm.v1.Query/ContractInfo" + resp, sdkerr := q.Route(path)(ctx, &abci.RequestQuery{Path: path, Data: bz}) + require.NoError(t, sdkerr) + require.True(t, resp.IsOK()) + bz = resp.Value + + var rsp types.QueryContractInfoResponse + require.NoError(t, marshaler.Unmarshal(bz, &rsp)) + + assert.Equal(t, codeID, rsp.CodeID) + assert.Equal(t, creator.String(), rsp.Creator) +} diff --git a/tests/integration/wasm/msg_server_integration_test.go b/tests/integration/wasm/msg_server_integration_test.go new file mode 100644 index 00000000..a004d968 --- /dev/null +++ b/tests/integration/wasm/msg_server_integration_test.go @@ -0,0 +1,1224 @@ +package wasm_test + +import ( + "encoding/json" + "testing" + "time" + + wasmvm "github.com/CosmWasm/wasmvm/v3" + wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/types" + + "github.com/LumeraProtocol/lumera/app" +) + +var reflectContract = mustLoad(GetTestDataFilePath("reflect_1_5.wasm")) + +func TestStoreCode(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContext(false) + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = reflectContract + m.Sender = sender.String() + }) + + // when + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + + // then + require.NoError(t, err) + var result types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + assert.Equal(t, uint64(1), result.CodeID) + + expHash, err := wasmvm.CreateChecksum(reflectContract) + require.NoError(t, err) + assert.Equal(t, expHash[:], wasmvmtypes.Checksum(result.Checksum)) + // and + info := wasmApp.WasmKeeper.GetCodeInfo(ctx, 1) + assert.NotNil(t, info) + assert.Equal(t, expHash[:], wasmvmtypes.Checksum(info.CodeHash)) + assert.Equal(t, sender.String(), info.Creator) + assert.Equal(t, types.DefaultParams().InstantiateDefaultPermission.With(sender), info.InstantiateConfig) +} + +func TestUpdateParams(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContext(false) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + oneAddressAccessConfig = types.AccessTypeAnyOfAddresses.With(myAddress) + govAuthority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + src types.MsgUpdateParams + expUploadConfig types.AccessConfig + expInstantiateType types.AccessType + }{ + "update upload permission param": { + src: types.MsgUpdateParams{ + Authority: govAuthority, + Params: types.Params{ + CodeUploadAccess: types.AllowNobody, + InstantiateDefaultPermission: types.AccessTypeEverybody, + }, + }, + expUploadConfig: types.AllowNobody, + expInstantiateType: types.AccessTypeEverybody, + }, + "update upload permission with same as current value": { + src: types.MsgUpdateParams{ + Authority: govAuthority, + Params: types.Params{ + CodeUploadAccess: types.AllowEverybody, + InstantiateDefaultPermission: types.AccessTypeEverybody, + }, + }, + expUploadConfig: types.AllowEverybody, + expInstantiateType: types.AccessTypeEverybody, + }, + "update upload permission param with address": { + src: types.MsgUpdateParams{ + Authority: govAuthority, + Params: types.Params{ + CodeUploadAccess: oneAddressAccessConfig, + InstantiateDefaultPermission: types.AccessTypeEverybody, + }, + }, + expUploadConfig: oneAddressAccessConfig, + expInstantiateType: types.AccessTypeEverybody, + }, + "update instantiate param": { + src: types.MsgUpdateParams{ + Authority: govAuthority, + Params: types.Params{ + CodeUploadAccess: types.AllowEverybody, + InstantiateDefaultPermission: types.AccessTypeNobody, + }, + }, + expUploadConfig: types.AllowEverybody, + expInstantiateType: types.AccessTypeNobody, + }, + "update instantiate param as default": { + src: types.MsgUpdateParams{ + Authority: govAuthority, + Params: types.Params{ + CodeUploadAccess: types.AllowEverybody, + InstantiateDefaultPermission: types.AccessTypeEverybody, + }, + }, + expUploadConfig: types.AllowEverybody, + expInstantiateType: types.AccessTypeEverybody, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + err := wasmApp.WasmKeeper.SetParams(ctx, types.DefaultParams()) + require.NoError(t, err) + + // when + rsp, err := wasmApp.MsgServiceRouter().Handler(&spec.src)(ctx, &spec.src) //nolint:gosec + require.NoError(t, err) + var result types.MsgUpdateParamsResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + + // then + assert.True(t, spec.expUploadConfig.Equals(wasmApp.WasmKeeper.GetParams(ctx).CodeUploadAccess), + "got %#v not %#v", wasmApp.WasmKeeper.GetParams(ctx).CodeUploadAccess, spec.expUploadConfig) + assert.Equal(t, spec.expInstantiateType, wasmApp.WasmKeeper.GetParams(ctx).InstantiateDefaultPermission) + }) + } +} + +func TestAddCodeUploadParamsAddresses(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContext(false) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + otherAddr = func() sdk.AccAddress { _, addr := keyPubAddr(); return addr }() + govAuthority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + src types.MsgAddCodeUploadParamsAddresses + uploadConfig types.AccessConfig + expUploadConfig types.AccessConfig + expErr bool + }{ + "authority can add addresses when permission is any of addresses": { + src: types.MsgAddCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + }, + "add existing address": { + src: types.MsgAddCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{myAddress.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + }, + "authority cannot add addresses when permission is allow everybody": { + src: types.MsgAddCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AllowEverybody, + expUploadConfig: types.AllowEverybody, + expErr: true, + }, + "authority cannot add addresses when permission is allow nobody": { + src: types.MsgAddCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AllowNobody, + expUploadConfig: types.AllowNobody, + expErr: true, + }, + "authority cannot add duplicate addresses when permission is any of addresses": { + src: types.MsgAddCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String(), otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + expErr: true, + }, + "other address cannot add addresses when permission is any of addresses": { + src: types.MsgAddCodeUploadParamsAddresses{ + Authority: otherAddr.String(), + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + err := wasmApp.WasmKeeper.SetParams(ctx, types.Params{ + CodeUploadAccess: spec.uploadConfig, + InstantiateDefaultPermission: types.AccessTypeEverybody, + }) + require.NoError(t, err) + + // when + rsp, err := wasmApp.MsgServiceRouter().Handler(&spec.src)(ctx, &spec.src) //nolint:gosec + if spec.expErr { + require.Error(t, err) + require.Nil(t, rsp) + return + } + require.NoError(t, err) + require.Len(t, rsp.MsgResponses, 1) + assert.IsType(t, rsp.MsgResponses[0].GetCachedValue(), &types.MsgAddCodeUploadParamsAddressesResponse{}) + + // then + gotUploadConfig := wasmApp.WasmKeeper.GetParams(ctx).CodeUploadAccess + assert.True(t, spec.expUploadConfig.Equals(gotUploadConfig), + "got %#v not %#v", gotUploadConfig, spec.expUploadConfig) + }) + } +} + +func TestRemoveCodeUploadParamsAddresses(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContext(false) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + otherAddr = func() sdk.AccAddress { _, addr := keyPubAddr(); return addr }() + govAuthority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + src types.MsgRemoveCodeUploadParamsAddresses + uploadConfig types.AccessConfig + expUploadConfig types.AccessConfig + expErr bool + }{ + "authority can remove addresses when permission is any of addresses": { + src: types.MsgRemoveCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + }, + "authority cannot remove not existing addresses when permission is any of addresses": { + src: types.MsgRemoveCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress), + }, + "authority cannot remove addresses when permission is allow everybody": { + src: types.MsgRemoveCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AllowEverybody, + expUploadConfig: types.AllowEverybody, + expErr: true, + }, + "authority cannot remove addresses when permission is allow nobody": { + src: types.MsgRemoveCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AllowNobody, + expUploadConfig: types.AllowNobody, + expErr: true, + }, + "authority cannot remove duplicate addresses when permission is any of addresses": { + src: types.MsgRemoveCodeUploadParamsAddresses{ + Authority: govAuthority, + Addresses: []string{otherAddr.String(), otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + expErr: true, + }, + "other address cannot remove addresses when permission is any of addresses": { + src: types.MsgRemoveCodeUploadParamsAddresses{ + Authority: otherAddr.String(), + Addresses: []string{otherAddr.String()}, + }, + uploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + expUploadConfig: types.AccessTypeAnyOfAddresses.With(myAddress, otherAddr), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + err := wasmApp.WasmKeeper.SetParams(ctx, types.Params{ + CodeUploadAccess: spec.uploadConfig, + InstantiateDefaultPermission: types.AccessTypeEverybody, + }) + require.NoError(t, err) + + // when + rsp, err := wasmApp.MsgServiceRouter().Handler(&spec.src)(ctx, &spec.src) //nolint:gosec + if spec.expErr { + require.Error(t, err) + require.Nil(t, rsp) + return + } + require.NoError(t, err) + require.Len(t, rsp.MsgResponses, 1) + assert.IsType(t, rsp.MsgResponses[0].GetCachedValue(), &types.MsgRemoveCodeUploadParamsAddressesResponse{}) + + // then + gotUploadConfig := wasmApp.WasmKeeper.GetParams(ctx).CodeUploadAccess + assert.True(t, spec.expUploadConfig.Equals(gotUploadConfig), + "got %#v not %#v", gotUploadConfig, spec.expUploadConfig) + }) + } +} + +func TestPinCodes(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContext(false) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + expErr bool + }{ + "authority can pin codes": { + addr: authority, + expErr: false, + }, + "other address cannot pin codes": { + addr: myAddress.String(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = reflectContract + m.Sender = sender.String() + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var result types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + require.False(t, wasmApp.WasmKeeper.IsPinnedCode(ctx, result.CodeID)) + + // when + msgPinCodes := &types.MsgPinCodes{ + Authority: spec.addr, + CodeIDs: []uint64{result.CodeID}, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgPinCodes)(ctx, msgPinCodes) + + // then + if spec.expErr { + require.Error(t, err) + assert.False(t, wasmApp.WasmKeeper.IsPinnedCode(ctx, result.CodeID)) + } else { + require.NoError(t, err) + assert.True(t, wasmApp.WasmKeeper.IsPinnedCode(ctx, result.CodeID)) + } + }) + } +} + +func TestUnpinCodes(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContext(false) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + expErr bool + }{ + "authority can unpin codes": { + addr: authority, + expErr: false, + }, + "other address cannot unpin codes": { + addr: myAddress.String(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = reflectContract + m.Sender = sender.String() + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var result types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + + // pin code + msgPin := &types.MsgPinCodes{ + Authority: authority, + CodeIDs: []uint64{result.CodeID}, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgPin)(ctx, msgPin) + require.NoError(t, err) + assert.True(t, wasmApp.WasmKeeper.IsPinnedCode(ctx, result.CodeID)) + + // when + msgUnpinCodes := &types.MsgUnpinCodes{ + Authority: spec.addr, + CodeIDs: []uint64{result.CodeID}, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgUnpinCodes)(ctx, msgUnpinCodes) + + // then + if spec.expErr { + require.Error(t, err) + assert.True(t, wasmApp.WasmKeeper.IsPinnedCode(ctx, result.CodeID)) + } else { + require.NoError(t, err) + assert.False(t, wasmApp.WasmKeeper.IsPinnedCode(ctx, result.CodeID)) + } + }) + } +} + +func TestSudoContract(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + type StealMsg struct { + Recipient string `json:"recipient"` + Amount []sdk.Coin `json:"amount"` + } + + stealMsg := struct { + Steal StealMsg `json:"steal_funds"` + }{Steal: StealMsg{ + Recipient: myAddress.String(), + Amount: []sdk.Coin{}, + }} + + stealMsgBz, err := json.Marshal(stealMsg) + require.NoError(t, err) + + specs := map[string]struct { + addr string + expErr bool + }{ + "authority can call sudo on a contract": { + addr: authority, + expErr: false, + }, + "other address cannot call sudo on a contract": { + addr: myAddress.String(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = testContract + m.Sender = sender.String() + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var storeCodeResponse types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &storeCodeResponse)) + + // instantiate contract + initMsg := keeper.HackatomExampleInitMsg{ + Verifier: sender, + Beneficiary: myAddress, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + msgInstantiate := &types.MsgInstantiateContract{ + Sender: sender.String(), + Admin: sender.String(), + CodeID: storeCodeResponse.CodeID, + Label: "test", + Msg: initMsgBz, + Funds: sdk.Coins{}, + } + rsp, err = wasmApp.MsgServiceRouter().Handler(msgInstantiate)(ctx, msgInstantiate) + require.NoError(t, err) + var instantiateResponse types.MsgInstantiateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &instantiateResponse)) + + // when + msgSudoContract := &types.MsgSudoContract{ + Authority: spec.addr, + Msg: stealMsgBz, + Contract: instantiateResponse.Address, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgSudoContract)(ctx, msgSudoContract) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestStoreAndInstantiateContract(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + permission *types.AccessConfig + expErr bool + }{ + "authority can store and instantiate a contract when permission is nobody": { + addr: authority, + permission: &types.AllowNobody, + expErr: false, + }, + "other address cannot store and instantiate a contract when permission is nobody": { + addr: myAddress.String(), + permission: &types.AllowNobody, + expErr: true, + }, + "authority can store and instantiate a contract when permission is everybody": { + addr: authority, + permission: &types.AllowEverybody, + expErr: false, + }, + "other address can store and instantiate a contract when permission is everybody": { + addr: myAddress.String(), + permission: &types.AllowEverybody, + expErr: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // when + msg := &types.MsgStoreAndInstantiateContract{ + Authority: spec.addr, + WASMByteCode: reflectContract, + InstantiatePermission: spec.permission, + Admin: myAddress.String(), + UnpinCode: false, + Label: "test", + Msg: []byte(`{}`), + Funds: sdk.Coins{}, + } + _, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestUpdateAdmin(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + otherAddr = func() sdk.AccAddress { _, addr := keyPubAddr(); return addr }() + ) + + specs := map[string]struct { + addr string + expErr bool + }{ + "authority can update admin": { + addr: authority, + expErr: false, + }, + "admin can update admin": { + addr: myAddress.String(), + expErr: false, + }, + "other address cannot update admin": { + addr: otherAddr.String(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + _, newAdmin := keyPubAddr() + + // setup + msg := &types.MsgStoreAndInstantiateContract{ + Authority: spec.addr, + WASMByteCode: reflectContract, + InstantiatePermission: &types.AllowEverybody, + Admin: myAddress.String(), + UnpinCode: false, + Label: "test", + Msg: []byte(`{}`), + Funds: sdk.Coins{}, + } + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var storeAndInstantiateResponse types.MsgStoreAndInstantiateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &storeAndInstantiateResponse)) + + // when + msgUpdateAdmin := &types.MsgUpdateAdmin{ + Sender: spec.addr, + NewAdmin: newAdmin.String(), + Contract: storeAndInstantiateResponse.Address, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgUpdateAdmin)(ctx, msgUpdateAdmin) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestClearAdmin(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + otherAddr = func() sdk.AccAddress { _, addr := keyPubAddr(); return addr }() + ) + + specs := map[string]struct { + addr string + expErr bool + }{ + "authority can clear admin": { + addr: authority, + expErr: false, + }, + "admin can clear admin": { + addr: myAddress.String(), + expErr: false, + }, + "other address cannot clear admin": { + addr: otherAddr.String(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + msg := &types.MsgStoreAndInstantiateContract{ + Authority: spec.addr, + WASMByteCode: reflectContract, + InstantiatePermission: &types.AllowEverybody, + Admin: myAddress.String(), + UnpinCode: false, + Label: "test", + Msg: []byte(`{}`), + Funds: sdk.Coins{}, + } + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var storeAndInstantiateResponse types.MsgStoreAndInstantiateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &storeAndInstantiateResponse)) + + // when + msgClearAdmin := &types.MsgClearAdmin{ + Sender: spec.addr, + Contract: storeAndInstantiateResponse.Address, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgClearAdmin)(ctx, msgClearAdmin) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMigrateContract(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + otherAddr = func() sdk.AccAddress { _, addr := keyPubAddr(); return addr }() + ) + + specs := map[string]struct { + addr string + expErr bool + }{ + "authority can migrate a contract": { + addr: authority, + expErr: false, + }, + "admin can migrate a contract": { + addr: myAddress.String(), + expErr: false, + }, + "other address cannot migrate a contract": { + addr: otherAddr.String(), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = testContract + m.Sender = sender.String() + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var storeCodeResponse types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &storeCodeResponse)) + + // instantiate contract + initMsg := keeper.HackatomExampleInitMsg{ + Verifier: sender, + Beneficiary: myAddress, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + msgInstantiate := &types.MsgInstantiateContract{ + Sender: sender.String(), + Admin: myAddress.String(), + CodeID: storeCodeResponse.CodeID, + Label: "test", + Msg: initMsgBz, + Funds: sdk.Coins{}, + } + rsp, err = wasmApp.MsgServiceRouter().Handler(msgInstantiate)(ctx, msgInstantiate) + require.NoError(t, err) + var instantiateResponse types.MsgInstantiateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &instantiateResponse)) + + // when + migMsg := struct { + Verifier sdk.AccAddress `json:"verifier"` + }{Verifier: myAddress} + migMsgBz, err := json.Marshal(migMsg) + require.NoError(t, err) + msgMigrateContract := &types.MsgMigrateContract{ + Sender: spec.addr, + Msg: migMsgBz, + Contract: instantiateResponse.Address, + CodeID: storeCodeResponse.CodeID, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgMigrateContract)(ctx, msgMigrateContract) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestInstantiateContract(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + permission *types.AccessConfig + expErr bool + }{ + "authority can instantiate a contract when permission is nobody": { + addr: authority, + permission: &types.AllowNobody, + expErr: false, + }, + "other address cannot instantiate a contract when permission is nobody": { + addr: myAddress.String(), + permission: &types.AllowNobody, + expErr: true, + }, + "authority can instantiate a contract when permission is everybody": { + addr: authority, + permission: &types.AllowEverybody, + expErr: false, + }, + "other address can instantiate a contract when permission is everybody": { + addr: myAddress.String(), + permission: &types.AllowEverybody, + expErr: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = reflectContract + m.Sender = sender.String() + m.InstantiatePermission = spec.permission + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var result types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + + // when + msgInstantiate := &types.MsgInstantiateContract{ + Sender: spec.addr, + Admin: myAddress.String(), + CodeID: result.CodeID, + Label: "test", + Msg: []byte(`{}`), + Funds: sdk.Coins{}, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgInstantiate)(ctx, msgInstantiate) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestInstantiateContract2(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + salt string + permission *types.AccessConfig + expErr bool + }{ + "authority can instantiate a contract when permission is nobody": { + addr: authority, + permission: &types.AllowNobody, + salt: "salt1", + expErr: false, + }, + "other address cannot instantiate a contract when permission is nobody": { + addr: myAddress.String(), + permission: &types.AllowNobody, + salt: "salt2", + expErr: true, + }, + "authority can instantiate a contract when permission is everybody": { + addr: authority, + permission: &types.AllowEverybody, + salt: "salt3", + expErr: false, + }, + "other address can instantiate a contract when permission is everybody": { + addr: myAddress.String(), + permission: &types.AllowEverybody, + salt: "salt4", + expErr: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + _, sender := keyPubAddr() + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = reflectContract + m.Sender = sender.String() + m.InstantiatePermission = spec.permission + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var result types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + + // when + msgInstantiate := &types.MsgInstantiateContract2{ + Sender: spec.addr, + Admin: myAddress.String(), + CodeID: result.CodeID, + Label: "label", + Msg: []byte(`{}`), + Funds: sdk.Coins{}, + Salt: []byte(spec.salt), + FixMsg: true, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgInstantiate)(ctx, msgInstantiate) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestUpdateInstantiateConfig(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + creator sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + permission *types.AccessConfig + expErr bool + }{ + "authority can update instantiate config when permission is subset": { + addr: authority, + permission: &types.AllowNobody, + expErr: false, + }, + "creator can update instantiate config when permission is subset": { + addr: creator.String(), + permission: &types.AllowNobody, + expErr: false, + }, + "authority can update instantiate config when permission is not subset": { + addr: authority, + permission: &types.AllowEverybody, + expErr: false, + }, + "creator cannot update instantiate config when permission is not subset": { + addr: creator.String(), + permission: &types.AllowEverybody, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + err := wasmApp.WasmKeeper.SetParams(ctx, types.Params{ + CodeUploadAccess: types.AllowEverybody, + InstantiateDefaultPermission: types.AccessTypeNobody, + }) + require.NoError(t, err) + + msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) { + m.WASMByteCode = reflectContract + m.Sender = creator.String() + m.InstantiatePermission = &types.AllowNobody + }) + + // store code + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var result types.MsgStoreCodeResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + + // when + msgUpdateInstantiateConfig := &types.MsgUpdateInstantiateConfig{ + Sender: spec.addr, + CodeID: result.CodeID, + NewInstantiatePermission: spec.permission, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgUpdateInstantiateConfig)(ctx, msgUpdateInstantiateConfig) + + // then + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestStoreAndMigrateContract(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + checksum, err := wasmvm.CreateChecksum(testContract) + require.NoError(t, err) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + ) + + specs := map[string]struct { + addr string + permission *types.AccessConfig + expChecksum []byte + expErr bool + }{ + "authority can store and migrate a contract when permission is nobody": { + addr: authority, + permission: &types.AllowNobody, + expChecksum: checksum, + }, + "authority can store and migrate a contract when permission is everybody": { + addr: authority, + permission: &types.AllowEverybody, + expChecksum: checksum, + }, + "other address can store and migrate a contract when permission is everybody": { + addr: myAddress.String(), + permission: &types.AllowEverybody, + expChecksum: checksum, + }, + "other address cannot store and migrate a contract when permission is nobody": { + addr: myAddress.String(), + permission: &types.AllowNobody, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + initMsg := keeper.HackatomExampleInitMsg{ + Verifier: myAddress, + Beneficiary: myAddress, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + storeAndInstantiateMsg := &types.MsgStoreAndInstantiateContract{ + Authority: spec.addr, + WASMByteCode: testContract, + InstantiatePermission: &types.AllowEverybody, + Admin: myAddress.String(), + UnpinCode: false, + Label: "test", + Msg: initMsgBz, + Funds: sdk.Coins{}, + } + rsp, err := wasmApp.MsgServiceRouter().Handler(storeAndInstantiateMsg)(ctx, storeAndInstantiateMsg) + require.NoError(t, err) + var storeAndInstantiateResponse types.MsgStoreAndInstantiateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &storeAndInstantiateResponse)) + + contractAddr := storeAndInstantiateResponse.Address + + // when + migMsg := struct { + Verifier sdk.AccAddress `json:"verifier"` + }{Verifier: myAddress} + migMsgBz, err := json.Marshal(migMsg) + require.NoError(t, err) + msg := &types.MsgStoreAndMigrateContract{ + Authority: spec.addr, + WASMByteCode: testContract, + InstantiatePermission: spec.permission, + Msg: migMsgBz, + Contract: contractAddr, + } + rsp, err = wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + + // then + if spec.expErr { + require.Error(t, err) + require.Nil(t, rsp) + return + } + + require.NoError(t, err) + var result types.MsgStoreAndMigrateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) + assert.Equal(t, spec.expChecksum, result.Checksum) + require.NotZero(t, result.CodeID) + }) + } +} + +func TestUpdateContractLabel(t *testing.T) { + wasmApp := app.Setup(t) + ctx := wasmApp.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()}) + + var ( + myAddress sdk.AccAddress = make([]byte, types.ContractAddrLen) + authority = wasmApp.WasmKeeper.GetAuthority() + otherAddr = func() sdk.AccAddress { _, addr := keyPubAddr(); return addr }() + ) + + specs := map[string]struct { + addr string + newLabel string + expErr bool + }{ + "authority can update contract label": { + addr: authority, + newLabel: "new label", + expErr: false, + }, + "admin can update contract label": { + addr: myAddress.String(), + newLabel: "new label", + expErr: false, + }, + "other address cannot update contract label": { + addr: otherAddr.String(), + newLabel: "new label", + expErr: true, + }, + "empty new label": { + addr: authority, + expErr: true, + }, + "invalid new label": { + addr: authority, + newLabel: " start with space ", + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup + msg := &types.MsgStoreAndInstantiateContract{ + Authority: spec.addr, + WASMByteCode: reflectContract, + InstantiatePermission: &types.AllowEverybody, + Admin: myAddress.String(), + UnpinCode: false, + Label: "old label", + Msg: []byte(`{}`), + Funds: sdk.Coins{}, + } + rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg) + require.NoError(t, err) + var storeAndInstantiateResponse types.MsgStoreAndInstantiateContractResponse + require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &storeAndInstantiateResponse)) + + contract := storeAndInstantiateResponse.Address + contractAddr, err := sdk.AccAddressFromBech32(contract) + require.NoError(t, err) + require.Equal(t, "old label", wasmApp.WasmKeeper.GetContractInfo(ctx, contractAddr).Label) + + // when + msgUpdateLabel := &types.MsgUpdateContractLabel{ + Sender: spec.addr, + NewLabel: spec.newLabel, + Contract: storeAndInstantiateResponse.Address, + } + _, err = wasmApp.MsgServiceRouter().Handler(msgUpdateLabel)(ctx, msgUpdateLabel) + + // then + if spec.expErr { + require.Error(t, err) + require.Equal(t, "old label", wasmApp.WasmKeeper.GetContractInfo(ctx, contractAddr).Label) + } else { + require.NoError(t, err) + require.Equal(t, spec.newLabel, wasmApp.WasmKeeper.GetContractInfo(ctx, contractAddr).Label) + } + }) + } +} diff --git a/tests/integration/wasm/query_plugin_integration_test.go b/tests/integration/wasm/query_plugin_integration_test.go index f3d51500..f33150d5 100644 --- a/tests/integration/wasm/query_plugin_integration_test.go +++ b/tests/integration/wasm/query_plugin_integration_test.go @@ -13,7 +13,7 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types" "github.com/cometbft/cometbft/crypto/secp256k1" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" - gogoproto "github.com/cosmos/gogoproto/proto" + proto "github.com/cosmos/gogoproto/proto" channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -130,7 +130,7 @@ func TestReflectStargateQuery(t *testing.T) { func TestReflectGrpcQuery(t *testing.T) { queryPlugins := (*reflectPlugins()).Merge(&wasmKeeper.QueryPlugins{ - Grpc: func(ctx sdk.Context, request *wasmvmtypes.GrpcQuery) (gogoproto.Message, error) { + Grpc: func(ctx sdk.Context, request *wasmvmtypes.GrpcQuery) (proto.Message, error) { if request.Path == "cosmos.bank.v1beta1.Query/AllBalances" { return &banktypes.QueryAllBalancesResponse{ Balances: sdk.NewCoins(), @@ -157,7 +157,7 @@ func TestReflectGrpcQuery(t *testing.T) { // now grpc query for the bank balance cosmosBankQuery := banktypes.NewQueryAllBalancesRequest(creator, nil, false) - cosmosBankQueryBz, err := gogoproto.Marshal(cosmosBankQuery) + cosmosBankQueryBz, err := proto.Marshal(cosmosBankQuery) require.NoError(t, err) reflectQuery := wasmvmtypes.QueryRequest{ Grpc: &wasmvmtypes.GrpcQuery{ @@ -176,7 +176,7 @@ func TestReflectGrpcQuery(t *testing.T) { mustUnmarshal(t, reflectRespBz, &reflectResp) // now unmarshal the protobuf response var grpcBalance banktypes.QueryAllBalancesResponse - err = gogoproto.Unmarshal(reflectResp.Data, &grpcBalance) + err = proto.Unmarshal(reflectResp.Data, &grpcBalance) require.NoError(t, err) } @@ -254,7 +254,7 @@ func TestReflectInvalidStargateQuery(t *testing.T) { protoQuery := banktypes.QueryAllBalancesRequest{ Address: creator.String(), } - protoQueryBin, err := gogoproto.Marshal(&protoQuery) + protoQueryBin, err := proto.Marshal(&protoQuery) require.NoError(t, err) protoRequest := wasmvmtypes.QueryRequest{ @@ -953,16 +953,16 @@ func TestAcceptListStargateQuerier(t *testing.T) { addrs := app.AddTestAddrsIncremental(lumeraApp, ctx, 2, sdkmath.NewInt(1_000_000)) accepted := wasmKeeper.AcceptedQueries{ - "/cosmos.auth.v1beta1.Query/Account": func() gogoproto.Message { + "/cosmos.auth.v1beta1.Query/Account": func() proto.Message { return &authtypes.QueryAccountResponse{} }, - "/no/route/to/this": func() gogoproto.Message { + "/no/route/to/this": func() proto.Message { return &authtypes.QueryAccountResponse{} }, } - marshal := func(pb gogoproto.Message) []byte { - b, err := gogoproto.Marshal(pb) + marshal := func(pb proto.Message) []byte { + b, err := proto.Marshal(pb) require.NoError(t, err) return b } @@ -1048,8 +1048,8 @@ func TestDeterministicJsonMarshal(t *testing.T) { originalResponse string updatedResponse string queryPath string - responseProtoStruct gogoproto.Message - expectedProto func() gogoproto.Message + responseProtoStruct proto.Message + expectedProto func() proto.Message }{ /** * @@ -1077,7 +1077,7 @@ func TestDeterministicJsonMarshal(t *testing.T) { "0a530a202f636f736d6f732e617574682e763162657461312e426173654163636f756e74122f0a2d636f736d6f733166387578756c746e3873717a687a6e72737a3371373778776171756867727367366a79766679122d636f736d6f733166387578756c746e3873717a687a6e72737a3371373778776171756867727367366a79766679", "/cosmos.auth.v1beta1.Query/Account", &authtypes.QueryAccountResponse{}, - func() gogoproto.Message { + func() proto.Message { account := authtypes.BaseAccount{ Address: "cosmos1f8uxultn8sqzhznrsz3q77xwaquhgrsg6jyvfy", } @@ -1119,9 +1119,9 @@ func TestConvertProtoToJSONMarshal(t *testing.T) { testCases := []struct { name string queryPath string - protoResponseStruct gogoproto.Message + protoResponseStruct proto.Message originalResponse string - expectedProtoResponse gogoproto.Message + expectedProtoResponse proto.Message expectedError bool }{ { diff --git a/tests/integration/wasm/snapshotter_integration_test.go b/tests/integration/wasm/snapshotter_integration_test.go new file mode 100644 index 00000000..028503da --- /dev/null +++ b/tests/integration/wasm/snapshotter_integration_test.go @@ -0,0 +1,141 @@ +package wasm_test + +import ( + "os" + "testing" + "time" + + wasmvm "github.com/CosmWasm/wasmvm/v3" + wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + tmtypes "github.com/cometbft/cometbft/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + sdkmath "cosmossdk.io/math" + + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/types" + + "github.com/LumeraProtocol/lumera/app" + lcfg "github.com/LumeraProtocol/lumera/config" +) + +func TestSnapshotter(t *testing.T) { + specs := map[string]struct { + wasmFiles []string + }{ + "single contract": { + wasmFiles: []string{GetTestDataFilePath("reflect_1_5.wasm")}, + }, + "multiple contract": { + wasmFiles: []string{ + GetTestDataFilePath("reflect_1_5.wasm"), + GetTestDataFilePath("burner.wasm"), + GetTestDataFilePath("reflect_1_5.wasm"), + }, + }, + "duplicate contracts": { + wasmFiles: []string{GetTestDataFilePath("reflect_1_5.wasm"), GetTestDataFilePath("reflect_1_5.wasm")}, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup source app + srcWasmApp, genesisAddr := newWasmExampleApp(t) + + // store wasm codes on chain + ctx := srcWasmApp.NewUncachedContext(false, tmproto.Header{ + ChainID: "foo", + Height: srcWasmApp.LastBlockHeight() + 1, + Time: time.Now(), + }) + wasmKeeper := srcWasmApp.WasmKeeper + contractKeeper := keeper.NewDefaultPermissionKeeper(wasmKeeper) + + srcCodeIDToChecksum := make(map[uint64][]byte, len(spec.wasmFiles)) + for i, v := range spec.wasmFiles { + wasmCode, err := os.ReadFile(v) + require.NoError(t, err) + codeID, checksum, err := contractKeeper.Create(ctx, genesisAddr, wasmCode, nil) + require.NoError(t, err) + require.Equal(t, uint64(i+1), codeID) + srcCodeIDToChecksum[codeID] = checksum + } + // create snapshot + _, err := srcWasmApp.Commit() + require.NoError(t, err) + + snapshotHeight := uint64(srcWasmApp.LastBlockHeight()) + snapshot, err := srcWasmApp.SnapshotManager().Create(snapshotHeight) + require.NoError(t, err) + assert.NotNil(t, snapshot) + + originalMaxWasmSize := types.MaxWasmSize + types.MaxWasmSize = 1 + t.Cleanup(func() { + types.MaxWasmSize = originalMaxWasmSize + }) + + // when snapshot imported into dest app instance + destWasmApp := app.SetupWithEmptyStore(t) + require.NoError(t, destWasmApp.SnapshotManager().Restore(*snapshot)) + for i := uint32(0); i < snapshot.Chunks; i++ { + chunkBz, err := srcWasmApp.SnapshotManager().LoadChunk(snapshot.Height, snapshot.Format, i) + require.NoError(t, err) + end, err := destWasmApp.SnapshotManager().RestoreChunk(chunkBz) + require.NoError(t, err) + if end { + break + } + } + + // then all wasm contracts are imported + wasmKeeper = destWasmApp.WasmKeeper + ctx = destWasmApp.NewUncachedContext(false, tmproto.Header{ + ChainID: "foo", + Height: destWasmApp.LastBlockHeight() + 1, + Time: time.Now(), + }) + + destCodeIDToChecksum := make(map[uint64][]byte, len(spec.wasmFiles)) + wasmKeeper.IterateCodeInfos(ctx, func(id uint64, info types.CodeInfo) bool { + bz, err := wasmKeeper.GetByteCode(ctx, id) + require.NoError(t, err) + + hash, err := wasmvm.CreateChecksum(bz) + require.NoError(t, err) + destCodeIDToChecksum[id] = hash[:] + assert.Equal(t, hash[:], wasmvmtypes.Checksum(info.CodeHash)) + return false + }) + assert.Equal(t, srcCodeIDToChecksum, destCodeIDToChecksum) + }) + } +} + +func newWasmExampleApp(t *testing.T) (*app.App, sdk.AccAddress) { + senderPrivKey, senderAddr := keyPubAddr() + pubKey := senderPrivKey.PubKey() + sdkPubKey, err := cryptocodec.FromCmtPubKeyInterface(pubKey) + require.NoError(t, err) + + acc := authtypes.NewBaseAccount(senderAddr, sdkPubKey, 0, 0) + amount, ok := sdkmath.NewIntFromString("10000000000000000000") + require.True(t, ok) + + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(lcfg.ChainDenom, amount)), + } + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + wasmApp := app.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, "testing", sdk.DefaultPowerReduction, []banktypes.Balance{balance}) + + return wasmApp, senderAddr +} diff --git a/tests/system/claiming_test.go b/tests/system/claiming_test.go deleted file mode 100644 index f157154d..00000000 --- a/tests/system/claiming_test.go +++ /dev/null @@ -1,312 +0,0 @@ -package system_test - -import ( - "context" - "os" - "testing" - - "github.com/LumeraProtocol/lumera/app" - "github.com/LumeraProtocol/lumera/tests/ibctesting" - "github.com/LumeraProtocol/lumera/x/claim/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - claimtestutils "github.com/LumeraProtocol/lumera/x/claim/testutils" - lcfg "github.com/LumeraProtocol/lumera/config" -) - -type SystemTestSuite struct { - app *app.App - sdkCtx sdk.Context - ctx context.Context -} - -func setupClaimSystemSuite(t *testing.T) *SystemTestSuite { - os.Setenv("SYSTEM_TESTS", "true") - t.Cleanup(func() { - os.Unsetenv("SYSTEM_TESTS") - }) - - suite := &SystemTestSuite{} - coord := ibctesting.NewCoordinator(t, 1) // One chain setup - chain := coord.GetChain(ibctesting.GetChainID(1)) - - app := chain.App.(*app.App) - suite.app = app - - baseCtx := chain.GetContext() - suite.sdkCtx = baseCtx - suite.ctx = baseCtx - - // Set up default parameters - err := suite.app.ClaimKeeper.SetParams(chain.GetContext(), types.DefaultParams()) - require.NoError(t, err) - - return suite -} - -func TestClaimProcess(t *testing.T) { - suite := setupClaimSystemSuite(t) - - // Generate test data - testData, err := claimtestutils.GenerateClaimingTestData() - t.Logf("\nTest Data Generated:"+ - "\n===================="+ - "\nOldAddress: %s"+ - "\nPubKey: %s"+ - "\nNewAddress: %s"+ - "\nSignature: %s"+ - "\n====================\n", - testData.OldAddress, - testData.PubKey, - testData.NewAddress, - testData.Signature) - require.NoError(t, err) - - testAmount := int64(1_000_000) - - testCases := []struct { - name string - setup func() - msg *types.MsgClaim - expectError bool - expectedError error - }{ - { - name: "Successful claim with non-existing new address", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = true - err := suite.app.ClaimKeeper.SetParams(suite.sdkCtx, params) - require.NoError(t, err) - - claimRecord := types.ClaimRecord{ - OldAddress: testData.OldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err = suite.app.ClaimKeeper.SetClaimRecord(suite.sdkCtx, claimRecord) - require.NoError(t, err) - - err = suite.app.BankKeeper.MintCoins(suite.sdkCtx, types.ModuleName, claimRecord.Balance) - require.NoError(t, err) - }, - msg: &types.MsgClaim{ - OldAddress: testData.OldAddress, - NewAddress: testData.NewAddress, - PubKey: testData.PubKey, - Signature: testData.Signature, - }, - expectError: false, - }, - { - name: "Already claimed", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = true - err := suite.app.ClaimKeeper.SetParams(suite.sdkCtx, params) - require.NoError(t, err) - - claimRecord := types.ClaimRecord{ - OldAddress: testData.OldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: true, - ClaimTime: suite.sdkCtx.BlockTime().Unix(), - } - err = suite.app.ClaimKeeper.SetClaimRecord(suite.sdkCtx, claimRecord) - require.NoError(t, err) - }, - msg: &types.MsgClaim{ - OldAddress: testData.OldAddress, - NewAddress: testData.NewAddress, - PubKey: testData.PubKey, - Signature: testData.Signature, - }, - expectError: true, - expectedError: types.ErrClaimAlreadyClaimed, - }, - { - name: "Non-existent claim", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = true - err := suite.app.ClaimKeeper.SetParams(suite.sdkCtx, params) - require.NoError(t, err) - }, - msg: &types.MsgClaim{ - OldAddress: "PtqHAEacynVd3V821NPhgxu9K4Ab6kAguHx", // Different address - NewAddress: testData.NewAddress, - PubKey: testData.PubKey, - Signature: testData.Signature, - }, - expectError: true, - expectedError: types.ErrClaimNotFound, - }, - { - name: "Claims disabled", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = false - err := suite.app.ClaimKeeper.SetParams(suite.sdkCtx, params) - require.NoError(t, err) - - claimRecord := types.ClaimRecord{ - OldAddress: testData.OldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err = suite.app.ClaimKeeper.SetClaimRecord(suite.sdkCtx, claimRecord) - require.NoError(t, err) - }, - msg: &types.MsgClaim{ - OldAddress: testData.OldAddress, - NewAddress: testData.NewAddress, - PubKey: testData.PubKey, - Signature: testData.Signature, - }, - expectError: true, - expectedError: types.ErrClaimDisabled, - }, - { - name: "Invalid signature", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = true - err := suite.app.ClaimKeeper.SetParams(suite.sdkCtx, params) - require.NoError(t, err) - - claimRecord := types.ClaimRecord{ - OldAddress: testData.OldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err = suite.app.ClaimKeeper.SetClaimRecord(suite.sdkCtx, claimRecord) - require.NoError(t, err) - }, - msg: &types.MsgClaim{ - OldAddress: testData.OldAddress, - NewAddress: testData.NewAddress, - PubKey: testData.PubKey, - Signature: "invalid_signature", - }, - expectError: true, - expectedError: types.ErrInvalidSignature, - }, - { - name: "Claim period expired", - setup: func() { - params := types.DefaultParams() - params.EnableClaims = true - params.ClaimEndTime = suite.sdkCtx.BlockTime().Unix() - 1 - err := suite.app.ClaimKeeper.SetParams(suite.sdkCtx, params) - require.NoError(t, err) - - claimRecord := types.ClaimRecord{ - OldAddress: testData.OldAddress, - Balance: sdk.NewCoins(sdk.NewInt64Coin(lcfg.ChainDenom, testAmount)), - Claimed: false, - } - err = suite.app.ClaimKeeper.SetClaimRecord(suite.sdkCtx, claimRecord) - require.NoError(t, err) - }, - msg: &types.MsgClaim{ - OldAddress: testData.OldAddress, - NewAddress: testData.NewAddress, - PubKey: testData.PubKey, - Signature: testData.Signature, - }, - expectError: true, - expectedError: types.ErrClaimPeriodExpired, - }, - } - - // Execute each test case - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Set up the test environment for this specific case - tc.setup() - msgServer := keeper.NewMsgServerImpl(suite.app.ClaimKeeper) - - // Record initial balances for validation - moduleAddr := suite.app.AuthKeeper.GetModuleAddress(types.ModuleName) - initialModuleBalance := suite.app.BankKeeper.GetAllBalances(suite.sdkCtx, moduleAddr) - - // Get destination address and its initial balance - destAddr, err := sdk.AccAddressFromBech32(tc.msg.NewAddress) - require.NoError(t, err) - initialUserBalance := suite.app.BankKeeper.GetAllBalances(suite.sdkCtx, destAddr) - - // Execute the claim message - response, err := msgServer.Claim(suite.sdkCtx, tc.msg) - - // Handle error cases - if tc.expectError { - require.Error(t, err) - require.ErrorIs(t, err, tc.expectedError) - require.Nil(t, response) - } else { - // Verify successful claim execution - require.NoError(t, err) - require.NotNil(t, response) - - // Verify claim record has been properly updated - record, found, err := suite.app.ClaimKeeper.GetClaimRecord(suite.sdkCtx, tc.msg.OldAddress) - require.NoError(t, err) - require.True(t, found) - require.True(t, record.Claimed) - require.NotZero(t, record.ClaimTime) - - // Verify destination account exists (should be created if it didn't exist) - acc := suite.app.AuthKeeper.GetAccount(suite.sdkCtx, destAddr) - require.NotNil(t, acc) - - // Verify token balances after transfer - finalUserBalance := suite.app.BankKeeper.GetAllBalances(suite.sdkCtx, destAddr) - finalModuleBalance := suite.app.BankKeeper.GetAllBalances(suite.sdkCtx, moduleAddr) - - // Check user received the correct amount - expectedUserBalance := initialUserBalance.Add(record.Balance...) - require.Equal(t, expectedUserBalance, finalUserBalance) - - // Check module account balance decreased correctly - expectedModuleBalance := initialModuleBalance.Sub(record.Balance...) - require.Equal(t, expectedModuleBalance, finalModuleBalance) - - // Verify event emission - events := suite.sdkCtx.EventManager().Events() - require.NotEmpty(t, events) - - // Look for the claim processed event and verify its attributes - var foundClaimEvent bool - for _, event := range events { - if event.Type == types.EventTypeClaimProcessed { - foundClaimEvent = true - hasOldAddr, hasNewAddr, hasClaimTime := false, false, false - - // Check all required attributes are present with correct values - for _, attr := range event.Attributes { - switch string(attr.Key) { - case types.AttributeKeyOldAddress: - require.Equal(t, tc.msg.OldAddress, string(attr.Value)) - hasOldAddr = true - case types.AttributeKeyNewAddress: - require.Equal(t, tc.msg.NewAddress, string(attr.Value)) - hasNewAddr = true - case types.AttributeKeyClaimTime: - require.NotEmpty(t, string(attr.Value)) - hasClaimTime = true - } - } - - // Ensure all required attributes were found - require.True(t, hasOldAddr, "missing old address attribute") - require.True(t, hasNewAddr, "missing new address attribute") - require.True(t, hasClaimTime, "missing claim time attribute") - } - } - require.True(t, foundClaimEvent, "claim_processed event not found") - } - }) - } -} diff --git a/tests/systemtests/claim_period_end_test.go b/tests/systemtests/claim_period_end_test.go deleted file mode 100644 index cb1afe2f..00000000 --- a/tests/systemtests/claim_period_end_test.go +++ /dev/null @@ -1,122 +0,0 @@ -//go:build system_test - -package system - -import ( - "fmt" - "testing" - "time" - "strconv" - - "github.com/stretchr/testify/require" - "github.com/tidwall/gjson" - "github.com/tidwall/sjson" - - claimtestutils "github.com/LumeraProtocol/lumera/x/claim/testutils" - claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestClaimPeriodEndBurn(t *testing.T) { - // Reset chain for a clean state - sut.ResetChain(t) - - // Generate test data for claims - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - - // Setup test parameters - claimAmount := uint64(1_000_000) - totalClaimableAmount := uint64(2_000_000) // Two potential claims - - // Generate a CSV file with the test data - claimsPath, err := claimtestutils.GenerateClaimsCSVFile([]claimtestutils.ClaimCSVRecord{ - {OldAddress: testData.OldAddress, Amount: claimAmount}, - {OldAddress: "lumc4mple2ddress000000000000000000000000", Amount: claimAmount}, // Second address that won't be claimed - }, nil) - require.NoError(t, err) - - // Ensure the file is cleaned up after the test - t.Cleanup(func() { - claimtestutils.CleanupClaimsCSVFile(claimsPath) - }) - - claimPeriodSecs := time.Duration(20) * time.Second // Short claim period for testing - // Set a short claim period - claimEndTime := time.Now().Add(claimPeriodSecs).Unix() - sut.Logf("Claim end time: %s\n", time.Unix(claimEndTime, 0).Format(time.RFC3339)) - - // Modify genesis to set up test conditions - sut.ModifyGenesisJSON(t, func(genesis []byte) []byte { - state := genesis - var err error - - // Set total claimable amount - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", - []byte(strconv.FormatUint(totalClaimableAmount, 10))) - require.NoError(t, err) - - // Enable claims and set end time - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("true")) - require.NoError(t, err) - state, err = sjson.SetRawBytes(state, "app_state.claim.params.claim_end_time", - []byte(fmt.Sprintf("%d", claimEndTime))) - require.NoError(t, err) - - return state - }) - - // Start the chain - sut.StartChain(t, fmt.Sprintf("--%s=%s", claimtypes.FlagClaimsPath, claimsPath)) - cli := NewLumeradCLI(t, sut, true) - - // Get claim module account address - moduleAcctResp := cli.CustomQuery("q", "auth", "module-account", "claim") - moduleAddr := gjson.Get(moduleAcctResp, "account.value.address").String() - require.NotEmpty(t, moduleAddr, "claim module address should not be empty") - - // Verify initial module balance - initialModuleBalance := cli.QueryBalance(moduleAddr, claimtypes.DefaultClaimsDenom) - require.Equal(t, totalClaimableAmount, initialModuleBalance, - "Initial module balance should match total claimable amount") - - // Process claim - registerCmd := []string{ - "tx", "claim", "claim", - testData.OldAddress, - testData.NewAddress, - testData.PubKey, - testData.Signature, - "--from", "node0", - } - sut.Logf("Registering claim with command: %s\n", registerCmd) - resp := cli.CustomCommand(registerCmd...) - RequireTxSuccess(t, resp) - - // Verify user received funds - userBalance := cli.QueryBalance(testData.NewAddress, claimtypes.DefaultClaimsDenom) - require.Equal(t, uint64(1_000_000), userBalance, "User should receive claim amount") - - // Verify module balance decreased by claim amount - midModuleBalance := cli.QueryBalance(moduleAddr, claimtypes.DefaultClaimsDenom) - require.Equal(t, uint64(1_000_000), midModuleBalance, - "Module balance should be reduced by claimed amount") - - // Wait for claim period to end - t.Log("Waiting for claim period to end...") - time.Sleep(time.Until(time.Unix(claimEndTime, 0)) + claimPeriodSecs) - - // Wait additional blocks for EndBlocker to process - sut.AwaitNextBlock(t) - sut.AwaitNextBlock(t) - sut.AwaitNextBlock(t) - - // Verify claims are disabled in params - paramsResp := cli.CustomQuery("q", "claim", "params") - enableClaims := gjson.Get(paramsResp, "params.enable_claims").Bool() - require.False(t, enableClaims, "Claims should be disabled after period end") - - // KEY ASSERTION: Verify all remaining tokens were burned - finalModuleBalance := cli.QueryBalance(moduleAddr, claimtypes.DefaultClaimsDenom) - require.Equal(t, uint64(0), finalModuleBalance, - "Module balance should be zero after burn") -} diff --git a/tests/systemtests/claim_test.go b/tests/systemtests/claim_test.go deleted file mode 100644 index ec6e4b35..00000000 --- a/tests/systemtests/claim_test.go +++ /dev/null @@ -1,295 +0,0 @@ -//go:build system_test - -package system - -import ( - "fmt" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/tidwall/gjson" - "github.com/tidwall/sjson" - - claimtestutils "github.com/LumeraProtocol/lumera/x/claim/testutils" - claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestClaimsSystem(t *testing.T) { - testCases := []struct { - name string - balanceToClaim uint64 - setupFn func(t *testing.T) (claimtestutils.TestData, string) - modifyGenesis func(genesis []byte) []byte - expectSuccess bool - expectedError string - waitBeforeClaim bool - claimAttempts int // number of times to attempt the claim in the same block - }{ - { - name: "successful_claim", - balanceToClaim: 1_000_000, - setupFn: func(t *testing.T) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state, err := sjson.SetRawBytes(genesis, "app_state.claim.total_claimable_amount", []byte("1000000")) - require.NoError(t, err) - return state - }, - expectSuccess: true, - waitBeforeClaim: false, - claimAttempts: 1, - }, - { - // we remove zero balances from csv file by default - name: "claim_with_zero_balance", - balanceToClaim: 0, - setupFn: func(t *testing.T) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state, err := sjson.SetRawBytes(genesis, "app_state.claim.total_claimable_amount", []byte("0")) - require.NoError(t, err) - return state - }, - expectSuccess: false, - expectedError: "claim not found", - waitBeforeClaim: false, - claimAttempts: 1, - }, - { - name: "claims_disabled", - balanceToClaim: 500_000, - setupFn: func(t *testing.T) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state := genesis - var err error - - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte("500000")) - require.NoError(t, err) - - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("false")) - require.NoError(t, err) - - return state - }, - expectSuccess: false, - expectedError: "claim is disabled", - claimAttempts: 1, - }, - { - name: "claim_period_expired", - balanceToClaim: 500_000, - setupFn: func(t *testing.T) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state := genesis - var err error - - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte("500000")) - require.NoError(t, err) - - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("true")) - require.NoError(t, err) - - endTime := time.Now().Add(10 * time.Second).Unix() - state, err = sjson.SetRawBytes(state, "app_state.claim.params.claim_end_time", []byte(strconv.FormatInt(endTime, 10))) - require.NoError(t, err) - - return state - }, - expectSuccess: false, - expectedError: "claim is disabled", - waitBeforeClaim: true, - claimAttempts: 1, - }, - { - name: "duplicate_claim", - balanceToClaim: 500_000, - setupFn: func(t *testing.T) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state := genesis - var err error - - // Set total claimable amount - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte("500000")) - require.NoError(t, err) - - // Set claims per block to 1 - state, err = sjson.SetRawBytes(state, "app_state.claim.params.max_claims_per_block", []byte("10")) - require.NoError(t, err) - - // Enable claims - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("true")) - require.NoError(t, err) - - // Set reasonable claim end time - endTime := time.Now().Add(1 * time.Hour).Unix() - state, err = sjson.SetRawBytes(state, "app_state.claim.params.claim_end_time", []byte(strconv.FormatInt(endTime, 10))) - require.NoError(t, err) - - return state - }, - expectSuccess: false, - expectedError: "claim already claimed", - waitBeforeClaim: false, - claimAttempts: 2, // Try to claim 2 times - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - sut.ResetChain(t) - - cli := NewLumeradCLI(t, sut, true) - - // Get test data and CSV address - testData, oldAddress := tc.setupFn(t) - - // Apply custom genesis modifications - sut.ModifyGenesisJSON(t, tc.modifyGenesis) - - // generate claims CSV file in temp dir - claimsPath, err := claimtestutils.GenerateClaimsCSVFile([]claimtestutils.ClaimCSVRecord{ - { - OldAddress: oldAddress, - Amount: tc.balanceToClaim, - }, - }, nil) - require.NoError(t, err) - // Ensure the file is cleaned up after the test - t.Cleanup(func() { - claimtestutils.CleanupClaimsCSVFile(claimsPath) - }) - - // Start the chain with modified genesis - sut.StartChain(t, fmt.Sprintf("--%s=%s", claimtypes.FlagClaimsPath, claimsPath)) - - // Wait when needed - if tc.waitBeforeClaim { - t.Log("Waiting for claim period to expire...") - time.Sleep(11 * time.Second) - } - - var lastResp string - // Register claim multiple times if specified - for i := 0; i < tc.claimAttempts; i++ { - registerCmd := []string{ - "tx", "claim", "claim", - testData.OldAddress, // Old address - testData.NewAddress, // New address - testData.PubKey, // PubKey - testData.Signature, // Signature - "--from", "node0", - } - - lastResp = cli.CustomCommand(registerCmd...) - - // For multiple attempts, only the first one should succeed - if i == 0 && tc.expectSuccess { - RequireTxSuccess(t, lastResp) - } - } - - // Validate the final response - if tc.expectSuccess { - RequireTxSuccess(t, lastResp) - - // Get txhash and query transaction - txHash := gjson.Get(lastResp, "txhash").String() - require.NotEmpty(t, txHash, "txhash not found in response") - - txResp := cli.CustomQuery("q", "tx", txHash) - require.NotEmpty(t, txResp) - - // Verify claim_processed event and transfer from module - events := gjson.Get(txResp, "events") - require.True(t, events.Exists()) - - foundClaimEvent := false - foundModuleTransfer := false - - for _, event := range events.Array() { - eventType := event.Get("type").String() - attrs := event.Get("attributes").Array() - - // Check claim_processed event - if eventType == "claim_processed" { - foundClaimEvent = true - for _, attr := range attrs { - key := attr.Get("key").String() - value := attr.Get("value").String() - switch key { - case "module": - require.Equal(t, "claim", value) - case "amount": - require.Equal(t, strconv.FormatUint(tc.balanceToClaim, 10) + claimtypes.DefaultClaimsDenom, value) - case "old_address": - require.Equal(t, testData.OldAddress, value) - case "new_address": - require.Equal(t, testData.NewAddress, value) - } - } - } - - // Check for transfer from module to recipient - if eventType == "transfer" { - // Only interested in msg_index=0 which relates to the claim operation - msgIndexAttr := false - for _, attr := range attrs { - if attr.Get("key").String() == "msg_index" && attr.Get("value").String() == "0" { - msgIndexAttr = true - break - } - } - - if msgIndexAttr { - recipient := "" - amount := "" - - for _, attr := range attrs { - if attr.Get("key").String() == "recipient" { - recipient = attr.Get("value").String() - } else if attr.Get("key").String() == "amount" { - amount = attr.Get("value").String() - } - } - - if recipient == testData.NewAddress && - amount == (strconv.FormatUint(tc.balanceToClaim, 10) + claimtypes.DefaultClaimsDenom) { - foundModuleTransfer = true - } - } - } - } - - require.True(t, foundClaimEvent, "claim_processed event not found") - require.True(t, foundModuleTransfer, "module transfer to recipient not found") - - // Verify balance after claim - balance := cli.QueryBalance(testData.NewAddress, claimtypes.DefaultClaimsDenom) - require.Equal(t, tc.balanceToClaim, balance) - } else { - RequireTxFailure(t, lastResp, tc.expectedError) - } - }) - } -} diff --git a/tests/systemtests/claims_params_test.go b/tests/systemtests/claims_params_test.go deleted file mode 100644 index ac911fbe..00000000 --- a/tests/systemtests/claims_params_test.go +++ /dev/null @@ -1,116 +0,0 @@ -//go:build system_test - -package system - -import ( - "fmt" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/tidwall/gjson" - "github.com/tidwall/sjson" - - lcfg "github.com/LumeraProtocol/lumera/config" - claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" -) - -// Voting Period is set to 10 seconds for faster test execution by default -func TestClaimsUpdateParamsProposal(t *testing.T) { - // Initialize and reset chain - sut.ResetChain(t) - - // Set initial parameters in genesis - initialEndTime := time.Now().Add(48 * time.Hour).Unix() - sut.ModifyGenesisJSON(t, - // Set shorter voting period for faster test execution - SetGovVotingPeriod(t, 10*time.Second), - // Set initial claim parameters - func(genesis []byte) []byte { - state := genesis - var err error - - // Set total claimable amount - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", - []byte(strconv.FormatInt(claimtypes.DefaultClaimableAmountConst, 10))) - require.NoError(t, err) - - state, err = sjson.SetRawBytes(state, "app_state.claim.params", []byte(fmt.Sprintf(`{ - "enable_claims": true, - "claim_end_time": "%d", - "max_claims_per_block": "75" - }`, initialEndTime))) - require.NoError(t, err) - - return state - }, - ) - - // Start the chain - sut.StartChain(t) - - // Create CLI helper - cli := NewLumeradCLI(t, sut, true) - - // Get and verify initial parameters - initialParams := cli.CustomQuery("q", "claim", "params") - t.Logf("Initial params: %s", initialParams) - - require.True(t, gjson.Get(initialParams, "params.enable_claims").Bool(), "initial enable_claims should be true") - require.Equal(t, "75", gjson.Get(initialParams, "params.max_claims_per_block").String(), "initial max_claims_per_block should be 75") - require.Equal(t, fmt.Sprintf("%d", initialEndTime), gjson.Get(initialParams, "params.claim_end_time").String(), "initial claim_end_time should match") - - // Get gov module account address - govAcctResp := cli.CustomQuery("q", "auth", "module-account", "gov") - t.Logf("Gov account response: %s", govAcctResp) - govAddr := gjson.Get(govAcctResp, "account.value.address").String() - require.NotEmpty(t, govAddr, "gov module address should not be empty") - - // Create governance proposal to update parameters - proposalJson := fmt.Sprintf(`{ - "messages": [{ - "@type": "/lumera.claim.MsgUpdateParams", - "authority": "%s", - "params": { - "enable_claims": false, - "claim_end_time": %d, - "max_claims_per_block": 50 - } - }], - "deposit": "100000000%s", - "metadata": "ipfs://CID", - "title": "Update Claim Parameters", - "summary": "Update claims module parameters with new values" - }`, govAddr, time.Now().Add(72*time.Hour).Unix(), lcfg.ChainDenom) - - // Submit proposal and have all validators vote yes - proposalID := cli.SubmitAndVoteGovProposal(proposalJson) - require.NotEmpty(t, proposalID) - - // Wait for proposal to be executed (aligned with the shortened voting period) - var proposalPassed bool - deadline := time.Now().Add(30 * time.Second) - for time.Now().Before(deadline) { - sut.AwaitNextBlock(t) - status := cli.CustomQuery("q", "gov", "proposal", proposalID) - if gjson.Get(status, "proposal.status").String() == "PROPOSAL_STATUS_PASSED" { - proposalPassed = true - break - } - } - require.True(t, proposalPassed, "proposal did not pass") - - // Query and verify updated parameters - updatedParams := cli.CustomQuery("q", "claim", "params") - t.Logf("Updated params: %s", updatedParams) - - require.False(t, gjson.Get(updatedParams, "params.enable_claims").Bool(), "enable_claims should be false") - require.Equal(t, "50", gjson.Get(updatedParams, "params.max_claims_per_block").String(), "max_claims_per_block should be 50") - - // The end time would be approximately 72 hours from when the proposal passed - updatedEndTime := gjson.Get(updatedParams, "params.claim_end_time").Int() - expectedEndTime := time.Now().Add(72 * time.Hour).Unix() - require.InDelta(t, expectedEndTime, updatedEndTime, float64(time.Hour.Seconds()), - "claim_end_time should be approximately 72 hours from now") -} diff --git a/tests/systemtests/claims_per_block_test.go b/tests/systemtests/claims_per_block_test.go deleted file mode 100644 index 44442ea6..00000000 --- a/tests/systemtests/claims_per_block_test.go +++ /dev/null @@ -1,399 +0,0 @@ -//go:build system_test - -package system - -import ( - "fmt" - "sync" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/tidwall/gjson" - "github.com/tidwall/sjson" - - claimtestutils "github.com/LumeraProtocol/lumera/x/claim/testutils" - claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" -) - -// System-wide constants that define test parameters and expected behavior -const ( - // Amount of tokens allocated per individual claim - tokensPerClaim = 1000000 // 1M tokens per claim - - // Response codes that indicate transaction status - successCode = "0" // Indicates successful claim processing - errCodeTooManyClaims = "1102" // Error code when block claim limit is exceeded - - // Test configuration parameters - numTestEntries = 10 // Total number of test cases to generate - maxClaimsPerBlock = 2 // Maximum allowed claims per block - numTxToSubmit = maxClaimsPerBlock + 1 // Intentionally exceed block limit by 1 -) - -// TestMaxClaimsPerBlockReset is a system test that verifies the block-level claim limiting mechanism. -// The test ensures that: -// 1. Claims are properly limited per block according to maxClaimsPerBlock -// 2. The claim counter correctly resets between blocks -// 3. Failed claims receive appropriate error codes -// 4. Successful claims are processed correctly -// -// Test Flow: -// Block N: -// - Submit maxClaimsPerBlock + 1 transactions concurrently -// - Verify exactly maxClaimsPerBlock succeed -// - Verify the excess transaction fails with correct error -// -// Block N+1: -// - Submit another batch of maxClaimsPerBlock + 1 transactions concurrently -// - Verify the limit has reset and exactly maxClaimsPerBlock new claims succeed -// - Verify the excess transaction fails appropriately -func TestMaxClaimsPerBlockReset(t *testing.T) { - t.Log("Starting TestMaxClaimsPerBlockReset...") - - // Initialize clean test environment - t.Log("Resetting chain...") - sut.ResetChain(t) - - // Create test dataset and calculate total tokens needed - testDataSet, totalClaimableAmount := generateClaimTestData(t) - var csvData []claimtestutils.ClaimCSVRecord - // convert test data to CSV format - for _, data := range testDataSet { - csvData = append(csvData, claimtestutils.ClaimCSVRecord{ - OldAddress: data.OldAddress, - Amount: tokensPerClaim, - }) - } - claimsPath, err := claimtestutils.GenerateClaimsCSVFile(csvData, nil) - require.NoError(t, err) - - // Ensure the file is cleaned up after the test - t.Cleanup(func() { - claimtestutils.CleanupClaimsCSVFile(claimsPath) - }) - - // Configure chain with test parameters - claimEndTime := time.Now().Add(1 * time.Hour).Unix() - setClaimsGenesis(t, totalClaimableAmount, fmt.Sprintf("%d", maxClaimsPerBlock), true, claimEndTime) - - t.Log("Starting chain...") - sut.StartChain(t, fmt.Sprintf("--%s=%s", claimtypes.FlagClaimsPath, claimsPath)) - cli := NewLumeradCLI(t, sut, true) - - // Record initial block for comparison - status := cli.CustomQuery("status") - startingHeight := gjson.Get(status, "sync_info.latest_block_height").Int() - t.Logf("Starting block height: %d", startingHeight) - - // First Block: Test claim limiting with concurrent submissions - t.Logf("Block %d: Submitting %d claims concurrently (max allowed is %d)...", startingHeight+1, numTxToSubmit, maxClaimsPerBlock) - - // WaitGroup to wait for all goroutines to complete - var wg sync.WaitGroup - // Channel to collect responses from goroutines - type responseItem struct { - index int - resp string - } - responseChannel := make(chan responseItem, numTxToSubmit) - - for i := 0; i < numTxToSubmit; i++ { - wg.Add(1) - go func(index int) { - defer wg.Done() - - testData := testDataSet[index] - // Construct claim transaction with necessary parameters - args := []string{ - "tx", "claim", "claim", - testData.OldAddress, - testData.NewAddress, - testData.PubKey, - testData.Signature, - "--from", fmt.Sprintf("node%d", index), - "--broadcast-mode", "sync", - "--chain-id", cli.chainID, - "--home", cli.homeDir, - "--keyring-backend", "test", - "--node", cli.nodeAddress, - "--output", "json", - "--yes", - "--fees", cli.fees, - } - - resp, ok := cli.run(args) - - t.Logf("Claim %d submission output: %s", index+1, resp) - require.True(t, ok) - - // Send result to channel - responseChannel <- responseItem{index: index, resp: resp} - }(i) - } - - // Close channel in a separate goroutine after all workers are done - go func() { - wg.Wait() - close(responseChannel) - }() - - // Collect all responses from the channel - firstBlockResponses := make([]string, numTxToSubmit) - for item := range responseChannel { - firstBlockResponses[item.index] = item.resp - } - - // Allow time for block completion and transaction processing - t.Log("Waiting for first block to complete...") - time.Sleep(12 * time.Second) - - // Extract first block details for verification - firstBlockTxHash := gjson.Get(firstBlockResponses[0], "txhash").String() - firstBlockTxResp := cli.CustomQuery("q", "tx", firstBlockTxHash) - firstBlockHeight := gjson.Get(firstBlockTxResp, "height").String() - - // Analyze first block results - var firstBlockSuccess, firstBlockErrors int - for i, resp := range firstBlockResponses { - txHash := gjson.Get(resp, "txhash").String() - require.NotEmpty(t, txHash, "txhash not found in response") - - txResp := cli.CustomQuery("q", "tx", txHash) - txCode := gjson.Get(txResp, "code").String() - txHeight := gjson.Get(txResp, "height").String() - - // Verify all transactions are in same block - require.Equal(t, firstBlockHeight, txHeight, "All first block transactions should be in the same block") - - if txCode == successCode { - firstBlockSuccess++ - verifySuccessfulClaim(t, txResp, testDataSet[i]) - } - if txCode == errCodeTooManyClaims { - firstBlockErrors++ - } - } - - t.Logf("First block results - Successful: %d, Failed: %d", firstBlockSuccess, firstBlockErrors) - require.Equal(t, maxClaimsPerBlock, firstBlockSuccess, "Expected exactly maxClaimsPerBlock successful claims in first block") - require.Equal(t, 1, firstBlockErrors, "Expected exactly one failed claim in first block") - - // Second Block: Verify limit reset with concurrent submissions - t.Log("Submitting second batch of claims concurrently in new block...") - - // Channel for second block responses - secondResponseChannel := make(chan responseItem, numTxToSubmit) - // Reset WaitGroup for second block - var wg2 sync.WaitGroup - - for i := 0; i < numTxToSubmit; i++ { - wg2.Add(1) - go func(index int) { - defer wg2.Done() - - testData := testDataSet[index+numTxToSubmit] // Use next set of test data - args := []string{ - "tx", "claim", "claim", - testData.OldAddress, - testData.NewAddress, - testData.PubKey, - testData.Signature, - "--from", fmt.Sprintf("node%d", index), - "--broadcast-mode", "sync", - "--chain-id", cli.chainID, - "--home", cli.homeDir, - "--keyring-backend", "test", - "--node", cli.nodeAddress, - "--output", "json", - "--yes", - "--fees", cli.fees, - } - - resp, ok := cli.run(args) - - t.Logf("Second block claim %d submission output: %s", index+1, resp) - require.True(t, ok) - - // Send result to channel - secondResponseChannel <- responseItem{index: index, resp: resp} - }(i) - } - - // Close channel after all workers are done - go func() { - wg2.Wait() - close(secondResponseChannel) - }() - - // Collect responses from the channel - secondBlockResponses := make([]string, numTxToSubmit) - for item := range secondResponseChannel { - secondBlockResponses[item.index] = item.resp - } - - // Allow time for second block processing - t.Log("Waiting for second block to complete...") - time.Sleep(12 * time.Second) - - // Extract second block details - secondBlockTxHash := gjson.Get(secondBlockResponses[0], "txhash").String() - secondBlockTxResp := cli.CustomQuery("q", "tx", secondBlockTxHash) - secondBlockHeight := gjson.Get(secondBlockTxResp, "height").String() - - // Ensure blocks are distinct - require.NotEqual(t, firstBlockHeight, secondBlockHeight, "Second batch should be in a different block") - - // Analyze second block results - var secondBlockSuccess, secondBlockErrors int - for i, resp := range secondBlockResponses { - txHash := gjson.Get(resp, "txhash").String() - require.NotEmpty(t, txHash, "txhash not found in response") - - txResp := cli.CustomQuery("q", "tx", txHash) - txCode := gjson.Get(txResp, "code").String() - txHeight := gjson.Get(txResp, "height").String() - - require.Equal(t, secondBlockHeight, txHeight, "All second block transactions should be in the same block") - - if txCode == successCode { - secondBlockSuccess++ - verifySuccessfulClaim(t, txResp, testDataSet[i+numTxToSubmit]) - } - if txCode == errCodeTooManyClaims { - secondBlockErrors++ - } - } - - t.Logf("Second block results - Successful: %d, Failed: %d", secondBlockSuccess, secondBlockErrors) - require.Equal(t, maxClaimsPerBlock, secondBlockSuccess, "Expected exactly maxClaimsPerBlock successful claims in second block") - require.Equal(t, 1, secondBlockErrors, "Expected exactly one failed claim in second block") -} - -// generateClaimTestData creates a set of test data entries for claims testing. -// Returns: -// - Array of TestData structures containing claim information -// - Total amount of tokens that should be made available for claims -func generateClaimTestData(t *testing.T) ([]claimtestutils.TestData, int64) { - t.Log("Generating test data...") - var testDataSet []claimtestutils.TestData - var totalClaimableAmount int64 - - for i := 0; i < numTestEntries; i++ { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - testDataSet = append(testDataSet, testData) - totalClaimableAmount += tokensPerClaim - } - t.Logf("Generated %d test data entries", len(testDataSet)) - - return testDataSet, totalClaimableAmount -} - -// setClaimsGenesis configures the genesis state for claims testing. -// Parameters: -// - totalClaimableAmount: Total tokens available for claims -// - maxClaimsPerBlock: Maximum number of claims allowed per block -// - enableClaims: Whether claiming is enabled -// - claimEndTime: Unix timestamp when claiming period ends -func setClaimsGenesis(t *testing.T, totalClaimableAmount int64, maxClaimsPerBlock string, enableClaims bool, claimEndTime int64) { - t.Log("Modifying genesis configuration...") - sut.ModifyGenesisJSON(t, func(genesis []byte) []byte { - state := genesis - var err error - - // Configure total tokens available for claims - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte(fmt.Sprintf("%d", totalClaimableAmount))) - require.NoError(t, err) - - // Set maximum claims allowed per block - state, err = sjson.SetRawBytes(state, "app_state.claim.params.max_claims_per_block", []byte(maxClaimsPerBlock)) - require.NoError(t, err) - - // Enable or disable claiming functionality - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("true")) - require.NoError(t, err) - - // Set the deadline for making claims - state, err = sjson.SetRawBytes(state, "app_state.claim.params.claim_end_time", []byte(fmt.Sprintf("%d", claimEndTime))) - require.NoError(t, err) - - return state - }) -} - -// verifySuccessfulClaim checks that a successful claim transaction -// contains all required events and correct data. -// Parameters: -// - txResp: Transaction response JSON -// - testData: Expected claim data to verify against -func verifySuccessfulClaim(t *testing.T, txResp string, testData claimtestutils.TestData) { - events := gjson.Get(txResp, "events").Array() - - var foundClaimProcessed bool - var foundTransfer bool - var foundMsgClaim bool - - // Examine each event in the transaction - for _, event := range events { - eventType := event.Get("type").String() - attrs := event.Get("attributes").Array() - - switch eventType { - case "claim_processed": - // Verify claim processing details - foundClaimProcessed = true - for _, attr := range attrs { - key := attr.Get("key").String() - value := attr.Get("value").String() - - switch key { - case "module": - require.Equal(t, "claim", value) - case "amount": - require.Equal(t, fmt.Sprintf("%dulume", tokensPerClaim), value) - case "old_address": - require.Equal(t, testData.OldAddress, value) - case "new_address": - require.Equal(t, testData.NewAddress, value) - case "claim_time": - require.NotEmpty(t, value) - } - } - - case "transfer": - // Verify token transfer details - var hasCorrectTransfer bool - for _, attr := range attrs { - if attr.Get("key").String() == "amount" && - attr.Get("value").String() == fmt.Sprintf("%dulume", tokensPerClaim) { - hasCorrectTransfer = true - foundTransfer = true - break - } - } - if hasCorrectTransfer { - // Confirm recipient address - for _, attr := range attrs { - if attr.Get("key").String() == "recipient" { - require.Equal(t, testData.NewAddress, attr.Get("value").String()) - } - } - } - - case "message": - // Verify message type - for _, attr := range attrs { - if attr.Get("key").String() == "action" && - attr.Get("value").String() == "/lumera.claim.MsgClaim" { - foundMsgClaim = true - } - } - } - } - - // Ensure all required events were found - require.True(t, foundClaimProcessed, "claim_processed event not found") - require.True(t, foundTransfer, "transfer event not found") - require.True(t, foundMsgClaim, "MsgClaim action not found") -} diff --git a/tests/systemtests/delayed_claim_test.go b/tests/systemtests/delayed_claim_test.go deleted file mode 100644 index 2dbdae22..00000000 --- a/tests/systemtests/delayed_claim_test.go +++ /dev/null @@ -1,375 +0,0 @@ -//go:build system_test - -package system - -import ( - "fmt" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/tidwall/gjson" - "github.com/tidwall/sjson" - - claimtestutils "github.com/LumeraProtocol/lumera/x/claim/testutils" - claimtypes "github.com/LumeraProtocol/lumera/x/claim/types" - lcfg "github.com/LumeraProtocol/lumera/config" -) - -func TestDelayedClaimsSystem(t *testing.T) { - testCases := []struct { - name string - balanceToClaim uint64 - setupFn func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) - modifyGenesis func(genesis []byte) []byte - expectSuccess bool - expectedError string - waitBeforeClaim bool - claimAttempts int // number of times to attempt the claim in the same block - tier string - from string - }{ - { - name: "successful_claim", - balanceToClaim: 1_000_000, - setupFn: func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state, err := sjson.SetRawBytes(genesis, "app_state.claim.total_claimable_amount", []byte("1000000")) - require.NoError(t, err) - return state - }, - expectSuccess: true, - waitBeforeClaim: false, - claimAttempts: 1, - tier: "1", - from: "node0", - }, - { - name: "successful_claim_from_same_address", - balanceToClaim: 1_000_000, - setupFn: func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) { - return claimtestutils.TestData{}, "" - }, - modifyGenesis: func(genesis []byte) []byte { - state, err := sjson.SetRawBytes(genesis, "app_state.claim.total_claimable_amount", []byte("1000000")) - require.NoError(t, err) - return state - }, - expectSuccess: true, - waitBeforeClaim: false, - claimAttempts: 1, - tier: "1", - from: "test_1", - }, - { - // we remove zero balances from csv file by default - name: "claim_with_zero_balance", - balanceToClaim: 0, - setupFn: func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state, err := sjson.SetRawBytes(genesis, "app_state.claim.total_claimable_amount", []byte("0")) - require.NoError(t, err) - return state - }, - expectSuccess: false, - expectedError: "claim not found", - waitBeforeClaim: false, - claimAttempts: 1, - tier: "1", - from: "node0", - }, - { - name: "claims_disabled", - balanceToClaim: 500_000, - setupFn: func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state := genesis - var err error - - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte("500000")) - require.NoError(t, err) - - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("false")) - require.NoError(t, err) - - return state - }, - expectSuccess: false, - expectedError: "claim is disabled", - claimAttempts: 1, - tier: "1", - from: "node0", - }, - { - name: "claim_period_expired", - balanceToClaim: 500_000, - setupFn: func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state := genesis - var err error - - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte("500000")) - require.NoError(t, err) - - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("true")) - require.NoError(t, err) - - endTime := time.Now().Add(10 * time.Second).Unix() - state, err = sjson.SetRawBytes(state, "app_state.claim.params.claim_end_time", []byte(strconv.FormatInt(endTime, 10))) - require.NoError(t, err) - - return state - }, - expectSuccess: false, - expectedError: "claim is disabled", - waitBeforeClaim: true, - claimAttempts: 1, - tier: "1", - from: "node0", - }, - { - name: "duplicate_claim", - balanceToClaim: 500_000, - setupFn: func(t *testing.T, cli *LumeradCli) (claimtestutils.TestData, string) { - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - return testData, testData.OldAddress - }, - modifyGenesis: func(genesis []byte) []byte { - state := genesis - var err error - - // Set total claimable amount - state, err = sjson.SetRawBytes(state, "app_state.claim.total_claimable_amount", []byte("500000")) - require.NoError(t, err) - - // Set claims per block to 1 - state, err = sjson.SetRawBytes(state, "app_state.claim.params.max_claims_per_block", []byte("10")) - require.NoError(t, err) - - // Enable claims - state, err = sjson.SetRawBytes(state, "app_state.claim.params.enable_claims", []byte("true")) - require.NoError(t, err) - - // Set reasonable claim end time - endTime := time.Now().Add(1 * time.Hour).Unix() - state, err = sjson.SetRawBytes(state, "app_state.claim.params.claim_end_time", []byte(strconv.FormatInt(endTime, 10))) - require.NoError(t, err) - - return state - }, - expectSuccess: false, - expectedError: "claim already claimed", - waitBeforeClaim: false, - claimAttempts: 2, // Try to claim 2 times - tier: "1", - from: "node0", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - sut.ResetChain(t) - - cli := NewLumeradCLI(t, sut, true) - - // Get test data and CSV address - testData, csvAddress := tc.setupFn(t, cli) - - // Apply custom genesis modifications - sut.ModifyGenesisJSON(t, tc.modifyGenesis) - - var pastelAccount claimtestutils.PastelAccount - if tc.name == "successful_claim_from_same_address" { - var err error - pastelAccount, err = claimtestutils.GeneratePastelAddress() - require.NoError(t, err) - csvAddress = pastelAccount.Address - } - - // generate CSV file with claim data - claimsPath, err := claimtestutils.GenerateClaimsCSVFile([]claimtestutils.ClaimCSVRecord{ - { - OldAddress: csvAddress, - Amount: tc.balanceToClaim, - }, - }, nil) - require.NoError(t, err) - - t.Cleanup(func() { - claimtestutils.CleanupClaimsCSVFile(claimsPath) - }) - - // Start the chain with modified genesis - sut.StartChain(t, fmt.Sprintf("--%s=%s", claimtypes.FlagClaimsPath, claimsPath)) - - // Wait when needed - if tc.waitBeforeClaim { - t.Log("Waiting for claim period to expire...") - time.Sleep(11 * time.Second) - } - - if tc.name == "successful_claim_from_same_address" { - address := cli.AddKey("test_1") - cli.FundAddress(address, "1" + lcfg.ChainDenom) - testData, err = claimtestutils.GenerateClaimingTestData2(pastelAccount, address) - require.NoError(t, err) - - // Verify account exist and it is Base account - baseAccount := cli.GetAccount(testData.NewAddress) - require.NotNil(t, baseAccount, "account not found") - baseAccountType := gjson.Get(baseAccount, "account.type").String() - require.Equal(t, "/cosmos.auth.v1beta1.BaseAccount", baseAccountType, "account type mismatch") - } - - var lastResp string - // Register claim multiple times if specified - for i := 0; i < tc.claimAttempts; i++ { - registerCmd := []string{ - "tx", "claim", "delayed-claim", - testData.OldAddress, // Old address - testData.NewAddress, // New address - testData.PubKey, // PubKey - testData.Signature, // Signature - tc.tier, // Tier - "--from", tc.from, // From address - } - - lastResp = cli.CustomCommand(registerCmd...) - - // For multiple attempts, only the first one should succeed - if i == 0 && tc.expectSuccess { - RequireTxSuccess(t, lastResp) - } - } - - // Validate the final response - if tc.expectSuccess { - RequireTxSuccess(t, lastResp) - - // Get txhash and query transaction - txHash := gjson.Get(lastResp, "txhash").String() - require.NotEmpty(t, txHash, "txhash not found in response") - - txResp := cli.CustomQuery("q", "tx", txHash) - require.NotEmpty(t, txResp) - - // Verify delayed_claim_processed event and transfer from module - events := gjson.Get(txResp, "events") - require.True(t, events.Exists()) - - foundClaimEvent := false - foundModuleTransfer := false - - var claimTime, delayedTime int64 - for _, event := range events.Array() { - eventType := event.Get("type").String() - attrs := event.Get("attributes").Array() - - // Check delayed_claim_processed event - if eventType == "delayed_claim_processed" { - foundClaimEvent = true - for _, attr := range attrs { - key := attr.Get("key").String() - value := attr.Get("value").String() - switch key { - case "module": - require.Equal(t, "claim", value) - case "amount": - require.Equal(t, strconv.FormatUint(tc.balanceToClaim, 10) + claimtypes.DefaultClaimsDenom, value) - case "old_address": - require.Equal(t, testData.OldAddress, value) - case "new_address": - require.Equal(t, testData.NewAddress, value) - case "delayed_end_time": - delayedTime = attr.Get("value").Int() - case "claim_time": - claimTime = attr.Get("value").Int() - } - } - require.Greater(t, delayedTime, claimTime, "delayed_end_time should be greater than claim_time") - // delayedTime = claimTime + 6 month * tc.tier - //tier, _ := strconv.ParseInt(tc.tier, 10, 64) - //endTime := time.Unix(claimTime, 0).AddDate(0, int(tier*6), 0).Unix() - 3600 - //require.Equal(t, endTime, delayedTime, "delayed_end_time should be equal to claim_time + 6 month * tc.tier") - } - - // Check for transfer from module to recipient - if eventType == "transfer" { - // Only interested in msg_index=0 which relates to the claim operation - msgIndexAttr := false - for _, attr := range attrs { - if attr.Get("key").String() == "msg_index" && attr.Get("value").String() == "0" { - msgIndexAttr = true - break - } - } - - if msgIndexAttr { - recipient := "" - amount := "" - - for _, attr := range attrs { - if attr.Get("key").String() == "recipient" { - recipient = attr.Get("value").String() - } else if attr.Get("key").String() == "amount" { - amount = attr.Get("value").String() - } - } - - if recipient == testData.NewAddress && - amount == (strconv.FormatUint(tc.balanceToClaim, 10) + claimtypes.DefaultClaimsDenom) { - foundModuleTransfer = true - } - } - } - } - - require.True(t, foundClaimEvent, "claim_processed event not found") - require.True(t, foundModuleTransfer, "module transfer to recipient not found") - - // Verify balance after claim - balance := cli.QueryBalance(testData.NewAddress, claimtypes.DefaultClaimsDenom) - require.Equal(t, tc.balanceToClaim, balance) - - // Verify vested account creation - vestingAccount := cli.GetAccount(testData.NewAddress) - require.NotNil(t, vestingAccount, "account not found") - // Check if the account is a vesting account - vestingAccountType := gjson.Get(vestingAccount, "account.type").String() - require.Equal(t, "/cosmos.vesting.v1beta1.DelayedVestingAccount", vestingAccountType, "account type mismatch") - // Check if the account has a vesting schedule - vestingSchedule := gjson.Get(vestingAccount, "account.value.base_vesting_account.end_time").Int() - require.Greater(t, vestingSchedule, int64(0), "vesting schedule not found") - // check end_time is equal to delayed_end_time - require.Equal(t, delayedTime, vestingSchedule, "vesting schedule mismatch") - // Check if the account has a balance - vesting_balance := gjson.Get(vestingAccount, "account.value.base_vesting_account.original_vesting").Array() - require.NotEmpty(t, vesting_balance, "account balance not found") - // check amount is equal to balanceToClaim, convert to uint64 - amount := gjson.Get(vestingAccount, "account.value.base_vesting_account.original_vesting.0.amount").Uint() - require.Equal(t, tc.balanceToClaim, amount, "account balance mismatch") - } else { - RequireTxFailure(t, lastResp, tc.expectedError) - } - }) - } -} diff --git a/tests/systemtests/go.mod b/tests/systemtests/go.mod index 392ead95..af8a812f 100644 --- a/tests/systemtests/go.mod +++ b/tests/systemtests/go.mod @@ -4,50 +4,48 @@ go 1.25.5 replace ( github.com/LumeraProtocol/lumera => ../../ - - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.50.14 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 nhooyr.io/websocket => github.com/coder/websocket v1.8.7 ) +require ( + cosmossdk.io/math v1.5.3 + github.com/LumeraProtocol/lumera v1.9.1 + github.com/cometbft/cometbft v0.38.20 + github.com/cosmos/cosmos-sdk v0.53.5 + github.com/tidwall/gjson v1.14.2 + github.com/tidwall/sjson v1.2.5 + golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b +) + require ( github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.7.0 // indirect - github.com/cosmos/iavl v1.2.4 // indirect + github.com/cosmos/gogoproto v1.7.2 // indirect + 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.22.0 // 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-20250505200425-f936aa4a68b2 // indirect + google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/grpc v1.77.0 // indirect ) -require ( - cosmossdk.io/math v1.5.3 - github.com/LumeraProtocol/lumera v1.8.5 - github.com/cometbft/cometbft v0.38.18 - github.com/cosmos/cosmos-sdk v0.53.0 - github.com/tidwall/gjson v1.14.2 - github.com/tidwall/sjson v1.2.5 - golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b -) - require ( cosmossdk.io/api v0.9.2 // indirect - cosmossdk.io/collections v1.3.0 // indirect + cosmossdk.io/collections v1.3.1 // indirect cosmossdk.io/core v0.11.3 // indirect - cosmossdk.io/depinject v1.2.0 // indirect + cosmossdk.io/depinject v1.2.1 // indirect cosmossdk.io/errors v1.0.2 // indirect - cosmossdk.io/log v1.6.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/tx v0.14.0 // indirect @@ -62,8 +60,8 @@ require ( github.com/bgentry/speakeasy v0.2.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.1 // indirect - github.com/bytedance/sonic/loader v0.3.0 // 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 @@ -75,23 +73,23 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // 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.2 // indirect + github.com/cosmos/cosmos-db v1.1.3 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.14.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.1.1 // indirect + github.com/dgraph-io/ristretto v0.2.0 // indirect github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect github.com/dustin/go-humanize v1.0.1 // 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.32.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 @@ -99,8 +97,7 @@ require ( github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.5 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // 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 @@ -142,8 +139,8 @@ require ( github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // 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 @@ -159,26 +156,30 @@ require ( 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/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.14.3 // indirect + github.com/zondax/ledger-go v1.0.1 // indirect 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.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/arch v0.15.0 // indirect - golang.org/x/crypto v0.43.0 // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/text v0.30.0 // 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/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 - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.2 // indirect nhooyr.io/websocket v1.8.17 // indirect pgregory.net/rapid v1.2.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) replace ( diff --git a/tests/systemtests/go.sum b/tests/systemtests/go.sum index 66dc7e1f..df5a502e 100644 --- a/tests/systemtests/go.sum +++ b/tests/systemtests/go.sum @@ -37,16 +37,16 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= -cosmossdk.io/collections v1.3.0 h1:RUY23xXBy/bu5oSHZ5y+mkJRyA4ZboKDO4Yvx4+g2uc= -cosmossdk.io/collections v1.3.0/go.mod h1:cqVpBMDGEYhuNmNSXIOmqpnQ7Eav43hpJIetzLuEkns= +cosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw= +cosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c= 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.0 h1:6NW/FSK1IkWTrX7XxUpBmX1QMBozpEI9SsWkKTBc5zw= -cosmossdk.io/depinject v1.2.0/go.mod h1:pvitjtUxZZZTQESKNS9KhGjWVslJZxtO9VooRJYyPjk= +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/log v1.6.0 h1:SJIOmJ059wi1piyRgNRXKXhlDXGqnB5eQwhcZKv2tOk= -cosmossdk.io/log v1.6.0/go.mod h1:5cXXBvfBkR2/BcXmosdCSLXllvgSjphrrDVdfVRmBGM= +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= cosmossdk.io/math v1.5.3/go.mod h1:uqcZv7vexnhMFJF+6zh9EWdm/+Ylyln34IvPnBauPCQ= cosmossdk.io/schema v1.1.0 h1:mmpuz3dzouCoyjjcMcA/xHBEmMChN+EHh8EHxHRHhzE= @@ -110,12 +110,12 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E= github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= -github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +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/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +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.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -132,10 +132,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.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= -github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +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/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= @@ -185,8 +185,8 @@ 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.18 h1:1ZHYMdu0S75YxFM13LlPXnOwiIpUW5z9TKMQtTIALpw= -github.com/cometbft/cometbft v0.38.18/go.mod h1:PlOQgf3jQorep+g6oVnJgtP65TJvBJoLiXjGaMdNxBE= +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-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/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -197,29 +197,29 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.1.2 h1:KZm4xLlPp6rLkyIOmPOhh+XDK9oH1++pNH/csLdX0Dk= -github.com/cosmos/cosmos-db v1.1.2/go.mod h1:dMg2gav979Ig2N076POEw4CEKbCsieaOfDWSfFZxs8M= +github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= +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.50.14 h1:G8CtGHFWbExa+ZpVOVAb4kFmko/R30igsYOwyzRMtgY= -github.com/cosmos/cosmos-sdk v0.50.14/go.mod h1:hrWEFMU1eoXqLJeE6VVESpJDQH67FS1nnMrQIjO2daw= +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/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= -github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= -github.com/cosmos/iavl v1.2.4 h1:IHUrG8dkyueKEY72y92jajrizbkZKPZbMmG14QzsEkw= -github.com/cosmos/iavl v1.2.4/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw= -github.com/cosmos/ibc-go/v10 v10.3.0 h1:w5DkHih8qn15deAeFoTk778WJU+xC1krJ5kDnicfUBc= -github.com/cosmos/ibc-go/v10 v10.3.0/go.mod h1:CthaR7n4d23PJJ7wZHegmNgbVcLXCQql7EwHrAXnMtw= +github.com/cosmos/gogoproto v1.7.2 h1:5G25McIraOC0mRFv9TVO139Uh3OklV2hczr13KKVHCA= +github.com/cosmos/gogoproto v1.7.2/go.mod h1:8S7w53P1Y1cHwND64o0BnArT6RmdgIvsBuco6uTllsk= +github.com/cosmos/iavl v1.2.6 h1:Hs3LndJbkIB+rEvToKJFXZvKo6Vy0Ex1SJ54hhtioIs= +github.com/cosmos/iavl v1.2.6/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw= +github.com/cosmos/ibc-go/v10 v10.5.0 h1:NI+cX04fXdu9JfP0V0GYeRi1ENa7PPdq0BYtVYo8Zrs= +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/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.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= -github.com/cosmos/ledger-cosmos-go v0.14.0/go.mod h1:E07xCWSBl3mTGofZ2QnL4cIUzMbbGVyik84QYKbX3RA= +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/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/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -240,9 +240,8 @@ github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs= github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= +github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= @@ -250,7 +249,6 @@ github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vma github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= @@ -286,8 +284,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.32.0 h1:YKs+//QmwE3DcYtfKRH8/KyOOF/I6Qnx7qYGNHCGmCY= -github.com/getsentry/sentry-go v0.32.0/go.mod h1:CYNcMMz73YigoHljQRG+qPF+eMq8gG72XcGN/p71BAY= +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/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= @@ -331,9 +329,8 @@ github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= 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/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= 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= @@ -349,14 +346,12 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -407,7 +402,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -517,8 +511,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 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/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= -github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +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= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= @@ -571,8 +565,8 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/linxGnu/grocksdb v1.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs= github.com/linxGnu/grocksdb v1.9.8/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LFV4wIZuHk= github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -625,8 +619,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -695,8 +690,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -712,8 +707,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.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +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/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= @@ -721,8 +716,8 @@ 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.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= 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= @@ -795,6 +790,8 @@ 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.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= @@ -829,10 +826,12 @@ 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/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= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= -github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +github.com/zondax/ledger-go v1.0.1 h1:Ks/2tz/dOF+dbRynfZ0dEhcdL1lqw43Sa0zMXHpQ3aQ= +github.com/zondax/ledger-go v1.0.1/go.mod h1:j7IgMY39f30apthJYMd1YsHZRqdyu4KbVmUp0nU78X0= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.4.0-alpha.1 h1:3yrqQzbRRPFPdOMWS/QQIVxVnzSkAZQYeWlZFv1kbj4= go.etcd.io/bbolt v1.4.0-alpha.1/go.mod h1:S/Z/Nm3iuOnyO1W4XuFfPci51Gj6F1Hv0z8hisyYYOw= @@ -872,14 +871,20 @@ go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 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/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.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +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= @@ -899,8 +904,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.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +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/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= @@ -996,8 +1001,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.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= 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= @@ -1023,8 +1028,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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +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/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= @@ -1096,7 +1101,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1105,8 +1109,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.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.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= @@ -1116,8 +1120,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.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +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/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= @@ -1133,8 +1137,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.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +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/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= @@ -1277,8 +1281,8 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78= -google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= +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= @@ -1326,8 +1330,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1373,6 +1377,6 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/tests/systemtests/main_test.go b/tests/systemtests/main_test.go index ae964643..19bde2d5 100644 --- a/tests/systemtests/main_test.go +++ b/tests/systemtests/main_test.go @@ -31,6 +31,8 @@ func TestMain(m *testing.M) { blockTime := flag.Duration("block-time", 1000*time.Millisecond, "block creation time") execBinary := flag.String("binary", "lumerad", "executable binary for server/ client side") bech32Prefix := flag.String("bech32", "lumera", "bech32 prefix to be used with addresses") + claimsPath := flag.String("claims-path", "", "path to claims.csv file or directory") + skipClaimsCheck := flag.Bool("skip-claims-check", false, "skip claims.csv validation") flag.BoolVar(&verbose, "verbose", true, "verbose output") flag.Parse() @@ -53,6 +55,8 @@ func TestMain(m *testing.M) { } execBinaryName = *execBinary sut = NewSystemUnderTest(*execBinary, verbose, *nodesCount, *blockTime) + sut.SetClaimsPath(*claimsPath) + sut.SetSkipClaimsCheck(*skipClaimsCheck) if *rebuild { sut.BuildNewBinary() } diff --git a/tests/systemtests/system.go b/tests/systemtests/system.go index 350dc450..b591b23b 100644 --- a/tests/systemtests/system.go +++ b/tests/systemtests/system.go @@ -47,11 +47,13 @@ var ( // SystemUnderTest blockchain provisioning type SystemUnderTest struct { - ExecBinary string - blockListener *EventListener - currentHeight int64 - chainID string - outputDir string + ExecBinary string + blockListener *EventListener + currentHeight int64 + chainID string + outputDir string + claimsPath string + skipClaimsCheck bool // blockTime is the expected/desired block time. This is not going to be very precise // since Tendermint consensus does not allow specifying it directly. blockTime time.Duration @@ -168,7 +170,14 @@ func (s *SystemUnderTest) StartChain(t *testing.T, xargs ...string) { t.Helper() s.Log("Start chain\n") s.ChainStarted = true - s.startNodesAsync(t, append([]string{"start", "--trace", "--log_level=info"}, xargs...)...) + args := []string{"start", "--trace", "--log_level=info"} + if s.claimsPath != "" { + args = append(args, "--claims-path="+s.claimsPath) + } + if s.skipClaimsCheck { + args = append(args, "--skip-claims-check") + } + s.startNodesAsync(t, append(args, xargs...)...) s.AwaitNodeUp(t, s.rpcAddr) @@ -184,6 +193,14 @@ func (s *SystemUnderTest) StartChain(t *testing.T, xargs ...string) { s.AwaitNextBlock(t, 4e9) } +func (s *SystemUnderTest) SetClaimsPath(path string) { + s.claimsPath = path +} + +func (s *SystemUnderTest) SetSkipClaimsCheck(skip bool) { + s.skipClaimsCheck = skip +} + // MarkDirty whole chain will be reset when marked dirty func (s *SystemUnderTest) MarkDirty() { s.dirty = true diff --git a/tests/testdata/escrow_0.7.wasm b/tests/testdata/escrow_0.7.wasm new file mode 100644 index 00000000..668aa74e Binary files /dev/null and b/tests/testdata/escrow_0.7.wasm differ diff --git a/tests/testdata/ibc2.wasm b/tests/testdata/ibc2.wasm index a5643c41..ab33e483 100644 Binary files a/tests/testdata/ibc2.wasm and b/tests/testdata/ibc2.wasm differ diff --git a/tests/testdata/ibc_callbacks.wasm b/tests/testdata/ibc_callbacks.wasm index 63519505..1bdaea16 100644 Binary files a/tests/testdata/ibc_callbacks.wasm and b/tests/testdata/ibc_callbacks.wasm differ diff --git a/x/action/v1/simulation/helpers.go b/x/action/v1/simulation/helpers.go index 0779376b..ba8504fe 100644 --- a/x/action/v1/simulation/helpers.go +++ b/x/action/v1/simulation/helpers.go @@ -26,16 +26,16 @@ import ( func registerSenseAction(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, bk types.BankKeeper, k keeper.Keeper, ak types.AuthKeeper) (string, *types.MsgRequestAction) { params := k.GetParams(ctx) - // 1. Select random account with enough balance - simAccount := selectRandomAccountWithSufficientFunds(r, ctx, accs, bk, ak, []string{""}) + // 1. Determine fee amount (within valid range) + feeAmount := generateRandomFee(r, ctx, params.BaseActionFee.Add(params.FeePerKbyte)) + + // 2. Select random account with enough spendable balance for the fee + simAccount := selectRandomAccountWithSufficientFunds(r, ctx, accs, bk, ak, feeAmount, []string{""}) - // 2. Generate random valid SENSE metadata + // 3. Generate random valid SENSE metadata dataHash := generateRandomHash(r) senseMetadata := generateRequestActionSenseMetadata(dataHash) - // 3. Determine fee amount (within valid range) - feeAmount := generateRandomFee(r, ctx, params.BaseActionFee.Add(params.FeePerKbyte)) - // 4. Generate an expiration time (current time + random duration >= expiration_duration) expirationTime := getRandomExpirationTime(ctx, r, params) @@ -65,23 +65,17 @@ func registerSenseAction(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, func registerCascadeAction(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, bk types.BankKeeper, k keeper.Keeper, ak types.AuthKeeper) (string, *types.MsgRequestAction) { params := k.GetParams(ctx) - // 1. Select random account with enough balance - simAccount := selectRandomAccountWithSufficientFunds(r, ctx, accs, bk, ak, []string{""}) + // 1. Determine fee amount (within valid range) + feeAmount := generateRandomFee(r, ctx, params.BaseActionFee.Add(params.FeePerKbyte)) - // 2. Set account public key - err := addPubKeyToAccount(ctx, simAccount, ak) - if err != nil { - panic(fmt.Sprintf("failed to set account public key: %v", err)) - } + // 2. Select random account with enough spendable balance for the fee + simAccount := selectRandomAccountWithSufficientFunds(r, ctx, accs, bk, ak, feeAmount, []string{""}) - // 2. Generate random valid CASCADE metadata + // 3. Generate random valid CASCADE metadata dataHash := generateRandomHash(r) fileName := generateRandomFileName(r) cascadeMetadata := generateRequestActionCascadeMetadata(dataHash, fileName, simAccount) - // 3. Determine fee amount (within valid range) - feeAmount := generateRandomFee(r, ctx, params.BaseActionFee.Add(params.FeePerKbyte)) - // 4. Generate an expiration time (current time + random duration) expirationTime := getRandomExpirationTime(ctx, r, params) @@ -123,7 +117,7 @@ func finalizeSenseAction(ctx sdk.Context, k keeper.Keeper, bk types.BankKeeper, // Create finalization metadata with signature metadata := generateFinalizeMetadataForSense(ctx, k, actionID, supernodes) - // Get supernode's initial balance to verify no fee distribution + // Get supernode's initial balance to verify it doesn't decrease feeDenom := k.GetParams(ctx).BaseActionFee.Denom initialBalance := bk.GetBalance(ctx, supernodes[0].Address, feeDenom) @@ -151,8 +145,8 @@ func finalizeSenseAction(ctx sdk.Context, k keeper.Keeper, bk types.BankKeeper, } finalBalance := bk.GetBalance(ctx, supernodes[0].Address, feeDenom) - if !finalBalance.Equal(initialBalance) { - panic(fmt.Sprintf("supernode %s balance changed after FinalizeAction, expected no fee distribution", supernodes[0].Address.String())) + if finalBalance.Amount.LT(initialBalance.Amount) { + panic(fmt.Sprintf("supernode %s balance decreased after FinalizeAction", supernodes[0].Address.String())) } return finalMsg @@ -256,7 +250,7 @@ func addPubKeyToAccount(ctx sdk.Context, simAccount simtypes.Account, ak types.A } // selectRandomAccountWithSufficientFunds selects a random account that has enough balance to cover the specified fee amount -func selectRandomAccountWithSufficientFunds(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, bk types.BankKeeper, ak types.AuthKeeper, skipAddresses []string) simtypes.Account { +func selectRandomAccountWithSufficientFunds(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, bk types.BankKeeper, ak types.AuthKeeper, minFee sdk.Coin, skipAddresses []string) simtypes.Account { if len(accs) == 0 { panic("no accounts available to select") } @@ -273,8 +267,8 @@ func selectRandomAccountWithSufficientFunds(r *rand.Rand, ctx sdk.Context, accs continue } - balance := bk.GetBalance(ctx, simAccount.Address, sdk.DefaultBondDenom) - if balance.IsZero() || balance.Amount.LT(math.NewInt(1_000_000)) { + spendable := bk.SpendableCoins(ctx, simAccount.Address) + if spendable.IsZero() || spendable.AmountOf(minFee.Denom).LT(minFee.Amount) { continue } diff --git a/x/action/v1/simulation/request_action.go b/x/action/v1/simulation/request_action.go index 67111e69..f5622ce7 100644 --- a/x/action/v1/simulation/request_action.go +++ b/x/action/v1/simulation/request_action.go @@ -74,24 +74,24 @@ func SimulateMsgRequestActionInvalidMetadata( ) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - // 1. Select random account with enough balance - simAccount := selectRandomAccountWithSufficientFunds(r, ctx, accs, bk, ak, []string{""}) - params := k.GetParams(ctx) - // 2. Get initial balance + // 1. Determine fee amount + feeAmount := generateRandomFee(r, ctx, params.BaseActionFee) + + // 2. Select random account with enough spendable balance + simAccount := selectRandomAccountWithSufficientFunds(r, ctx, accs, bk, ak, feeAmount, []string{""}) + + // 3. Get initial balance denom := params.BaseActionFee.Denom initialBalance := bk.GetBalance(ctx, simAccount.Address, denom) - // 3. Randomly select action type + // 4. Randomly select action type actionType := selectRandomActionType(r) - // 4. Generate invalid metadata based on action type + // 5. Generate invalid metadata based on action type invalidMetadata := generateRequestActionInvalidMetadata(r, actionType, simAccount) - // 5. Determine fee amount - feeAmount := generateRandomFee(r, ctx, params.BaseActionFee) - // 6. Generate an expiration time (current time + random duration) expirationTime := getRandomExpirationTime(ctx, r, params) diff --git a/x/claim/keeper/abci_test.go b/x/claim/keeper/abci_test.go deleted file mode 100644 index 5f9a9f7f..00000000 --- a/x/claim/keeper/abci_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package keeper_test - -import ( - "testing" - "time" - - _ "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestBeginBlocker(t *testing.T) { -} - -func TestEndBlocker(t *testing.T) { - keeper, ctx := keepertest.ClaimKeeper(t, "") - - testCases := []struct { - name string - setupParams types.Params - blockTime time.Time - expectDisable bool - }{ - { - name: "claims still active", - setupParams: types.Params{ - EnableClaims: true, - ClaimEndTime: time.Now().Add(time.Hour).Unix(), - }, - blockTime: time.Now(), - expectDisable: false, - }, - { - name: "claims should end", - setupParams: types.Params{ - EnableClaims: true, - ClaimEndTime: time.Now().Unix(), - }, - blockTime: time.Now().Add(time.Second), - expectDisable: true, - }, - { - name: "claims already disabled", - setupParams: types.Params{ - EnableClaims: false, - ClaimEndTime: time.Now().Unix(), - }, - blockTime: time.Now(), - expectDisable: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Setup test case - ctx = ctx.WithBlockTime(tc.blockTime) - err := keeper.SetParams(ctx, tc.setupParams) - require.NoError(t, err) - - // Run EndBlocker - err = keeper.EndBlocker(ctx) - require.NoError(t, err) - - // Verify final state - params := keeper.GetParams(ctx) - if tc.expectDisable { - require.False(t, params.EnableClaims, "claims should be disabled") - } else { - require.Equal(t, tc.setupParams.EnableClaims, params.EnableClaims, - "claims enable state should not change") - } - }) - } -} diff --git a/x/claim/keeper/claim_count_per_block_test.go b/x/claim/keeper/claim_count_per_block_test.go deleted file mode 100644 index 9556d859..00000000 --- a/x/claim/keeper/claim_count_per_block_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package keeper_test - -import ( - "testing" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - "github.com/stretchr/testify/require" -) - -func TestBlockClaimCount(t *testing.T) { - testCases := []struct { - name string - operations []string - expectedCount uint64 - }{ - { - name: "initial count is zero", - operations: []string{}, - expectedCount: 0, - }, - { - name: "single increment", - operations: []string{"increment"}, - expectedCount: 1, - }, - { - name: "multiple increments", - operations: []string{"increment", "increment", "increment"}, - expectedCount: 3, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - keeper, ctx := keepertest.ClaimKeeper(t, "") - - // Initial count should be zero. - count, err := keeper.GetBlockClaimCount(ctx) - require.NoError(t, err) - require.Equal(t, uint64(0), count, "initial count should be zero") - - // Perform operations. - for _, op := range tc.operations { - if op == "increment" { - err := keeper.IncrementBlockClaimCount(ctx) - require.NoError(t, err) - } - } - - // Check final count. - count, err = keeper.GetBlockClaimCount(ctx) - require.NoError(t, err) - require.Equal(t, tc.expectedCount, count, "unexpected final count") - }) - } -} diff --git a/x/claim/keeper/claim_record_test.go b/x/claim/keeper/claim_record_test.go deleted file mode 100644 index 7a81352f..00000000 --- a/x/claim/keeper/claim_record_test.go +++ /dev/null @@ -1,289 +0,0 @@ -package keeper_test - -import ( - "testing" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - "github.com/LumeraProtocol/lumera/x/claim/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestGetClaimRecord(t *testing.T) { - testCases := []struct { - name string - setupRecord *types.ClaimRecord - queryAddress string - expectFound bool - expectErr bool - expectRecord types.ClaimRecord - }{ - { - name: "non-existent record", - setupRecord: nil, - queryAddress: "test_address", - expectFound: false, - expectErr: false, - expectRecord: types.ClaimRecord{}, - }, - { - name: "existing record", - setupRecord: &types.ClaimRecord{ - OldAddress: "test_address", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: false, - }, - queryAddress: "test_address", - expectFound: true, - expectErr: false, - }, - { - name: "query wrong address", - setupRecord: &types.ClaimRecord{ - OldAddress: "test_address", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: false, - }, - queryAddress: "wrong_address", - expectFound: false, - expectErr: false, - expectRecord: types.ClaimRecord{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - - // Setup - if tc.setupRecord != nil { - err := k.SetClaimRecord(ctx, *tc.setupRecord) - require.NoError(t, err) - tc.expectRecord = *tc.setupRecord - } - - // Test - record, found, err := k.GetClaimRecord(ctx, tc.queryAddress) - - if tc.expectErr { - require.Error(t, err) - return - } - require.NoError(t, err) - require.Equal(t, tc.expectFound, found) - if tc.expectFound { - require.Equal(t, tc.expectRecord, record) - } - }) - } -} - -func TestSetClaimRecord(t *testing.T) { - testCases := []struct { - name string - initialRecord *types.ClaimRecord - recordToSet types.ClaimRecord - expectErr bool - }{ - { - name: "set new record", - initialRecord: nil, - recordToSet: types.ClaimRecord{ - OldAddress: "test_address", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: false, - }, - expectErr: false, - }, - { - name: "update existing record", - initialRecord: &types.ClaimRecord{ - OldAddress: "test_address", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: false, - }, - recordToSet: types.ClaimRecord{ - OldAddress: "test_address", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: true, - }, - expectErr: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - - // Setup - if tc.initialRecord != nil { - err := k.SetClaimRecord(ctx, *tc.initialRecord) - require.NoError(t, err) - } - - // Test - err := k.SetClaimRecord(ctx, tc.recordToSet) - if tc.expectErr { - require.Error(t, err) - return - } - require.NoError(t, err) - - // Verify - record, found, err := k.GetClaimRecord(ctx, tc.recordToSet.OldAddress) - require.NoError(t, err) - require.True(t, found) - require.Equal(t, tc.recordToSet, record) - }) - } -} - -func TestListClaimed(t *testing.T) { - testCases := []struct { - name string - setupRecords []types.ClaimRecord - vestedTerm uint32 - expectClaimed int - expectErr bool - }{ - { - name: "empty state", - setupRecords: nil, - vestedTerm: 1, - expectClaimed: 0, - expectErr: false, - }, - { - name: "no claimed records", - setupRecords: []types.ClaimRecord{ - { - OldAddress: "address1", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: false, - VestedTier: 1, - }, - { - OldAddress: "address2", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(200))), - Claimed: false, - VestedTier: 2, - }, - }, - vestedTerm: 1, - expectClaimed: 0, - expectErr: false, - }, - { - name: "claimed records with different vested tiers", - setupRecords: []types.ClaimRecord{ - { - OldAddress: "address1", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: true, - VestedTier: 1, - }, - { - OldAddress: "address2", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(200))), - Claimed: true, - VestedTier: 2, - }, - { - OldAddress: "address3", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(300))), - Claimed: true, - VestedTier: 1, - }, - }, - vestedTerm: 1, - expectClaimed: 2, - expectErr: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - q := keeper.NewQueryServerImpl(k) - - // Setup - if tc.setupRecords != nil { - for _, record := range tc.setupRecords { - err := k.SetClaimRecord(ctx, record) - require.NoError(t, err) - } - } - - // Test - req := &types.QueryListClaimedRequest{ - VestedTerm: tc.vestedTerm, - } - resp, err := q.ListClaimed(ctx, req) - - if tc.expectErr { - require.Error(t, err) - return - } - require.NoError(t, err) - require.NotNil(t, resp) - require.Equal(t, tc.expectClaimed, len(resp.Claims)) - - // Verify all returned records are claimed and have the correct vested tier - for _, claim := range resp.Claims { - require.True(t, claim.Claimed) - require.Equal(t, tc.vestedTerm, claim.VestedTier) - } - }) - } -} - -func TestGetClaimRecordCount(t *testing.T) { - testCases := []struct { - name string - setupRecords []types.ClaimRecord - expectCount uint64 - }{ - { - name: "initial empty state", - setupRecords: nil, - expectCount: 0, - }, - { - name: "multiple records", - setupRecords: []types.ClaimRecord{ - { - OldAddress: "address1", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(100))), - Claimed: false, - }, - { - OldAddress: "address2", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(200))), - Claimed: false, - }, - }, - expectCount: 2, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - - // Setup - if tc.setupRecords != nil { - for _, record := range tc.setupRecords { - err := k.SetClaimRecord(ctx, record) - require.NoError(t, err) - } - } - - // Test - count := k.GetClaimRecordCount(ctx) - require.Equal(t, tc.expectCount, count) - }) - } -} diff --git a/x/claim/keeper/crypto/utils_test.go b/x/claim/keeper/crypto/utils_test.go deleted file mode 100644 index de58ad41..00000000 --- a/x/claim/keeper/crypto/utils_test.go +++ /dev/null @@ -1,304 +0,0 @@ -package crypto - -import ( - "encoding/hex" - "strings" - "testing" - - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" -) - -func TestGetAddressFromPubKey(t *testing.T) { - tests := []struct { - name string - pubKey string - expectedAddress string - expectError bool - }{ - { - name: "Valid public key", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - expectedAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - expectError: false, - }, - { - name: "Invalid hex string", - pubKey: "invalid", - expectedAddress: "", - expectError: true, - }, - { - name: "Empty public key", - pubKey: "", - expectedAddress: "", - expectError: true, // hex.DecodeString will fail for empty string - }, - { - name: "Odd length hex string", - pubKey: "123", - expectedAddress: "", - expectError: true, - }, - { - name: "Wrong length public key (32 bytes)", - pubKey: strings.Repeat("00", 32), - expectedAddress: "", - expectError: false, - }, - { - name: "Public key with invalid prefix (not 0x02 or 0x03)", - pubKey: "0409331fc3d23ca17d91eec40ee7711efcd56facf949d46cbfa6393d43f2747e90", - expectedAddress: "", - expectError: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - address, err := GetAddressFromPubKey(tt.pubKey) - if tt.expectError { - if err == nil { - t.Errorf("Expected an error for input '%s', but got none", tt.pubKey) - } - } else { - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if tt.expectedAddress != "" && address != tt.expectedAddress { - t.Errorf("Expected address %s, but got %s", tt.expectedAddress, address) - } - } - }) - } -} - -func TestVerifySignature(t *testing.T) { - tests := []struct { - name string - pubKey string - message string - signature string - expectValid bool - expectError bool - }{ - { - name: "Valid signature", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - message: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc.038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12.lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - expectValid: true, - expectError: false, - }, - { - name: "Modified signature", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - message: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc.038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12.lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - signature: "1f46b3a2129047a0d7a6bf91e2879e940ed3db06a2cafaaaabacc337141146f43e4932d357b435bbf2c48227f5c2f738df23a2ebc221dd11cb14ed4b83bd2a95c8", - expectValid: false, - expectError: false, - }, - { - name: "Invalid public key hex", - pubKey: "invalid", - message: "test", - signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - expectValid: false, - expectError: true, - }, - { - name: "Empty public key", - pubKey: "", - message: "test", - signature: "1f46b3a2129047a0d7a6bf91e2879e940ed3db06a2cafaaaabacc337141146f43e4932d357b435bbf2c48227f5c2f738df23a2ebc221dd11cb14ed4b83bd2a95c7", - expectValid: false, - expectError: true, - }, - { - name: "Invalid signature hex", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - message: "test", - signature: "invalid", - expectValid: false, - expectError: true, - }, - { - name: "Empty signature", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - message: "test", - signature: "", - expectValid: false, - expectError: true, - }, - { - name: "Empty message", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - message: "", - signature: "1f46b3a2129047a0d7a6bf91e2879e940ed3db06a2cafaaaabacc337141146f43e4932d357b435bbf2c48227f5c2f738df23a2ebc221dd11cb14ed4b83bd2a95c7", - expectValid: false, - expectError: false, - }, - { - name: "Wrong length signature (64 bytes)", - pubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - message: "test", - signature: strings.Repeat("00", 64), - expectValid: false, - expectError: true, - }, - { - name: "Invalid public key format (wrong length)", - pubKey: strings.Repeat("00", 32), // 64 chars = 32 bytes instead of 33 - message: "test", - signature: "1f46b3a2129047a0d7a6bf91e2879e940ed3db06a2cafaaaabacc337141146f43e4932d357b435bbf2c48227f5c2f738df23a2ebc221dd11cb14ed4b83bd2a95c7", - expectValid: false, - expectError: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - isValid, err := VerifySignature(tt.pubKey, tt.message, tt.signature) - if tt.expectError { - if err == nil { - t.Errorf("Expected an error, but got none") - } - } else { - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if isValid != tt.expectValid { - t.Errorf("Expected validity %v, but got %v", tt.expectValid, isValid) - } - } - }) - } -} - -func TestGenerateKeyPair(t *testing.T) { - // Test multiple key pairs to ensure consistency - for i := 0; i < 10; i++ { - privKey, pubKey := GenerateKeyPair() - - // Test private key - if privKey == nil { - t.Fatal("Expected private key, got nil") - } - if len(privKey.Bytes()) != 32 { - t.Errorf("Expected private key length 32, got %d", len(privKey.Bytes())) - } - - // Test public key - if pubKey == nil { - t.Fatal("Expected public key, got nil") - } - if len(pubKey.Bytes()) != 33 { - t.Errorf("Expected compressed public key length 33, got %d", len(pubKey.Bytes())) - } - - // Verify public key format (should start with 0x02 or 0x03) - firstByte := pubKey.Bytes()[0] - if firstByte != 0x02 && firstByte != 0x03 { - t.Errorf("Invalid public key format: first byte should be 0x02 or 0x03, got 0x%x", firstByte) - } - - // Verify key pair relationship - derivedPub := privKey.PubKey() - if !derivedPub.Equals(pubKey) { - t.Error("Derived public key doesn't match generated public key") - } - } -} - -func TestSignMessage(t *testing.T) { - tests := []struct { - name string - message string - useNilKey bool - expectError bool - }{ - { - name: "Valid message", - message: "test message", - useNilKey: false, - expectError: false, - }, - { - name: "Empty message", - message: "", - useNilKey: false, - expectError: false, - }, - { - name: "Long message", - message: strings.Repeat("test", 1000), - useNilKey: false, - expectError: false, - }, - { - name: "Message with special characters", - message: "!@#$%^&*()_+-=[]{}|;:,.<>?", - useNilKey: false, - expectError: false, - }, - { - name: "Unicode message", - message: "Hello, 世界", - useNilKey: false, - expectError: false, - }, - { - name: "Nil private key", - message: "test message", - useNilKey: true, - expectError: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var privKey *secp256k1.PrivKey - var pubKey *secp256k1.PubKey - - if !tt.useNilKey { - privKey, pubKey = GenerateKeyPair() - } - - // Sign the message - signature, err := SignMessage(privKey, tt.message) - if tt.expectError { - if err == nil { - t.Errorf("Expected an error, but got none") - } - return - } - - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - // Verify signature format - sigBytes, err := hex.DecodeString(signature) - if err != nil { - t.Fatalf("Failed to decode signature hex: %v", err) - } - - if len(sigBytes) != 65 { - t.Errorf("Expected signature length 65, got %d", len(sigBytes)) - } - - if sigBytes[0] != 27 && sigBytes[0] != 28 { - t.Errorf("Invalid recovery byte: expected 27 or 28, got %d", sigBytes[0]) - } - - // Verify the signature using VerifySignature - pubKeyHex := hex.EncodeToString(pubKey.Bytes()) - isValid, err := VerifySignature(pubKeyHex, tt.message, signature) - if err != nil { - t.Fatalf("Signature verification failed with error: %v", err) - } - if !isValid { - t.Error("Signature verification failed") - } - }) - } -} diff --git a/x/claim/keeper/msg_server_claim_test.go b/x/claim/keeper/msg_server_claim_test.go deleted file mode 100644 index bfa8b018..00000000 --- a/x/claim/keeper/msg_server_claim_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package keeper_test - -import ( - "testing" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestMsgClaim(t *testing.T) { - k, ms, ctx := setupMsgServer(t) - - // Define valid claim record with proper coin denomination - validClaimRecord := types.ClaimRecord{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(1000000))), - Claimed: false, - } - - testCases := []struct { - name string - msg *types.MsgClaim - setup func() - expErr bool - expErrMsg string - }{ - { - name: "valid claim", - msg: &types.MsgClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = true - params.MaxClaimsPerBlock = 10 - params.ClaimEndTime = sdkCtx.BlockTime().Unix() + 3600 // 1 hour from now - require.NoError(t, k.SetParams(sdkCtx, params)) - - // Set fresh claim record - require.NoError(t, k.SetClaimRecord(sdkCtx, validClaimRecord)) - - // Set fee in context - fee := sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(1000))) - ctx = sdkCtx.WithValue(types.ClaimTxFee, fee) - }, - expErr: false, - }, - { - name: "claims disabled", - msg: &types.MsgClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = false - require.NoError(t, k.SetParams(sdkCtx, params)) - require.NoError(t, k.SetClaimRecord(sdkCtx, validClaimRecord)) - }, - expErr: true, - expErrMsg: types.ErrClaimDisabled.Error(), - }, - { - name: "claim period expired", - msg: &types.MsgClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = true - params.ClaimEndTime = sdkCtx.BlockTime().Unix() - 3600 // 1 hour ago - require.NoError(t, k.SetParams(sdkCtx, params)) - require.NoError(t, k.SetClaimRecord(sdkCtx, validClaimRecord)) - }, - expErr: true, - expErrMsg: types.ErrClaimPeriodExpired.Error(), - }, - { - name: "already claimed", - msg: &types.MsgClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = true - require.NoError(t, k.SetParams(sdkCtx, params)) - - claimedRecord := validClaimRecord - claimedRecord.Claimed = true - require.NoError(t, k.SetClaimRecord(sdkCtx, claimedRecord)) - }, - expErr: true, - expErrMsg: types.ErrClaimAlreadyClaimed.Error(), - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if tc.setup != nil { - tc.setup() - } - - resp, err := ms.Claim(ctx, tc.msg) - - if tc.expErr { - require.Error(t, err) - require.Contains(t, err.Error(), tc.expErrMsg) - require.Nil(t, resp) - } else { - require.NoError(t, err) - require.NotNil(t, resp) - - // Check claim record was updated - sdkCtx := sdk.UnwrapSDKContext(ctx) - record, found, err := k.GetClaimRecord(sdkCtx, tc.msg.OldAddress) - require.NoError(t, err) - require.True(t, found) - require.True(t, record.Claimed) - require.NotZero(t, record.ClaimTime) - } - }) - } -} diff --git a/x/claim/keeper/msg_server_delayed_claim_test.go b/x/claim/keeper/msg_server_delayed_claim_test.go deleted file mode 100644 index 656dd7b7..00000000 --- a/x/claim/keeper/msg_server_delayed_claim_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package keeper_test - -import ( - "testing" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestMsgDelayedClaim(t *testing.T) { - k, ms, ctx := setupMsgServer(t) - - // Define valid claim record with proper coin denomination - validClaimRecord := types.ClaimRecord{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(1000000))), - Claimed: false, - } - - testCases := []struct { - name string - msg *types.MsgDelayedClaim - setup func() - expErr bool - expErrMsg string - }{ - { - name: "valid claim", - msg: &types.MsgDelayedClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - Tier: 1, - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = true - params.MaxClaimsPerBlock = 10 - params.ClaimEndTime = sdkCtx.BlockTime().Unix() + 3600 // 1 hour from now - require.NoError(t, k.SetParams(sdkCtx, params)) - - // Set fresh claim record - require.NoError(t, k.SetClaimRecord(sdkCtx, validClaimRecord)) - - // Set fee in context - fee := sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(1000))) - ctx = sdkCtx.WithValue(types.ClaimTxFee, fee) - }, - expErr: false, - }, - { - name: "claims disabled", - msg: &types.MsgDelayedClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - Tier: 1, - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = false - require.NoError(t, k.SetParams(sdkCtx, params)) - require.NoError(t, k.SetClaimRecord(sdkCtx, validClaimRecord)) - }, - expErr: true, - expErrMsg: types.ErrClaimDisabled.Error(), - }, - { - name: "claim period expired", - msg: &types.MsgDelayedClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - Tier: 1, - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = true - params.ClaimEndTime = sdkCtx.BlockTime().Unix() - 3600 // 1 hour ago - require.NoError(t, k.SetParams(sdkCtx, params)) - require.NoError(t, k.SetClaimRecord(sdkCtx, validClaimRecord)) - }, - expErr: true, - expErrMsg: types.ErrClaimPeriodExpired.Error(), - }, - { - name: "already claimed", - msg: &types.MsgDelayedClaim{ - OldAddress: "Ptko7ZkiQXyT9Db45GtsewpnhnRRwpHkHBc", - NewAddress: "lumera1zvnc27832srgxa207y5hu2agy83wazfzurufyp", - PubKey: "038685010ec7ce724c1f83ba333564135feadf70eade12036546f20b95ce276a12", - Signature: "1f4926307e7d94f5290058f8836429963431b3f7fc091567f1621a510d25cbcb71240f9c4488d9cafa16c8c3457d07c263afcfe4c77e0081a4e75bb618e99e1cd3", - Tier: 1, - }, - setup: func() { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := types.DefaultParams() - params.EnableClaims = true - require.NoError(t, k.SetParams(sdkCtx, params)) - - claimedRecord := validClaimRecord - claimedRecord.Claimed = true - require.NoError(t, k.SetClaimRecord(sdkCtx, claimedRecord)) - }, - expErr: true, - expErrMsg: types.ErrClaimAlreadyClaimed.Error(), - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if tc.setup != nil { - tc.setup() - } - - resp, err := ms.DelayedClaim(ctx, tc.msg) - - if tc.expErr { - require.Error(t, err) - require.Contains(t, err.Error(), tc.expErrMsg) - require.Nil(t, resp) - } else { - require.NoError(t, err) - require.NotNil(t, resp) - - // Check claim record was updated - sdkCtx := sdk.UnwrapSDKContext(ctx) - record, found, err := k.GetClaimRecord(sdkCtx, tc.msg.OldAddress) - require.NoError(t, err) - require.True(t, found) - require.True(t, record.Claimed) - require.NotZero(t, record.ClaimTime) - } - }) - } -} diff --git a/x/claim/keeper/msg_server_test.go b/x/claim/keeper/msg_server_test.go deleted file mode 100644 index 4ae9d33c..00000000 --- a/x/claim/keeper/msg_server_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package keeper_test - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - "github.com/LumeraProtocol/lumera/x/claim/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func setupMsgServer(t testing.TB) (keeper.Keeper, types.MsgServer, sdk.Context) { - k, ctx := keepertest.ClaimKeeper(t, "") - return k, keeper.NewMsgServerImpl(k), ctx -} - -func TestMsgServer(t *testing.T) { - k, ms, ctx := setupMsgServer(t) - require.NotNil(t, ms) - require.NotNil(t, ctx) - require.NotEmpty(t, k) -} - -//Done diff --git a/x/claim/keeper/msg_update_params_test.go b/x/claim/keeper/msg_update_params_test.go deleted file mode 100644 index 9b86dbac..00000000 --- a/x/claim/keeper/msg_update_params_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package keeper_test - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestMsgUpdateParams(t *testing.T) { - k, ms, ctx := setupMsgServer(t) - params := types.DefaultParams() - require.NoError(t, k.SetParams(ctx, params)) - wctx := sdk.UnwrapSDKContext(ctx) - - // default params - testCases := []struct { - name string - input *types.MsgUpdateParams - expErr bool - expErrMsg string - }{ - { - name: "invalid authority", - input: &types.MsgUpdateParams{ - Authority: "invalid", - Params: params, - }, - expErr: true, - expErrMsg: "invalid authority", - }, - { - name: "send enabled param", - input: &types.MsgUpdateParams{ - Authority: k.GetAuthority(), - Params: types.Params{}, - }, - expErr: false, - }, - { - name: "all good", - input: &types.MsgUpdateParams{ - Authority: k.GetAuthority(), - Params: params, - }, - expErr: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - _, err := ms.UpdateParams(wctx, tc.input) - - if tc.expErr { - require.Error(t, err) - require.Contains(t, err.Error(), tc.expErrMsg) - } else { - require.NoError(t, err) - } - }) - } -} - -//Done diff --git a/x/claim/keeper/params_test.go b/x/claim/keeper/params_test.go deleted file mode 100644 index e732e478..00000000 --- a/x/claim/keeper/params_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package keeper_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestGetParams(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - params := types.DefaultParams() - - require.NoError(t, k.SetParams(ctx, params)) - require.EqualValues(t, params, k.GetParams(ctx)) -} - -//Done diff --git a/x/claim/keeper/query_claim_record_test.go b/x/claim/keeper/query_claim_record_test.go deleted file mode 100644 index c23b001f..00000000 --- a/x/claim/keeper/query_claim_record_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package keeper_test - -import ( - "testing" - - "cosmossdk.io/math" - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" - "github.com/LumeraProtocol/lumera/x/claim/keeper" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -func TestClaimRecordQuery(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - q := keeper.NewQueryServerImpl(k) - - // Define a valid claim record using real Pastel network values - validRecord := types.ClaimRecord{ - OldAddress: "PtqHAEacynVd3V821NPhgxu9K4Ab6kAguHi", - Balance: sdk.NewCoins(sdk.NewCoin(types.DefaultClaimsDenom, math.NewInt(1000000))), - Claimed: false, - } - - testCases := []struct { - name string - request *types.QueryClaimRecordRequest - setup func() - expErr bool - expCode codes.Code - expRecord *types.ClaimRecord - }{ - { - name: "empty request", - request: nil, - setup: func() {}, - expErr: true, - expCode: codes.InvalidArgument, - expRecord: nil, - }, - { - name: "query non-existent record", - request: &types.QueryClaimRecordRequest{ - Address: "PtqInvalidAddressXXXXXXXXXXXXXXXXXXXX", - }, - setup: func() {}, - expErr: true, - expCode: codes.NotFound, - expRecord: nil, - }, - { - name: "query existing record", - request: &types.QueryClaimRecordRequest{ - Address: validRecord.OldAddress, - }, - setup: func() { - err := k.SetClaimRecord(ctx, validRecord) - require.NoError(t, err) - }, - expErr: false, - expRecord: &validRecord, - }, - { - name: "query claimed record", - request: &types.QueryClaimRecordRequest{ - Address: "PtqHAEacynVd3V821NPhgxu9K4Ab6kAguHi", - }, - setup: func() { - claimedRecord := validRecord - claimedRecord.Claimed = true - err := k.SetClaimRecord(ctx, claimedRecord) - require.NoError(t, err) - }, - expErr: false, - expRecord: &types.ClaimRecord{ - OldAddress: "PtqHAEacynVd3V821NPhgxu9K4Ab6kAguHi", - Balance: validRecord.Balance, - Claimed: true, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Setup test state - tc.setup() - - // Execute query - response, err := q.ClaimRecord(ctx, tc.request) - - // Verify results - if tc.expErr { - require.Error(t, err) - statusErr, ok := status.FromError(err) - require.True(t, ok) - require.Equal(t, tc.expCode, statusErr.Code()) - require.Nil(t, response) - } else { - require.NoError(t, err) - require.NotNil(t, response) - require.Equal(t, tc.expRecord.OldAddress, response.Record.OldAddress) - require.Equal(t, tc.expRecord.Balance, response.Record.Balance) - require.Equal(t, tc.expRecord.Claimed, response.Record.Claimed) - } - }) - } -} diff --git a/x/claim/keeper/query_params_test.go b/x/claim/keeper/query_params_test.go deleted file mode 100644 index 687409c5..00000000 --- a/x/claim/keeper/query_params_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package keeper_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - - "github.com/LumeraProtocol/lumera/x/claim/keeper" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestParamsQuery(t *testing.T) { - k, ctx := keepertest.ClaimKeeper(t, "") - q := keeper.NewQueryServerImpl(k) - - params := types.DefaultParams() - require.NoError(t, k.SetParams(ctx, params)) - - response, err := q.Params(ctx, &types.QueryParamsRequest{}) - require.NoError(t, err) - require.Equal(t, &types.QueryParamsResponse{Params: params}, response) -} - -//Done diff --git a/x/claim/module/genesis_test.go b/x/claim/module/genesis_test.go deleted file mode 100644 index 9b77543b..00000000 --- a/x/claim/module/genesis_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package claim_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - keepertest "github.com/LumeraProtocol/lumera/testutil/keeper" - claim "github.com/LumeraProtocol/lumera/x/claim/module" - claimtestutils "github.com/LumeraProtocol/lumera/x/claim/testutils" - "github.com/LumeraProtocol/lumera/x/claim/types" -) - -func TestGenesis(t *testing.T) { - // Get the default genesis state first - defaultGenState := types.DefaultGenesis() - - // Create test genesis state matching the default values - genesisState := types.GenesisState{ - Params: types.DefaultParams(), - // Set to 0 in tests to avoid loading external CSV totals - TotalClaimableAmount: 0, - // Will be populated during initialization - ClaimRecords: []types.ClaimRecord{}, // Empty records for test - ClaimsDenom: types.DefaultClaimsDenom, - } - - testData, err := claimtestutils.GenerateClaimingTestData() - require.NoError(t, err) - - // generate a CSV file with the test data - claimsPath, err := claimtestutils.GenerateClaimsCSVFile([]claimtestutils.ClaimCSVRecord{ - {OldAddress: testData.OldAddress, Amount: defaultGenState.TotalClaimableAmount}, - }, nil) - require.NoError(t, err) - // Ensure the file is cleaned up after the test - t.Cleanup(func() { - claimtestutils.CleanupClaimsCSVFile(claimsPath) - }) - - k, ctx := keepertest.ClaimKeeper(t, claimsPath) - claim.InitGenesis(ctx, k, genesisState) - got := claim.ExportGenesis(ctx, k) - require.NotNil(t, got) - - // Verify params - require.Equal(t, genesisState.Params, got.Params) - - // Verify the module account exists - moduleAcc := k.GetAccountKeeper().GetModuleAccount(ctx, types.ModuleName) - require.NotNil(t, moduleAcc) - require.Equal(t, types.ModuleName, moduleAcc.GetName()) - - // Verify permissions - require.Contains(t, moduleAcc.GetPermissions(), "minter") - require.Contains(t, moduleAcc.GetPermissions(), "burner") - - // Verify total claimable amount matches default genesis state - require.Equal(t, defaultGenState.TotalClaimableAmount, got.TotalClaimableAmount) -} diff --git a/x/claim/simulation/claim.go b/x/claim/simulation/claim.go index d7fd38b0..59d9d6f9 100644 --- a/x/claim/simulation/claim.go +++ b/x/claim/simulation/claim.go @@ -6,9 +6,9 @@ import ( "encoding/hex" + claimcrypto "github.com/LumeraProtocol/lumera/x/claim/keeper/crypto" "github.com/LumeraProtocol/lumera/x/claim/keeper" "github.com/LumeraProtocol/lumera/x/claim/types" - "github.com/cometbft/cometbft/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" @@ -34,10 +34,12 @@ func SimulateMsgClaim( } // Generate simulated keys and addresses - privKey := secp256k1.GenPrivKey() - pubKeyBytes := privKey.PubKey().Bytes() - pubKeyHex := hex.EncodeToString(pubKeyBytes) - oldAddress := sdk.AccAddress(privKey.PubKey().Address()).String() + privKey, pubKey := claimcrypto.GenerateKeyPair() + pubKeyHex := hex.EncodeToString(pubKey.Key) + oldAddress, err := claimcrypto.GetAddressFromPubKey(pubKeyHex) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, TypeMsgClaim, "failed to generate claim address"), nil, err + } testAmount := int64(1_000_000) // Amount to be claimed in the test case @@ -67,7 +69,7 @@ func SimulateMsgClaim( // Generate message signature message := fmt.Sprintf("%s.%s.%s", oldAddress, pubKeyHex, simAccount.Address.String()) - signature, err := privKey.Sign([]byte(message)) + signature, err := claimcrypto.SignMessage(privKey, message) if err != nil { return simtypes.NoOpMsg(types.ModuleName, TypeMsgClaim, "failed to sign message"), nil, err } @@ -76,7 +78,7 @@ func SimulateMsgClaim( OldAddress: oldAddress, NewAddress: simAccount.Address.String(), PubKey: pubKeyHex, - Signature: hex.EncodeToString(signature), + Signature: signature, } // Check if we've hit the claims per block limit diff --git a/x/claim/types/genesis_test.go b/x/claim/types/genesis_test.go deleted file mode 100644 index 2f506021..00000000 --- a/x/claim/types/genesis_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package types_test - -import ( - "fmt" - "testing" - "time" - - "github.com/LumeraProtocol/lumera/x/claim/types" - "github.com/stretchr/testify/require" -) - -func TestGenesisState_Validate(t *testing.T) { - // Setup common test values - validEndTime := time.Now().Add(time.Hour * 48).Unix() - - testCases := []struct { - name string - genState *types.GenesisState - expErr bool - }{ - { - name: "default genesis state", - genState: types.DefaultGenesis(), - expErr: false, - }, - { - name: "valid genesis state - empty records", - genState: types.NewGenesisState( - types.Params{ - EnableClaims: true, - ClaimEndTime: validEndTime, - MaxClaimsPerBlock: 50, - }, - []types.ClaimRecord{}, // Should always be empty in genesis - - types.DefaultClaimableAmountConst, // Fixed claimable amount - types.DefaultClaimsDenom, - ), - expErr: false, - }, - { - name: "invalid params - negative end time", - genState: types.NewGenesisState( - types.Params{ - EnableClaims: true, - ClaimEndTime: -1, - MaxClaimsPerBlock: 50, - }, - []types.ClaimRecord{}, - - types.DefaultClaimableAmountConst, - types.DefaultClaimsDenom, - ), - expErr: true, - }, - { - name: "invalid params - zero max claims", - genState: types.NewGenesisState( - types.Params{ - EnableClaims: true, - ClaimEndTime: validEndTime, - MaxClaimsPerBlock: 0, - }, - []types.ClaimRecord{}, - - types.DefaultClaimableAmountConst, - types.DefaultClaimsDenom, - ), - expErr: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := tc.genState.Validate() - - if tc.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestDefaultGenesis(t *testing.T) { - genState := types.DefaultGenesis() - require.NotNil(t, genState) - require.Equal(t, types.DefaultParams(), genState.Params) - require.Empty(t, genState.ClaimRecords, "Genesis claim records should be empty") - require.Equal(t, uint64(types.DefaultClaimableAmountConst), genState.TotalClaimableAmount, fmt.Sprintf("total claimable amount should be fixed at %d", types.DefaultClaimableAmountConst)) - // Validate default genesis state - require.NoError(t, genState.Validate()) -} - -func TestNewGenesisState(t *testing.T) { - params := types.DefaultParams() - genState := types.NewGenesisState( - params, - []types.ClaimRecord{}, // Should be empty in genesis - types.DefaultClaimableAmountConst, // Fixed claimable amount - types.DefaultClaimsDenom, - ) - - require.NotNil(t, genState) - require.Equal(t, params, genState.Params) - require.Empty(t, genState.ClaimRecords, "Genesis claim records should be empty") - require.Equal(t, uint64(types.DefaultClaimableAmountConst), genState.TotalClaimableAmount, fmt.Sprintf("Total claimable amount should be fixed at %d", types.DefaultClaimableAmountConst)) -} diff --git a/x/claim/types/message_delayed_claim_test.go b/x/claim/types/message_delayed_claim_test.go deleted file mode 100644 index 27493c48..00000000 --- a/x/claim/types/message_delayed_claim_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package types - -import ( - "testing" - - "github.com/LumeraProtocol/lumera/testutil/sample" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/stretchr/testify/require" -) - -func TestMsgDelayedClaim_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg MsgDelayedClaim - err error - }{ - { - name: "invalid address", - msg: MsgDelayedClaim{ - Creator: "invalid_address", - }, - err: sdkerrors.ErrInvalidAddress, - }, { - name: "valid address", - msg: MsgDelayedClaim{ - Creator: sample.AccAddress(), - Tier: 1, - }, - }, { - name: "invalid tier", - msg: MsgDelayedClaim{ - Creator: sample.AccAddress(), - Tier: 7, - }, - err: sdkerrors.ErrInvalidRequest, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.msg.ValidateBasic() - if tt.err != nil { - require.ErrorIs(t, err, tt.err) - return - } - require.NoError(t, err) - }) - } -} diff --git a/x/lumeraid/module/depinject.go b/x/lumeraid/module/depinject.go new file mode 100644 index 00000000..53071585 --- /dev/null +++ b/x/lumeraid/module/depinject.go @@ -0,0 +1,73 @@ +package lumeraid + +import ( + "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/store" + "cosmossdk.io/depinject" + "cosmossdk.io/log" + "github.com/cosmos/cosmos-sdk/codec" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/LumeraProtocol/lumera/x/lumeraid/keeper" + "github.com/LumeraProtocol/lumera/x/lumeraid/types" +) + +var _ depinject.OnePerModuleType = AppModule{} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (AppModule) IsOnePerModuleType() {} + +// ---------------------------------------------------------------------------- +// App Wiring Setup +// ---------------------------------------------------------------------------- + +func init() { + appmodule.Register( + &Module{}, + appmodule.Provide(ProvideModule), + ) +} + +type ModuleInputs struct { + depinject.In + + StoreService store.KVStoreService + Cdc codec.Codec + Config *Module + Logger log.Logger + + AccountKeeper types.AccountKeeper + BankKeeper types.BankKeeper +} + +type ModuleOutputs struct { + depinject.Out + + LumeraidKeeper keeper.Keeper + Module appmodule.AppModule +} + +func ProvideModule(in ModuleInputs) ModuleOutputs { + // default to governance authority if not provided + authority := authtypes.NewModuleAddress(govtypes.ModuleName) + if in.Config.Authority != "" { + authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority) + } + k := keeper.NewKeeper( + in.Cdc, + in.StoreService, + in.Logger, + authority.String(), + in.BankKeeper, + in.AccountKeeper, + ) + m := NewAppModule( + in.Cdc, + k, + in.AccountKeeper, + in.BankKeeper, + ) + + return ModuleOutputs{LumeraidKeeper: k, Module: m} +} diff --git a/x/lumeraid/module/module.go b/x/lumeraid/module/module.go index 628155c8..a94c818c 100644 --- a/x/lumeraid/module/module.go +++ b/x/lumeraid/module/module.go @@ -9,16 +9,11 @@ import ( "github.com/spf13/cobra" "cosmossdk.io/core/appmodule" - "cosmossdk.io/core/store" - "cosmossdk.io/depinject" - "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/grpc-ecosystem/grpc-gateway/runtime" // this line is used by starport scaffolding # 1 @@ -170,62 +165,5 @@ func (am AppModule) EndBlock(_ context.Context) error { return nil } -// IsOnePerModuleType implements the depinject.OnePerModuleType interface. -func (am AppModule) IsOnePerModuleType() {} - // IsAppModule implements the appmodule.AppModule interface. func (am AppModule) IsAppModule() {} - -// ---------------------------------------------------------------------------- -// App Wiring Setup -// ---------------------------------------------------------------------------- - -func init() { - appmodule.Register( - &Module{}, - appmodule.Provide(ProvideModule), - ) -} - -type ModuleInputs struct { - depinject.In - - StoreService store.KVStoreService - Cdc codec.Codec - Config *Module - Logger log.Logger - - AccountKeeper types.AccountKeeper - BankKeeper types.BankKeeper -} - -type ModuleOutputs struct { - depinject.Out - - LumeraidKeeper keeper.Keeper - Module appmodule.AppModule -} - -func ProvideModule(in ModuleInputs) ModuleOutputs { - // default to governance authority if not provided - authority := authtypes.NewModuleAddress(govtypes.ModuleName) - if in.Config.Authority != "" { - authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority) - } - k := keeper.NewKeeper( - in.Cdc, - in.StoreService, - in.Logger, - authority.String(), - in.BankKeeper, - in.AccountKeeper, - ) - m := NewAppModule( - in.Cdc, - k, - in.AccountKeeper, - in.BankKeeper, - ) - - return ModuleOutputs{LumeraidKeeper: k, Module: m} -} diff --git a/x/supernode/v1/simulation/register_supernode.go b/x/supernode/v1/simulation/register_supernode.go index b8ec9aba..71c05687 100644 --- a/x/supernode/v1/simulation/register_supernode.go +++ b/x/supernode/v1/simulation/register_supernode.go @@ -42,6 +42,15 @@ func SimulateMsgRegisterSupernode( continue } + // Ensure the account isn't already associated with a different validator. + if snByAccount, foundByAccount, err := k.GetSuperNodeByAccount(ctx, simAccount.Address.String()); err == nil && foundByAccount { + if snByAccount.ValidatorAddress != valAddr.String() { + continue + } + } else if err != nil { + continue + } + // Check if supernode already exists and is not disabled supernode, superNodeExists := k.QuerySuperNode(ctx, valAddr) if superNodeExists {