From 67f633eb88c44d361b1db00dd245524b5fe87b37 Mon Sep 17 00:00:00 2001 From: Nicolas Lara Date: Thu, 23 Feb 2023 13:42:52 +0100 Subject: [PATCH] Added rate limits in upgrade (#4340) * added rate limits in upgrade * added upgrade test * refactor rate limiting tests and added rate limits pre-upgrade * lint * goimports * experiments for E2E * post merge lints * added RL before upgrade * just get the latest contract * experiments * updated wasm file * remove unnecessary prints * bad check * experiments without e2e * removed unnecessary fmt * param space initialization for rate limiting (#4360) * param space initialization for rate limiting * lint * better test * properly initialize empty params * fix typo * adding RL to E2E * removing RL again from E2E * debug * genesis * genesis 2 * add genesis and solve params bug * uncomment setup rate limiting * added configurable gov module * clean up * clean up and genesis test * upgrade handler * genesis clean up * clean up e2e * wire querier * route fix * fix router * debug things * fix init genesis bug * push fix * lint * fix * clean up upgrades * testing propper params after upgrade in E2E * "properly" unmarshaling the parm * goimports * allowing for types other than objects in cosmwasm queries * fix check for param reset * remove unnecessary prints * compiled with the proper vesion of workspace optimizer * Revert "compiled with the proper vesion of workspace optimizer" This reverts commit ab5cf6cd43789b3a7798f7bc06d9761704ac37c4. * added length check * params experiment for test with state-export --------- Co-authored-by: Roman Co-authored-by: Roman (cherry picked from commit a1e2b3d4ea00c4b1d108022477009ed3bbf33600) # Conflicts: # app/keepers/modules.go # app/modules.go # app/upgrades/v15/export_test.go # app/upgrades/v15/upgrade_test.go # app/upgrades/v15/upgrades.go # tests/e2e/configurer/chain/commands.go # tests/e2e/e2e_test.go --- app/keepers/keepers.go | 4 +- app/keepers/modules.go | 7 +- app/modules.go | 12 + app/upgrades/v15/export_test.go | 30 ++ app/upgrades/v15/upgrade_test.go | 161 +++++++++ app/upgrades/v15/upgrades.go | 217 ++++++++++++ .../ibc-rate-limit/v1beta1/genesis.proto | 15 + .../ibc-rate-limit/v1beta1/query.proto | 12 +- .../osmosis/ibc-rate-limit/v1beta1/query.yml | 10 + tests/e2e/configurer/chain/chain.go | 100 ++++++ tests/e2e/configurer/chain/commands.go | 39 ++- tests/e2e/configurer/chain/queries.go | 25 +- tests/e2e/configurer/upgrade.go | 11 + tests/e2e/e2e_test.go | 236 +++++++++---- x/ibc-rate-limit/client/cli/query.go | 5 +- x/ibc-rate-limit/client/grpc/grpc_query.go | 32 ++ x/ibc-rate-limit/client/query_proto_wrap.go | 21 ++ .../{types => client/queryproto}/query.pb.go | 158 ++++----- .../queryproto}/query.pb.gw.go | 8 +- x/ibc-rate-limit/genesis.go | 20 ++ x/ibc-rate-limit/genesis_test.go | 43 +++ x/ibc-rate-limit/ibc_module.go | 4 +- x/ibc-rate-limit/ibcratelimitmodule/module.go | 148 ++++++++ x/ibc-rate-limit/ics4_wrapper.go | 33 +- x/ibc-rate-limit/module.go | 58 --- x/ibc-rate-limit/types/genesis.go | 17 + x/ibc-rate-limit/types/genesis.pb.go | 329 ++++++++++++++++++ x/ibc-rate-limit/types/keys.go | 9 + x/ibc-rate-limit/types/params.go | 2 +- 29 files changed, 1521 insertions(+), 245 deletions(-) create mode 100644 app/upgrades/v15/export_test.go create mode 100644 app/upgrades/v15/upgrade_test.go create mode 100644 app/upgrades/v15/upgrades.go create mode 100644 proto/osmosis/ibc-rate-limit/v1beta1/genesis.proto create mode 100644 proto/osmosis/ibc-rate-limit/v1beta1/query.yml create mode 100644 x/ibc-rate-limit/client/grpc/grpc_query.go create mode 100644 x/ibc-rate-limit/client/query_proto_wrap.go rename x/ibc-rate-limit/{types => client/queryproto}/query.pb.go (62%) rename x/ibc-rate-limit/{types => client/queryproto}/query.pb.gw.go (98%) create mode 100644 x/ibc-rate-limit/genesis.go create mode 100644 x/ibc-rate-limit/genesis_test.go create mode 100644 x/ibc-rate-limit/ibcratelimitmodule/module.go delete mode 100644 x/ibc-rate-limit/module.go create mode 100644 x/ibc-rate-limit/types/genesis.go create mode 100644 x/ibc-rate-limit/types/genesis.pb.go diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 343a3036d92..09eeac98542 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -415,15 +415,13 @@ func (appKeepers *AppKeepers) WireICS20PreWasmKeeper( ) // ChannelKeeper wrapper for rate limiting SendPacket(). The wasmKeeper needs to be added after it's created - rateLimitingParams := appKeepers.GetSubspace(ibcratelimittypes.ModuleName) - rateLimitingParams = rateLimitingParams.WithKeyTable(ibcratelimittypes.ParamKeyTable()) rateLimitingICS4Wrapper := ibcratelimit.NewICS4Middleware( appKeepers.HooksICS4Wrapper, appKeepers.AccountKeeper, // wasm keeper we set later. nil, appKeepers.BankKeeper, - rateLimitingParams, + appKeepers.GetSubspace(ibcratelimittypes.ModuleName), ) appKeepers.RateLimitingICS4Wrapper = &rateLimitingICS4Wrapper diff --git a/app/keepers/modules.go b/app/keepers/modules.go index 24eafd9f277..9150609033e 100644 --- a/app/keepers/modules.go +++ b/app/keepers/modules.go @@ -31,7 +31,7 @@ import ( downtimemodule "github.com/osmosis-labs/osmosis/v14/x/downtime-detector/module" "github.com/osmosis-labs/osmosis/v14/x/epochs" "github.com/osmosis-labs/osmosis/v14/x/gamm" - ibc_rate_limit "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/ibcratelimitmodule" "github.com/osmosis-labs/osmosis/v14/x/incentives" "github.com/osmosis-labs/osmosis/v14/x/lockup" "github.com/osmosis-labs/osmosis/v14/x/mint" @@ -92,5 +92,10 @@ var AppModuleBasics = []module.AppModuleBasic{ wasm.AppModuleBasic{}, ica.AppModuleBasic{}, ibc_hooks.AppModuleBasic{}, +<<<<<<< HEAD ibc_rate_limit.AppModuleBasic{}, +======= + ibcratelimitmodule.AppModuleBasic{}, + router.AppModuleBasic{}, +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) } diff --git a/app/modules.go b/app/modules.go index f7e922a546a..a98f597f8d4 100644 --- a/app/modules.go +++ b/app/modules.go @@ -58,6 +58,8 @@ import ( epochstypes "github.com/osmosis-labs/osmosis/v14/x/epochs/types" "github.com/osmosis-labs/osmosis/v14/x/gamm" gammtypes "github.com/osmosis-labs/osmosis/v14/x/gamm/types" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/ibcratelimitmodule" + ibcratelimittypes "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" "github.com/osmosis-labs/osmosis/v14/x/incentives" incentivestypes "github.com/osmosis-labs/osmosis/v14/x/incentives/types" "github.com/osmosis-labs/osmosis/v14/x/lockup" @@ -151,6 +153,11 @@ func appModules( app.EpochsKeeper, ), tokenfactory.NewAppModule(*app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), +<<<<<<< HEAD +======= + valsetprefmodule.NewAppModule(appCodec, *app.ValidatorSetPreferenceKeeper), + ibcratelimitmodule.NewAppModule(*app.RateLimitingICS4Wrapper), +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) ibc_hooks.NewAppModule(app.AccountKeeper), } } @@ -227,6 +234,11 @@ func OrderInitGenesis(allModuleNames []string) []string { epochstypes.ModuleName, lockuptypes.ModuleName, authz.ModuleName, +<<<<<<< HEAD +======= + concentratedliquiditytypes.ModuleName, + ibcratelimittypes.ModuleName, +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) // wasm after ibc transfer wasm.ModuleName, // ibc_hooks after auth keeper diff --git a/app/upgrades/v15/export_test.go b/app/upgrades/v15/export_test.go new file mode 100644 index 00000000000..a5ae35d11b0 --- /dev/null +++ b/app/upgrades/v15/export_test.go @@ -0,0 +1,30 @@ +package v15 + +import ( + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + ibcratelimit "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit" + icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" + + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + gammkeeper "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" + poolmanagerkeeper "github.com/osmosis-labs/osmosis/v14/x/poolmanager" +) + +func MigrateNextPoolId(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanagerkeeper.Keeper) { + migrateNextPoolId(ctx, gammKeeper, poolmanagerKeeper) +} + +func RegisterOsmoIonMetadata(ctx sdk.Context, bankKeeper bankkeeper.Keeper) { + registerOsmoIonMetadata(ctx, bankKeeper) +} + +func SetICQParams(ctx sdk.Context, icqKeeper *icqkeeper.Keeper) { + setICQParams(ctx, icqKeeper) +} + +func SetRateLimits(ctx sdk.Context, accountKeeper *authkeeper.AccountKeeper, rateLimitingICS4Wrapper *ibcratelimit.ICS4Wrapper, wasmKeeper *wasmkeeper.Keeper) { + setRateLimits(ctx, accountKeeper, rateLimitingICS4Wrapper, wasmKeeper) +} diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go new file mode 100644 index 00000000000..a4a1012e764 --- /dev/null +++ b/app/upgrades/v15/upgrade_test.go @@ -0,0 +1,161 @@ +package v15_test + +import ( + "fmt" + "os" + "reflect" + "testing" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + + ibcratelimittypes "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" + + gamm "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" + + "github.com/stretchr/testify/suite" + + "github.com/osmosis-labs/osmosis/v14/app/apptesting" + v15 "github.com/osmosis-labs/osmosis/v14/app/upgrades/v15" +) + +type UpgradeTestSuite struct { + apptesting.KeeperTestHelper +} + +func (suite *UpgradeTestSuite) SetupTest() { + suite.Setup() +} + +func TestUpgradeTestSuite(t *testing.T) { + suite.Run(t, new(UpgradeTestSuite)) +} + +func (suite *UpgradeTestSuite) TestMigrateNextPoolIdAndCreatePool() { + suite.SetupTest() // reset + + const ( + expectedNextPoolId uint64 = 1 + ) + + var ( + gammKeeperType = reflect.TypeOf(&gamm.Keeper{}) + ) + + ctx := suite.Ctx + gammKeeper := suite.App.GAMMKeeper + poolmanagerKeeper := suite.App.PoolManagerKeeper + + nextPoolId := gammKeeper.GetNextPoolId(ctx) + suite.Require().Equal(expectedNextPoolId, nextPoolId) + + // system under test. + v15.MigrateNextPoolId(ctx, gammKeeper, poolmanagerKeeper) + + // validate poolmanager's next pool id. + actualNextPoolId := poolmanagerKeeper.GetNextPoolId(ctx) + suite.Require().Equal(expectedNextPoolId, actualNextPoolId) + + // create a pool after migration. + actualCreatedPoolId := suite.PrepareBalancerPool() + suite.Require().Equal(expectedNextPoolId, actualCreatedPoolId) + + // validate that module route mapping has been created for each pool id. + for poolId := uint64(1); poolId < expectedNextPoolId; poolId++ { + swapModule, err := poolmanagerKeeper.GetPoolModule(ctx, poolId) + suite.Require().NoError(err) + + suite.Require().Equal(gammKeeperType, reflect.TypeOf(swapModule)) + } + + // validate params + gammPoolCreationFee := gammKeeper.GetParams(ctx).PoolCreationFee + poolmanagerPoolCreationFee := poolmanagerKeeper.GetParams(ctx).PoolCreationFee + suite.Require().Equal(gammPoolCreationFee, poolmanagerPoolCreationFee) +} + +func (suite *UpgradeTestSuite) TestRegisterOsmoIonMetadata() { + suite.SetupTest() // reset + + expectedUosmodenom := "uosmo" + expectedUiondenom := "uion" + + ctx := suite.Ctx + bankKeeper := suite.App.BankKeeper + + // meta data should not be found pre-registration of meta data + uosmoMetadata, found := suite.App.BankKeeper.GetDenomMetaData(ctx, "uosmo") + suite.Require().False(found) + + uionMetadata, found := suite.App.BankKeeper.GetDenomMetaData(ctx, "uion") + suite.Require().False(found) + + // system under test. + v15.RegisterOsmoIonMetadata(ctx, *bankKeeper) + + uosmoMetadata, found = suite.App.BankKeeper.GetDenomMetaData(ctx, "uosmo") + suite.Require().True(found) + + uionMetadata, found = suite.App.BankKeeper.GetDenomMetaData(ctx, "uion") + suite.Require().True(found) + + suite.Require().Equal(expectedUosmodenom, uosmoMetadata.Base) + suite.Require().Equal(expectedUiondenom, uionMetadata.Base) +} + +func (suite *UpgradeTestSuite) TestSetICQParams() { + suite.SetupTest() // reset + + // system under test. + v15.SetICQParams(suite.Ctx, suite.App.ICQKeeper) + + suite.Require().True(suite.App.ICQKeeper.IsHostEnabled(suite.Ctx)) + suite.Require().Len(suite.App.ICQKeeper.GetAllowQueries(suite.Ctx), 63) +} + +func (suite *UpgradeTestSuite) TestSetRateLimits() { + suite.SetupTest() // reset + accountKeeper := suite.App.AccountKeeper + govModule := accountKeeper.GetModuleAddress(govtypes.ModuleName) + + code, err := os.ReadFile("../v13/rate_limiter.wasm") + suite.Require().NoError(err) + contractKeeper := wasmkeeper.NewGovPermissionKeeper(suite.App.WasmKeeper) + instantiateConfig := wasmtypes.AccessConfig{Permission: wasmtypes.AccessTypeOnlyAddress, Address: govModule.String()} + codeID, _, err := contractKeeper.Create(suite.Ctx, govModule, code, &instantiateConfig) + suite.Require().NoError(err) + transferModule := accountKeeper.GetModuleAddress(transfertypes.ModuleName) + initMsgBz := []byte(fmt.Sprintf(`{ + "gov_module": "%s", + "ibc_module":"%s", + "paths": [] + }`, + govModule, transferModule)) + + addr, _, err := contractKeeper.Instantiate(suite.Ctx, codeID, govModule, govModule, initMsgBz, "rate limiting contract", nil) + suite.Require().NoError(err) + addrStr, err := sdk.Bech32ifyAddressBytes("osmo", addr) + suite.Require().NoError(err) + params, err := ibcratelimittypes.NewParams(addrStr) + suite.Require().NoError(err) + paramSpace, ok := suite.App.ParamsKeeper.GetSubspace(ibcratelimittypes.ModuleName) + suite.Require().True(ok) + paramSpace.SetParamSet(suite.Ctx, ¶ms) + + // system under test. + v15.SetRateLimits(suite.Ctx, accountKeeper, suite.App.RateLimitingICS4Wrapper, suite.App.WasmKeeper) + + state, err := suite.App.WasmKeeper.QuerySmart(suite.Ctx, addr, []byte(`{"get_quotas": {"channel_id": "any", "denom": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2"}}`)) + suite.Require().Greaterf(len(state), 0, "state should not be empty") + + state, err = suite.App.WasmKeeper.QuerySmart(suite.Ctx, addr, []byte(`{"get_quotas": {"channel_id": "any", "denom": "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858"}}`)) + suite.Require().Greaterf(len(state), 0, "state should not be empty") + + // This is the last one. If the others failed the upgrade would've panicked before adding this one + state, err = suite.App.WasmKeeper.QuerySmart(suite.Ctx, addr, []byte(`{"get_quotas": {"channel_id": "any", "denom": "ibc/E6931F78057F7CC5DA0FD6CEF82FF39373A6E0452BF1FD76910B93292CF356C1"}}`)) + suite.Require().Greaterf(len(state), 0, "state should not be empty") + +} diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go new file mode 100644 index 00000000000..3cb1419eb51 --- /dev/null +++ b/app/upgrades/v15/upgrades.go @@ -0,0 +1,217 @@ +package v15 + +import ( + packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + + poolmanagertypes "github.com/osmosis-labs/osmosis/v14/x/poolmanager/types" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" + icqtypes "github.com/strangelove-ventures/async-icq/v4/types" + + "github.com/osmosis-labs/osmosis/v14/wasmbinding" + ibcratelimit "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit" + ibcratelimittypes "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" + + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + "github.com/osmosis-labs/osmosis/v14/app/keepers" + appParams "github.com/osmosis-labs/osmosis/v14/app/params" + "github.com/osmosis-labs/osmosis/v14/app/upgrades" + gammkeeper "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" + "github.com/osmosis-labs/osmosis/v14/x/poolmanager" +) + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + bpm upgrades.BaseAppParamManager, + keepers *keepers.AppKeepers, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + poolmanagerParams := poolmanagertypes.NewParams(keepers.GAMMKeeper.GetParams(ctx).PoolCreationFee) + + keepers.PoolManagerKeeper.SetParams(ctx, poolmanagerParams) + keepers.PacketForwardKeeper.SetParams(ctx, packetforwardtypes.DefaultParams()) + setICQParams(ctx, keepers.ICQKeeper) + + // N.B: pool id in gamm is to be deprecated in the future + // Instead,it is moved to poolmanager. + migrateNextPoolId(ctx, keepers.GAMMKeeper, keepers.PoolManagerKeeper) + + // N.B.: this is done to avoid initializing genesis for poolmanager module. + // Otherwise, it would overwrite migrations with InitGenesis(). + // See RunMigrations() for details. + fromVM[poolmanagertypes.ModuleName] = 0 + + // N.B.: this is done to avoid initializing genesis for ibcratelimit module. + // Otherwise, it would overwrite migrations with InitGenesis(). + // See RunMigrations() for details. + fromVM[ibcratelimittypes.ModuleName] = 0 + + // Metadata for uosmo and uion were missing prior to this upgrade. + // They are added in this upgrade. + registerOsmoIonMetadata(ctx, keepers.BankKeeper) + + setRateLimits(ctx, keepers.AccountKeeper, keepers.RateLimitingICS4Wrapper, keepers.WasmKeeper) + + return mm.RunMigrations(ctx, configurator, fromVM) + } +} + +func setICQParams(ctx sdk.Context, icqKeeper *icqkeeper.Keeper) { + icqparams := icqtypes.DefaultParams() + icqparams.AllowQueries = wasmbinding.GetStargateWhitelistedPaths() + // Adding SmartContractState query to allowlist + icqparams.AllowQueries = append(icqparams.AllowQueries, "/cosmwasm.wasm.v1.Query/SmartContractState") + icqKeeper.SetParams(ctx, icqparams) +} + +func setRateLimits(ctx sdk.Context, accountKeeper *authkeeper.AccountKeeper, rateLimitingICS4Wrapper *ibcratelimit.ICS4Wrapper, wasmKeeper *wasmkeeper.Keeper) { + govModule := accountKeeper.GetModuleAddress(govtypes.ModuleName) + contractKeeper := wasmkeeper.NewGovPermissionKeeper(wasmKeeper) + + paths := []string{ + `{"add_path": {"channel_id": "any", "denom": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", + "quotas": + [ + {"name":"ATOM-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"ATOM-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858", + "quotas": + [ + {"name":"USDC-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"USDC-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F", + "quotas": + [ + {"name":"WBTC-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"WBTC-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/EA1D43981D5C9A1C4AAEA9C23BB1D4FA126BA9BC7020A25E0AE4AA841EA25DC5", + "quotas": + [ + {"name":"WETH-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"WETH-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/6AE98883D4D5D5FF9E50D7130F1305DA2FFA0C652D1DD9C123657C6B4EB2DF8A", + "quotas": + [ + {"name":"EVMOS-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"EVMOS-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/987C17B11ABC2B20019178ACE62929FE9840202CE79498E29FE8E5CB02B7C0A4", + "quotas": + [ + {"name":"STARS-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"STARS-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/0CD3A0285E1341859B5E86B6AB7682F023D03E97607CCC1DC95706411D866DF7", + "quotas": + [ + {"name":"DAI-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"DAI-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED", + "quotas": + [ + {"name":"JUNO-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"JUNO-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + `{"add_path": {"channel_id": "any", "denom": "ibc/E6931F78057F7CC5DA0FD6CEF82FF39373A6E0452BF1FD76910B93292CF356C1", + "quotas": + [ + {"name":"CRO-DAY","duration":86400,"send_recv":[30,30]}, + {"name":"CRO-WEEK","duration":604800,"send_recv":[60,60]} + ] + }}`, + } + + contract := rateLimitingICS4Wrapper.GetContractAddress(ctx) + if contract == "" { + panic("rate limiting contract not set") + } + rateLimitingContract, err := sdk.AccAddressFromBech32(contract) + if err != nil { + panic("contract address improperly formatted") + } + for _, denom := range paths { + _, err := contractKeeper.Execute(ctx, rateLimitingContract, govModule, []byte(denom), nil) + if err != nil { + panic(err) + } + } +} + +func migrateNextPoolId(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper) { + // N.B: pool id in gamm is to be deprecated in the future + // Instead,it is moved to poolmanager. + // nolint: staticcheck + nextPoolId := gammKeeper.GetNextPoolId(ctx) + poolmanagerKeeper.SetNextPoolId(ctx, nextPoolId) + + for poolId := uint64(1); poolId < nextPoolId; poolId++ { + poolType, err := gammKeeper.GetPoolType(ctx, poolId) + if err != nil { + panic(err) + } + + poolmanagerKeeper.SetPoolRoute(ctx, poolId, poolType) + } +} + +func registerOsmoIonMetadata(ctx sdk.Context, bankKeeper bankkeeper.Keeper) { + uosmoMetadata := banktypes.Metadata{ + Description: "The native token of Osmosis", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: appParams.BaseCoinUnit, + Exponent: 0, + Aliases: nil, + }, + { + Denom: appParams.HumanCoinUnit, + Exponent: appParams.OsmoExponent, + Aliases: nil, + }, + }, + Base: appParams.BaseCoinUnit, + Display: appParams.HumanCoinUnit, + } + + uionMetadata := banktypes.Metadata{ + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "uion", + Exponent: 0, + Aliases: nil, + }, + { + Denom: "ion", + Exponent: 6, + Aliases: nil, + }, + }, + Base: "uion", + Display: "ion", + } + + bankKeeper.SetDenomMetaData(ctx, uosmoMetadata) + bankKeeper.SetDenomMetaData(ctx, uionMetadata) +} diff --git a/proto/osmosis/ibc-rate-limit/v1beta1/genesis.proto b/proto/osmosis/ibc-rate-limit/v1beta1/genesis.proto new file mode 100644 index 00000000000..60eb5d313fa --- /dev/null +++ b/proto/osmosis/ibc-rate-limit/v1beta1/genesis.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package osmosis.ibcratelimit.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/any.proto"; +import "osmosis/ibc-rate-limit/v1beta1/params.proto"; + +option go_package = "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types"; + +// GenesisState defines the ibc-rate-limit module's genesis state. +message GenesisState { + // params are all the parameters of the module + Params params = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/osmosis/ibc-rate-limit/v1beta1/query.proto b/proto/osmosis/ibc-rate-limit/v1beta1/query.proto index aff5e973c82..6efe48d63f6 100644 --- a/proto/osmosis/ibc-rate-limit/v1beta1/query.proto +++ b/proto/osmosis/ibc-rate-limit/v1beta1/query.proto @@ -6,22 +6,22 @@ import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "osmosis/ibc-rate-limit/v1beta1/params.proto"; -option go_package = "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types"; +option go_package = "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/queryproto"; // Query defines the gRPC querier service. service Query { // Params defines a gRPC query method that returns the ibc-rate-limit module's // parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + rpc Params(ParamsRequest) returns (ParamsResponse) { option (google.api.http).get = "/osmosis/ibc-rate-limit/v1beta1/params"; } } -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} +// ParamsRequest is the request type for the Query/Params RPC method. +message ParamsRequest {} -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { +// aramsResponse is the response type for the Query/Params RPC method. +message ParamsResponse { // params defines the parameters of the module. Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/proto/osmosis/ibc-rate-limit/v1beta1/query.yml b/proto/osmosis/ibc-rate-limit/v1beta1/query.yml new file mode 100644 index 00000000000..edff767cfe5 --- /dev/null +++ b/proto/osmosis/ibc-rate-limit/v1beta1/query.yml @@ -0,0 +1,10 @@ +keeper: + path: "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit" + struct: "Keeper" +client_path: "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client" +queries: + Params: + proto_wrapper: + query_func: "k.GetParams" + cli: + cmd: "GetParams" \ No newline at end of file diff --git a/tests/e2e/configurer/chain/chain.go b/tests/e2e/configurer/chain/chain.go index 3352476dd39..4d2544018df 100644 --- a/tests/e2e/configurer/chain/chain.go +++ b/tests/e2e/configurer/chain/chain.go @@ -1,11 +1,20 @@ package chain import ( + "encoding/json" "fmt" + "os" + "path/filepath" + "strconv" + "strings" "testing" "time" + paramsutils "github.com/cosmos/cosmos-sdk/x/params/client/utils" + ibcratelimittypes "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v14/tests/e2e/util" "github.com/stretchr/testify/require" coretypes "github.com/tendermint/tendermint/rpc/core/types" @@ -43,6 +52,8 @@ const ( waitUntilRepeatPauseTime = 2 * time.Second // waitUntilrepeatMax is the maximum number of times to repeat the wait until condition. waitUntilrepeatMax = 60 + + proposalStatusPassed = "PROPOSAL_STATUS_PASSED" ) func New(t *testing.T, containerManager *containers.Manager, id string, initValidatorConfigs []*initialization.NodeConfig) *Config { @@ -220,3 +231,92 @@ func (c *Config) getNodeAtIndex(nodeIndex int) (*NodeConfig, error) { } return c.NodeConfigs[nodeIndex], nil } + +func (c *Config) SubmitParamChangeProposal(subspace, key string, value []byte) error { + node, err := c.GetDefaultNode() + if err != nil { + return err + } + + proposal := paramsutils.ParamChangeProposalJSON{ + Title: "Param Change", + Description: fmt.Sprintf("Changing the %s param", key), + Changes: paramsutils.ParamChangesJSON{ + paramsutils.ParamChangeJSON{ + Subspace: subspace, + Key: key, + Value: value, + }, + }, + Deposit: "625000000uosmo", + } + proposalJson, err := json.Marshal(proposal) + if err != nil { + return err + } + + node.SubmitParamChangeProposal(string(proposalJson), initialization.ValidatorWalletName) + c.LatestProposalNumber += 1 + + for _, n := range c.NodeConfigs { + n.VoteYesProposal(initialization.ValidatorWalletName, c.LatestProposalNumber) + } + + require.Eventually(c.t, func() bool { + status, err := node.QueryPropStatus(c.LatestProposalNumber) + if err != nil { + return false + } + return status == proposalStatusPassed + }, time.Second*30, time.Millisecond*500) + return nil +} + +func (c *Config) SetupRateLimiting(paths, gov_addr string) (string, error) { + node, err := c.GetDefaultNode() + if err != nil { + return "", err + } + + // copy the contract from x/rate-limit/testdata/ + wd, err := os.Getwd() + if err != nil { + return "", err + } + // go up two levels + projectDir := filepath.Dir(filepath.Dir(wd)) + fmt.Println(wd, projectDir) + _, err = util.CopyFile(projectDir+"/x/ibc-rate-limit/bytecode/rate_limiter.wasm", wd+"/scripts/rate_limiter.wasm") + if err != nil { + return "", err + } + + node.StoreWasmCode("rate_limiter.wasm", initialization.ValidatorWalletName) + c.LatestCodeId = int(node.QueryLatestWasmCodeID()) + node.InstantiateWasmContract( + strconv.Itoa(c.LatestCodeId), + fmt.Sprintf(`{"gov_module": "%s", "ibc_module": "%s", "paths": [%s] }`, gov_addr, node.PublicAddress, paths), + initialization.ValidatorWalletName) + + contracts, err := node.QueryContractsFromId(c.LatestCodeId) + if err != nil { + return "", err + } + + contract := contracts[len(contracts)-1] + + err = c.SubmitParamChangeProposal( + ibcratelimittypes.ModuleName, + string(ibcratelimittypes.KeyContractAddress), + []byte(fmt.Sprintf(`"%s"`, contract)), + ) + if err != nil { + return "", err + } + require.Eventually(c.t, func() bool { + val := node.QueryParams(ibcratelimittypes.ModuleName, string(ibcratelimittypes.KeyContractAddress)) + return strings.Contains(val, contract) + }, time.Second*30, time.Millisecond*500) + fmt.Println("contract address set to", contract) + return contract, nil +} diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go index bb96100fffa..6f80182e068 100644 --- a/tests/e2e/configurer/chain/commands.go +++ b/tests/e2e/configurer/chain/commands.go @@ -26,8 +26,20 @@ import ( coretypes "github.com/tendermint/tendermint/rpc/core/types" ) +<<<<<<< HEAD func (n *NodeConfig) CreatePool(poolFile, from string) uint64 { n.LogActionF("creating pool from file %s", poolFile) +======= +// The value is returned as a string, so we have to unmarshal twice +type params struct { + Key string `json:"key"` + Subspace string `json:"subspace"` + Value string `json:"value"` +} + +func (n *NodeConfig) CreateBalancerPool(poolFile, from string) uint64 { + n.LogActionF("creating balancer pool from file %s", poolFile) +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) cmd := []string{"osmosisd", "tx", "gamm", "create-pool", fmt.Sprintf("--pool-file=/osmosis/%s", poolFile), fmt.Sprintf("--from=%s", from)} _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) @@ -55,7 +67,7 @@ func (n *NodeConfig) StoreWasmCode(wasmFile, from string) { func (n *NodeConfig) InstantiateWasmContract(codeId, initMsg, from string) { n.LogActionF("instantiating wasm contract %s with %s", codeId, initMsg) - cmd := []string{"osmosisd", "tx", "wasm", "instantiate", codeId, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=ratelimit"} + cmd := []string{"osmosisd", "tx", "wasm", "instantiate", codeId, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=contract"} n.LogActionF(strings.Join(cmd, " ")) _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) @@ -73,14 +85,37 @@ func (n *NodeConfig) WasmExecute(contract, execMsg, from string) { // QueryParams extracts the params for a given subspace and key. This is done generically via json to avoid having to // specify the QueryParamResponse type (which may not exist for all params). -func (n *NodeConfig) QueryParams(subspace, key string, result any) { +func (n *NodeConfig) QueryParams(subspace, key string) string { cmd := []string{"osmosisd", "query", "params", "subspace", subspace, key, "--output=json"} out, _, err := n.containerManager.ExecCmd(n.t, n.Name, cmd, "") require.NoError(n.t, err) + result := ¶ms{} err = json.Unmarshal(out.Bytes(), &result) require.NoError(n.t, err) + return result.Value +} + +func (n *NodeConfig) QueryGovModuleAccount() string { + cmd := []string{"osmosisd", "query", "auth", "module-accounts", "--output=json"} + + out, _, err := n.containerManager.ExecCmd(n.t, n.Name, cmd, "") + require.NoError(n.t, err) + var result map[string][]interface{} + err = json.Unmarshal(out.Bytes(), &result) + require.NoError(n.t, err) + for _, acc := range result["accounts"] { + account, ok := acc.(map[string]interface{}) + require.True(n.t, ok) + if account["name"] == "gov" { + moduleAccount, ok := account["base_account"].(map[string]interface{})["address"].(string) + require.True(n.t, ok) + return moduleAccount + } + } + require.True(n.t, false, "gov module account not found") + return "" } func (n *NodeConfig) SubmitParamChangeProposal(proposalJson, from string) { diff --git a/tests/e2e/configurer/chain/queries.go b/tests/e2e/configurer/chain/queries.go index b00ecba9c43..76a05e234b3 100644 --- a/tests/e2e/configurer/chain/queries.go +++ b/tests/e2e/configurer/chain/queries.go @@ -126,28 +126,43 @@ func (n *NodeConfig) QueryLatestWasmCodeID() uint64 { return response.CodeInfos[len(response.CodeInfos)-1].CodeID } -func (n *NodeConfig) QueryWasmSmart(contract string, msg string) (map[string]interface{}, error) { +func (n *NodeConfig) QueryWasmSmart(contract string, msg string, result any) error { // base64-encode the msg encodedMsg := base64.StdEncoding.EncodeToString([]byte(msg)) path := fmt.Sprintf("/cosmwasm/wasm/v1/contract/%s/smart/%s", contract, encodedMsg) bz, err := n.QueryGRPCGateway(path) if err != nil { - return nil, err + return err } var response wasmtypes.QuerySmartContractStateResponse err = util.Cdc.UnmarshalJSON(bz, &response) + if err != nil { + return err + } + + err = json.Unmarshal(response.Data, &result) + if err != nil { + return err + } + return nil +} + +func (n *NodeConfig) QueryWasmSmartObject(contract string, msg string) (resultObject map[string]interface{}, err error) { + err = n.QueryWasmSmart(contract, msg, &resultObject) if err != nil { return nil, err } + return resultObject, nil +} - var responseJSON map[string]interface{} - err = json.Unmarshal(response.Data, &responseJSON) +func (n *NodeConfig) QueryWasmSmartArray(contract string, msg string) (resultArray []interface{}, err error) { + err = n.QueryWasmSmart(contract, msg, &resultArray) if err != nil { return nil, err } - return responseJSON, nil + return resultArray, nil } func (n *NodeConfig) QueryPropTally(proposalNumber int) (sdk.Int, sdk.Int, sdk.Int, sdk.Int, error) { diff --git a/tests/e2e/configurer/upgrade.go b/tests/e2e/configurer/upgrade.go index 4f727b401ae..ff736055d2c 100644 --- a/tests/e2e/configurer/upgrade.go +++ b/tests/e2e/configurer/upgrade.go @@ -136,6 +136,17 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { chainANode.BankSend("10000000000000000000gamm/pool/1", chainA.NodeConfigs[0].PublicAddress, lockupWalletAddrA) chainANode.BankSend("10000000000000000000gamm/pool/1", chainA.NodeConfigs[0].PublicAddress, lockupWalletSuperfluidAddrA) + // Upload the rate limiting contract to both chains (as they both will be updated) + uc.t.Logf("Uploading rate limiting contract to both chains") + _, err = chainA.SetupRateLimiting("", chainANode.QueryGovModuleAccount()) + if err != nil { + return err + } + _, _ = chainB.SetupRateLimiting("", chainBNode.QueryGovModuleAccount()) + if err != nil { + return err + } + // test lock and add to existing lock for both regular and superfluid lockups (only chainA) chainA.LockAndAddToExistingLock(sdk.NewInt(1000000000000000000), "gamm/pool/1", lockupWalletAddrA, lockupWalletSuperfluidAddrA) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index d0a14e5c473..04a7f17fb7e 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -3,17 +3,31 @@ package e2e import ( "encoding/json" "fmt" - "io" "os" "path/filepath" "strconv" "strings" "time" +<<<<<<< HEAD ibchookskeeper "github.com/osmosis-labs/osmosis/x/ibc-hooks/keeper" paramsutils "github.com/cosmos/cosmos-sdk/x/params/client/utils" +======= + transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + + "github.com/iancoleman/orderedmap" + + "github.com/osmosis-labs/osmosis/v14/tests/e2e/configurer/chain" + "github.com/osmosis-labs/osmosis/v14/tests/e2e/util" + + packetforwardingtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + + ibchookskeeper "github.com/osmosis-labs/osmosis/x/ibc-hooks/keeper" + + "github.com/osmosis-labs/osmosis/v14/x/concentrated-liquidity/types" +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) ibcratelimittypes "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -152,23 +166,30 @@ func (s *IntegrationTestSuite) TestSuperfluidVoting() { ) } -// Copy a file from A to B with io.Copy -func copyFile(a, b string) error { - source, err := os.Open(a) - if err != nil { - return err - } - defer source.Close() - destination, err := os.Create(b) - if err != nil { - return err - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - return err +func (s *IntegrationTestSuite) TestRateLimitingParam() { + if s.skipUpgrade { + s.T().Skip("Skipping IBC tests") } - return nil + + // After v15, rate limiting gets set on genesis. + chainA := s.configurer.GetChainConfig(0) + chainB := s.configurer.GetChainConfig(1) + + nodeA, err := chainA.GetDefaultNode() + s.Require().NoError(err) + nodeB, err := chainB.GetDefaultNode() + s.Require().NoError(err) + + // Need to json unparshal the params because they are stored including quotes + paramA := nodeA.QueryParams(ibcratelimittypes.ModuleName, string(ibcratelimittypes.KeyContractAddress)) + json.Unmarshal([]byte(paramA), ¶mA) + paramB := nodeB.QueryParams(ibcratelimittypes.ModuleName, string(ibcratelimittypes.KeyContractAddress)) + json.Unmarshal([]byte(paramB), ¶mB) + + // When upgrading to v15, we want to make sure that the rate limits have been set. + quotas, err := nodeA.QueryWasmSmartArray(paramA, `{"get_quotas": {"channel_id": "any", "denom": "ibc/E6931F78057F7CC5DA0FD6CEF82FF39373A6E0452BF1FD76910B93292CF356C1"}}`) + s.Require().Len(quotas, 2) + s.Require().NoError(err) } func (s *IntegrationTestSuite) TestIBCTokenTransferRateLimiting() { @@ -179,78 +200,32 @@ func (s *IntegrationTestSuite) TestIBCTokenTransferRateLimiting() { chainB := s.configurer.GetChainConfig(1) node, err := chainA.GetDefaultNode() - s.NoError(err) + s.Require().NoError(err) + + // If the RL param is already set. Remember it to set it back at the end + param := node.QueryParams(ibcratelimittypes.ModuleName, string(ibcratelimittypes.KeyContractAddress)) + fmt.Println("param", param) osmoSupply, err := node.QuerySupplyOf("uosmo") - s.NoError(err) + s.Require().NoError(err) f, err := osmoSupply.ToDec().Float64() - s.NoError(err) + s.Require().NoError(err) over := f * 0.02 + paths := fmt.Sprintf(`{"channel_id": "channel-0", "denom": "%s", "quotas": [{"name":"testQuota", "duration": 86400, "send_recv": [1, 1]}] }`, initialization.OsmoToken.Denom) + // Sending >1% chainA.SendIBC(chainB, chainB.NodeConfigs[0].PublicAddress, sdk.NewInt64Coin(initialization.OsmoDenom, int64(over))) - // copy the contract from x/rate-limit/testdata/ - wd, err := os.Getwd() - s.NoError(err) - // co up two levels - projectDir := filepath.Dir(filepath.Dir(wd)) - fmt.Println(wd, projectDir) - err = copyFile(projectDir+"/x/ibc-rate-limit/bytecode/rate_limiter.wasm", wd+"/scripts/rate_limiter.wasm") - s.NoError(err) - - node.StoreWasmCode("rate_limiter.wasm", initialization.ValidatorWalletName) - chainA.LatestCodeId = int(node.QueryLatestWasmCodeID()) - node.InstantiateWasmContract( - strconv.Itoa(chainA.LatestCodeId), - fmt.Sprintf(`{"gov_module": "%s", "ibc_module": "%s", "paths": [{"channel_id": "channel-0", "denom": "%s", "quotas": [{"name":"testQuota", "duration": 86400, "send_recv": [1, 1]}] } ] }`, node.PublicAddress, node.PublicAddress, initialization.OsmoToken.Denom), - initialization.ValidatorWalletName) - - contracts, err := node.QueryContractsFromId(chainA.LatestCodeId) - s.NoError(err) - s.Require().Len(contracts, 1, "Wrong number of contracts for the rate limiter") - - proposal := paramsutils.ParamChangeProposalJSON{ - Title: "Param Change", - Description: "Changing the rate limit contract param", - Changes: paramsutils.ParamChangesJSON{ - paramsutils.ParamChangeJSON{ - Subspace: ibcratelimittypes.ModuleName, - Key: "contract", - Value: []byte(fmt.Sprintf(`"%s"`, contracts[0])), - }, - }, - Deposit: "625000000uosmo", - } - proposalJson, err := json.Marshal(proposal) - s.NoError(err) - - node.SubmitParamChangeProposal(string(proposalJson), initialization.ValidatorWalletName) - chainA.LatestProposalNumber += 1 - - for _, n := range chainA.NodeConfigs { - n.VoteYesProposal(initialization.ValidatorWalletName, chainA.LatestProposalNumber) - } - - // The value is returned as a string, so we have to unmarshal twice - type Params struct { - Key string `json:"key"` - Subspace string `json:"subspace"` - Value string `json:"value"` - } + contract, err := chainA.SetupRateLimiting(paths, chainA.NodeConfigs[0].PublicAddress) + s.Require().NoError(err) s.Eventually( func() bool { - var params Params - node.QueryParams(ibcratelimittypes.ModuleName, "contract", ¶ms) - var val string - err := json.Unmarshal([]byte(params.Value), &val) - if err != nil { - return false - } - return val == contracts[0] + val := node.QueryParams(ibcratelimittypes.ModuleName, string(ibcratelimittypes.KeyContractAddress)) + return strings.Contains(val, contract) }, 1*time.Minute, 10*time.Millisecond, @@ -263,9 +238,59 @@ func (s *IntegrationTestSuite) TestIBCTokenTransferRateLimiting() { node.FailIBCTransfer(initialization.ValidatorWalletName, chainB.NodeConfigs[0].PublicAddress, fmt.Sprintf("%duosmo", int(over))) // Removing the rate limit so it doesn't affect other tests - node.WasmExecute(contracts[0], `{"remove_path": {"channel_id": "channel-0", "denom": "uosmo"}}`, initialization.ValidatorWalletName) + node.WasmExecute(contract, `{"remove_path": {"channel_id": "channel-0", "denom": "uosmo"}}`, initialization.ValidatorWalletName) + //reset the param to the original contract if it existed + if param != "" { + err = chainA.SubmitParamChangeProposal( + ibcratelimittypes.ModuleName, + string(ibcratelimittypes.KeyContractAddress), + []byte(param), + ) + s.Require().NoError(err) + s.Eventually(func() bool { + val := node.QueryParams(ibcratelimittypes.ModuleName, string(ibcratelimittypes.KeyContractAddress)) + return strings.Contains(val, param) + }, time.Second*30, time.Millisecond*500) + + } + +} + +<<<<<<< HEAD +======= +func (s *IntegrationTestSuite) TestLargeWasmUpload() { + chainA := s.configurer.GetChainConfig(0) + node, err := chainA.GetDefaultNode() + s.NoError(err) + node.StoreWasmCode("bytecode/large.wasm", initialization.ValidatorWalletName) } +func (s *IntegrationTestSuite) UploadAndInstantiateCounter(chain *chain.Config) string { + // copy the contract from tests/ibc-hooks/bytecode + wd, err := os.Getwd() + s.NoError(err) + // co up two levels + projectDir := filepath.Dir(filepath.Dir(wd)) + _, err = util.CopyFile(projectDir+"/tests/ibc-hooks/bytecode/counter.wasm", wd+"/scripts/counter.wasm") + s.NoError(err) + node, err := chain.GetDefaultNode() + s.NoError(err) + + node.StoreWasmCode("counter.wasm", initialization.ValidatorWalletName) + chain.LatestCodeId = int(node.QueryLatestWasmCodeID()) + node.InstantiateWasmContract( + strconv.Itoa(chain.LatestCodeId), + `{"count": 0}`, + initialization.ValidatorWalletName) + + contracts, err := node.QueryContractsFromId(chain.LatestCodeId) + s.NoError(err) + s.Require().Len(contracts, 1, "Wrong number of contracts for the counter") + contractAddr := contracts[0] + return contractAddr +} + +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) func (s *IntegrationTestSuite) TestIBCWasmHooks() { if s.skipIBC { s.T().Skip("Skipping IBC tests") @@ -320,8 +345,13 @@ func (s *IntegrationTestSuite) TestIBCWasmHooks() { senderBech32, err := ibchookskeeper.DeriveIntermediateSender("channel-0", validatorAddr, "osmo") var response map[string]interface{} +<<<<<<< HEAD s.Eventually(func() bool { response, err = nodeA.QueryWasmSmart(contractAddr, fmt.Sprintf(`{"get_total_funds": {"addr": "%s"}}`, senderBech32)) +======= + s.Require().Eventually(func() bool { + response, err = nodeA.QueryWasmSmartObject(contractAddr, fmt.Sprintf(`{"get_total_funds": {"addr": "%s"}}`, senderBech32)) +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) totalFunds := response["total_funds"].([]interface{})[0] amount := totalFunds.(map[string]interface{})["amount"].(string) denom := totalFunds.(map[string]interface{})["denom"].(string) @@ -333,6 +363,58 @@ func (s *IntegrationTestSuite) TestIBCWasmHooks() { ) } +<<<<<<< HEAD +======= +// TestPacketForwarding sends a packet from chainA to chainB, and forwards it +// back to chainA with a custom memo to execute the counter contract on chain A +func (s *IntegrationTestSuite) TestPacketForwarding() { + if s.skipIBC { + s.T().Skip("Skipping IBC tests") + } + chainA := s.configurer.GetChainConfig(0) + + nodeA, err := chainA.GetDefaultNode() + s.NoError(err) + + // Instantiate the counter contract on chain A + contractAddr := s.UploadAndInstantiateCounter(chainA) + + transferAmount := int64(10) + validatorAddr := nodeA.GetWallet(initialization.ValidatorWalletName) + // Specify that the counter contract should be called on chain A when the packet is received + contractCallMemo := []byte(fmt.Sprintf(`{"wasm":{"contract":"%s","msg": {"increment": {}} }}`, contractAddr)) + // Generate the forward metadata + forwardMetadata := packetforwardingtypes.ForwardMetadata{ + Receiver: contractAddr, + Port: "transfer", + Channel: "channel-0", + Next: packetforwardingtypes.NewJSONObject(false, contractCallMemo, orderedmap.OrderedMap{}), // The packet sent to chainA will have this memo + } + memoData := packetforwardingtypes.PacketMetadata{Forward: &forwardMetadata} + forwardMemo, err := json.Marshal(memoData) + s.NoError(err) + // Send the transfer from chainA to chainB. ChainB will parse the memo and forward the packet back to chainA + nodeA.SendIBCTransfer(validatorAddr, validatorAddr, fmt.Sprintf("%duosmo", transferAmount), string(forwardMemo)) + + // check the balance of the contract + s.CheckBalance(nodeA, contractAddr, "uosmo", transferAmount) + + // sender wasm addr + senderBech32, err := ibchookskeeper.DeriveIntermediateSender("channel-0", validatorAddr, "osmo") + s.Require().Eventually(func() bool { + response, err := nodeA.QueryWasmSmartObject(contractAddr, fmt.Sprintf(`{"get_count": {"addr": "%s"}}`, senderBech32)) + if err != nil { + return false + } + count := response["count"].(float64) + return err == nil && count == 0 + }, + 15*time.Second, + 10*time.Millisecond, + ) +} + +>>>>>>> a1e2b3d4 (Added rate limits in upgrade (#4340)) // TestAddToExistingLockPostUpgrade ensures addToExistingLock works for locks created preupgrade. func (s *IntegrationTestSuite) TestAddToExistingLockPostUpgrade() { if s.skipUpgrade { diff --git a/x/ibc-rate-limit/client/cli/query.go b/x/ibc-rate-limit/client/cli/query.go index e1f1a8910b3..e594d6dd938 100644 --- a/x/ibc-rate-limit/client/cli/query.go +++ b/x/ibc-rate-limit/client/cli/query.go @@ -4,6 +4,7 @@ import ( "github.com/spf13/cobra" "github.com/osmosis-labs/osmosis/osmoutils/osmocli" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/queryproto" "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" ) @@ -12,8 +13,8 @@ func GetQueryCmd() *cobra.Command { cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( - osmocli.GetParams[*types.QueryParamsRequest]( - types.ModuleName, types.NewQueryClient), + osmocli.GetParams[*queryproto.ParamsRequest]( + types.ModuleName, queryproto.NewQueryClient), ) return cmd diff --git a/x/ibc-rate-limit/client/grpc/grpc_query.go b/x/ibc-rate-limit/client/grpc/grpc_query.go new file mode 100644 index 00000000000..5c666ddf6e3 --- /dev/null +++ b/x/ibc-rate-limit/client/grpc/grpc_query.go @@ -0,0 +1,32 @@ +package grpc + +// THIS FILE IS GENERATED CODE, DO NOT EDIT +// SOURCE AT `proto/osmosis/ibc-rate-limit/v1beta1/query.yml` + +import ( + context "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/queryproto" +) + +type Querier struct { + Q client.Querier +} + +var _ queryproto.QueryServer = Querier{} + +func (q Querier) Params(grpcCtx context.Context, + req *queryproto.ParamsRequest, +) (*queryproto.ParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + ctx := sdk.UnwrapSDKContext(grpcCtx) + return q.Q.Params(ctx, *req) +} + diff --git a/x/ibc-rate-limit/client/query_proto_wrap.go b/x/ibc-rate-limit/client/query_proto_wrap.go new file mode 100644 index 00000000000..53f53e0ed78 --- /dev/null +++ b/x/ibc-rate-limit/client/query_proto_wrap.go @@ -0,0 +1,21 @@ +package client + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + ibcratelimit "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/queryproto" +) + +// This file should evolve to being code gen'd, off of `proto/twap/v1beta/query.yml` + +type Querier struct { + K ibcratelimit.ICS4Wrapper +} + +func (q Querier) Params(ctx sdk.Context, + req queryproto.ParamsRequest, +) (*queryproto.ParamsResponse, error) { + params := q.K.GetParams(ctx) + return &queryproto.ParamsResponse{Params: params}, nil +} diff --git a/x/ibc-rate-limit/types/query.pb.go b/x/ibc-rate-limit/client/queryproto/query.pb.go similarity index 62% rename from x/ibc-rate-limit/types/query.pb.go rename to x/ibc-rate-limit/client/queryproto/query.pb.go index c03303843c9..2047d8247fd 100644 --- a/x/ibc-rate-limit/types/query.pb.go +++ b/x/ibc-rate-limit/client/queryproto/query.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: osmosis/ibc-rate-limit/v1beta1/query.proto -package types +package queryproto import ( context "context" @@ -10,6 +10,7 @@ import ( _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" + types "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -30,22 +31,22 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// QueryParamsRequest is the request type for the Query/Params RPC method. -type QueryParamsRequest struct { +// ParamsRequest is the request type for the Query/Params RPC method. +type ParamsRequest struct { } -func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } -func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryParamsRequest) ProtoMessage() {} -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { +func (m *ParamsRequest) Reset() { *m = ParamsRequest{} } +func (m *ParamsRequest) String() string { return proto.CompactTextString(m) } +func (*ParamsRequest) ProtoMessage() {} +func (*ParamsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_9376d12c6390a846, []int{0} } -func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { +func (m *ParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_ParamsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -55,36 +56,36 @@ func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsRequest.Merge(m, src) +func (m *ParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParamsRequest.Merge(m, src) } -func (m *QueryParamsRequest) XXX_Size() int { +func (m *ParamsRequest) XXX_Size() int { return m.Size() } -func (m *QueryParamsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +func (m *ParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ParamsRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo +var xxx_messageInfo_ParamsRequest proto.InternalMessageInfo -// QueryParamsResponse is the response type for the Query/Params RPC method. -type QueryParamsResponse struct { +// aramsResponse is the response type for the Query/Params RPC method. +type ParamsResponse struct { // params defines the parameters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Params types.Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` } -func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } -func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryParamsResponse) ProtoMessage() {} -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { +func (m *ParamsResponse) Reset() { *m = ParamsResponse{} } +func (m *ParamsResponse) String() string { return proto.CompactTextString(m) } +func (*ParamsResponse) ProtoMessage() {} +func (*ParamsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_9376d12c6390a846, []int{1} } -func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { +func (m *ParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_ParamsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -94,28 +95,28 @@ func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsResponse.Merge(m, src) +func (m *ParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParamsResponse.Merge(m, src) } -func (m *QueryParamsResponse) XXX_Size() int { +func (m *ParamsResponse) XXX_Size() int { return m.Size() } -func (m *QueryParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +func (m *ParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ParamsResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo +var xxx_messageInfo_ParamsResponse proto.InternalMessageInfo -func (m *QueryParamsResponse) GetParams() Params { +func (m *ParamsResponse) GetParams() types.Params { if m != nil { return m.Params } - return Params{} + return types.Params{} } func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "osmosis.ibcratelimit.v1beta1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "osmosis.ibcratelimit.v1beta1.QueryParamsResponse") + proto.RegisterType((*ParamsRequest)(nil), "osmosis.ibcratelimit.v1beta1.ParamsRequest") + proto.RegisterType((*ParamsResponse)(nil), "osmosis.ibcratelimit.v1beta1.ParamsResponse") } func init() { @@ -123,27 +124,28 @@ func init() { } var fileDescriptor_9376d12c6390a846 = []byte{ - // 317 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x90, 0xb1, 0x4a, 0x03, 0x31, - 0x18, 0xc7, 0x2f, 0xa2, 0x1d, 0xce, 0xed, 0xec, 0x20, 0xa5, 0x44, 0x29, 0x22, 0xa5, 0xd2, 0xc4, - 0xab, 0x4e, 0x8e, 0x7d, 0x02, 0x2d, 0x2e, 0xba, 0x25, 0x47, 0x88, 0x81, 0xde, 0x7d, 0xe9, 0x25, - 0x2d, 0x76, 0xf5, 0x09, 0x04, 0x67, 0x67, 0x5f, 0xa5, 0x63, 0xc1, 0xc5, 0x49, 0xa4, 0xf5, 0x41, - 0xe4, 0x92, 0x58, 0x50, 0xa1, 0xea, 0x76, 0x7c, 0xf7, 0xfb, 0xff, 0xbe, 0x7f, 0xbe, 0xb8, 0x03, - 0x26, 0x07, 0xa3, 0x0c, 0x55, 0x3c, 0xeb, 0x96, 0xcc, 0x8a, 0xee, 0x50, 0xe5, 0xca, 0xd2, 0x49, - 0xca, 0x85, 0x65, 0x29, 0x1d, 0x8d, 0x45, 0x39, 0x25, 0xba, 0x04, 0x0b, 0x49, 0x33, 0xb0, 0x44, - 0xf1, 0xac, 0x42, 0x1d, 0x49, 0x02, 0xd9, 0xa8, 0x4b, 0x90, 0xe0, 0x40, 0x5a, 0x7d, 0xf9, 0x4c, - 0xa3, 0x29, 0x01, 0xe4, 0x50, 0x50, 0xa6, 0x15, 0x65, 0x45, 0x01, 0x96, 0x59, 0x05, 0x85, 0x09, - 0x7f, 0x3b, 0x99, 0x53, 0x52, 0xce, 0x8c, 0xf0, 0xab, 0x56, 0x8b, 0x35, 0x93, 0xaa, 0x70, 0x70, - 0x60, 0x8f, 0x7e, 0x69, 0xaa, 0x59, 0xc9, 0xf2, 0x20, 0x6e, 0xd5, 0xe3, 0xe4, 0xa2, 0xd2, 0x9d, - 0xbb, 0xe1, 0x40, 0x8c, 0xc6, 0xc2, 0xd8, 0xd6, 0x55, 0xbc, 0xf3, 0x65, 0x6a, 0x34, 0x14, 0x46, - 0x24, 0xfd, 0xb8, 0xe6, 0xc3, 0xbb, 0x68, 0x1f, 0xb5, 0xb7, 0x7b, 0x07, 0x64, 0xdd, 0x43, 0x89, - 0x4f, 0xf7, 0x37, 0x67, 0xaf, 0x7b, 0xd1, 0x20, 0x24, 0x7b, 0x4f, 0x28, 0xde, 0x72, 0xee, 0xe4, - 0x11, 0xc5, 0x35, 0x8f, 0x24, 0xc7, 0xeb, 0x45, 0x3f, 0x1b, 0x36, 0xd2, 0x7f, 0x24, 0x7c, 0xfb, - 0x16, 0xb9, 0x7b, 0x7e, 0x7f, 0xd8, 0x68, 0x27, 0x87, 0xf4, 0x4f, 0x07, 0xea, 0x5f, 0xce, 0x16, - 0x18, 0xcd, 0x17, 0x18, 0xbd, 0x2d, 0x30, 0xba, 0x5f, 0xe2, 0x68, 0xbe, 0xc4, 0xd1, 0xcb, 0x12, - 0x47, 0xd7, 0x67, 0x52, 0xd9, 0x9b, 0x31, 0x27, 0x19, 0xe4, 0x9f, 0xae, 0xee, 0x90, 0x71, 0xb3, - 0x12, 0x4f, 0xd2, 0x53, 0x7a, 0xfb, 0x5d, 0x6f, 0xa7, 0x5a, 0x18, 0x5e, 0x73, 0x77, 0x3f, 0xf9, - 0x08, 0x00, 0x00, 0xff, 0xff, 0x13, 0x76, 0x8a, 0x7f, 0x50, 0x02, 0x00, 0x00, + // 321 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xbf, 0x4a, 0x73, 0x31, + 0x18, 0xc6, 0x4f, 0x3e, 0x3e, 0x3b, 0x44, 0x54, 0x38, 0x38, 0x48, 0x29, 0x51, 0x8a, 0x48, 0x69, + 0x6d, 0x42, 0xab, 0x57, 0xd0, 0xc1, 0x59, 0x8b, 0x93, 0x93, 0xc9, 0x21, 0xc4, 0xc0, 0x39, 0x79, + 0x4f, 0x4f, 0xd2, 0xa2, 0xab, 0x57, 0x20, 0x74, 0xf6, 0x7e, 0x3a, 0x16, 0x5c, 0x9c, 0x44, 0x5a, + 0x2f, 0x44, 0x9a, 0xa4, 0x1d, 0x1c, 0xb4, 0x53, 0xfe, 0xfd, 0x9e, 0xe7, 0x7d, 0xf2, 0xbe, 0xb8, + 0x0d, 0xb6, 0x00, 0xab, 0x2d, 0xd3, 0x22, 0xeb, 0x56, 0xdc, 0xc9, 0x6e, 0xae, 0x0b, 0xed, 0xd8, + 0xa4, 0x27, 0xa4, 0xe3, 0x3d, 0x36, 0x1a, 0xcb, 0xea, 0x89, 0x96, 0x15, 0x38, 0x48, 0x1b, 0x91, + 0xa5, 0x5a, 0x64, 0x2b, 0xd4, 0x93, 0x34, 0x92, 0xf5, 0x43, 0x05, 0x0a, 0x3c, 0xc8, 0x56, 0xbb, + 0xa0, 0xa9, 0x37, 0x14, 0x80, 0xca, 0x25, 0xe3, 0xa5, 0x66, 0xdc, 0x18, 0x70, 0xdc, 0x69, 0x30, + 0x36, 0xbe, 0xb6, 0x33, 0x6f, 0xc9, 0x04, 0xb7, 0x32, 0x94, 0xda, 0x14, 0x2e, 0xb9, 0xd2, 0xc6, + 0xc3, 0x91, 0xed, 0xfc, 0x91, 0xb4, 0xe4, 0x15, 0x2f, 0xa2, 0x71, 0xf3, 0x00, 0xef, 0x5d, 0xfb, + 0xf3, 0x50, 0x8e, 0xc6, 0xd2, 0xba, 0xe6, 0x2d, 0xde, 0x5f, 0x5f, 0xd8, 0x12, 0x8c, 0x95, 0xe9, + 0x00, 0xd7, 0x82, 0xe4, 0x08, 0x9d, 0xa0, 0xd6, 0x6e, 0xff, 0x94, 0xfe, 0xf6, 0x3d, 0x1a, 0xd4, + 0x83, 0xff, 0xb3, 0x8f, 0xe3, 0x64, 0x18, 0x95, 0xfd, 0x57, 0x84, 0x77, 0x6e, 0x56, 0xb1, 0xd3, + 0x29, 0xc2, 0xb5, 0x80, 0xa4, 0x9d, 0x6d, 0x8c, 0x62, 0xae, 0xfa, 0xf9, 0x76, 0x70, 0xc8, 0xdc, + 0xa4, 0xcf, 0x6f, 0x5f, 0xd3, 0x7f, 0xad, 0xf4, 0x8c, 0x6d, 0xd5, 0x8c, 0xc1, 0xfd, 0x6c, 0x41, + 0xd0, 0x7c, 0x41, 0xd0, 0xe7, 0x82, 0xa0, 0x97, 0x25, 0x49, 0xe6, 0x4b, 0x92, 0xbc, 0x2f, 0x49, + 0x72, 0x77, 0xa5, 0xb4, 0x7b, 0x18, 0x0b, 0x9a, 0x41, 0xb1, 0xf6, 0xea, 0xe6, 0x5c, 0xd8, 0x8d, + 0xf1, 0xa4, 0x77, 0xc9, 0x1e, 0x7f, 0xda, 0x67, 0xb9, 0x96, 0xc6, 0x85, 0x49, 0xf9, 0x46, 0x8b, + 0x9a, 0x5f, 0x2e, 0xbe, 0x03, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xd0, 0xad, 0x85, 0x48, 0x02, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -160,7 +162,7 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // Params defines a gRPC query method that returns the ibc-rate-limit module's // parameters. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + Params(ctx context.Context, in *ParamsRequest, opts ...grpc.CallOption) (*ParamsResponse, error) } type queryClient struct { @@ -171,8 +173,8 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - out := new(QueryParamsResponse) +func (c *queryClient) Params(ctx context.Context, in *ParamsRequest, opts ...grpc.CallOption) (*ParamsResponse, error) { + out := new(ParamsResponse) err := c.cc.Invoke(ctx, "/osmosis.ibcratelimit.v1beta1.Query/Params", in, out, opts...) if err != nil { return nil, err @@ -184,14 +186,14 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . type QueryServer interface { // Params defines a gRPC query method that returns the ibc-rate-limit module's // parameters. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + Params(context.Context, *ParamsRequest) (*ParamsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. type UnimplementedQueryServer struct { } -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { +func (*UnimplementedQueryServer) Params(ctx context.Context, req *ParamsRequest) (*ParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } @@ -200,7 +202,7 @@ func RegisterQueryServer(s grpc1.Server, srv QueryServer) { } func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) + in := new(ParamsRequest) if err := dec(in); err != nil { return nil, err } @@ -212,7 +214,7 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf FullMethod: "/osmosis.ibcratelimit.v1beta1.Query/Params", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + return srv.(QueryServer).Params(ctx, req.(*ParamsRequest)) } return interceptor(ctx, in, info, handler) } @@ -230,7 +232,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Metadata: "osmosis/ibc-rate-limit/v1beta1/query.proto", } -func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { +func (m *ParamsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -240,12 +242,12 @@ func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *ParamsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -253,7 +255,7 @@ func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { +func (m *ParamsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -263,12 +265,12 @@ func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *ParamsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -297,7 +299,7 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *QueryParamsRequest) Size() (n int) { +func (m *ParamsRequest) Size() (n int) { if m == nil { return 0 } @@ -306,7 +308,7 @@ func (m *QueryParamsRequest) Size() (n int) { return n } -func (m *QueryParamsResponse) Size() (n int) { +func (m *ParamsResponse) Size() (n int) { if m == nil { return 0 } @@ -323,7 +325,7 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { +func (m *ParamsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -346,10 +348,10 @@ func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ParamsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -373,7 +375,7 @@ func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { +func (m *ParamsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -396,10 +398,10 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: ParamsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/x/ibc-rate-limit/types/query.pb.gw.go b/x/ibc-rate-limit/client/queryproto/query.pb.gw.go similarity index 98% rename from x/ibc-rate-limit/types/query.pb.gw.go rename to x/ibc-rate-limit/client/queryproto/query.pb.gw.go index 9e938b097e5..949f7dd73de 100644 --- a/x/ibc-rate-limit/types/query.pb.gw.go +++ b/x/ibc-rate-limit/client/queryproto/query.pb.gw.go @@ -2,11 +2,11 @@ // source: osmosis/ibc-rate-limit/v1beta1/query.proto /* -Package types is a reverse proxy. +Package queryproto is a reverse proxy. It translates gRPC into RESTful JSON APIs. */ -package types +package queryproto import ( "context" @@ -34,7 +34,7 @@ var _ = descriptor.ForMessage var _ = metadata.Join func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest + var protoReq ParamsRequest var metadata runtime.ServerMetadata msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -43,7 +43,7 @@ func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, cl } func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest + var protoReq ParamsRequest var metadata runtime.ServerMetadata msg, err := server.Params(ctx, &protoReq) diff --git a/x/ibc-rate-limit/genesis.go b/x/ibc-rate-limit/genesis.go new file mode 100644 index 00000000000..e4611df345c --- /dev/null +++ b/x/ibc-rate-limit/genesis.go @@ -0,0 +1,20 @@ +package ibc_rate_limit + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" +) + +// InitGenesis initializes the x/ibc-rate-limit module's state from a provided genesis +// state, which includes the parameter for the contract address. +func (i *ICS4Wrapper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { + i.SetParams(ctx, genState.Params) +} + +// ExportGenesis returns the x/ibc-rate-limit module's exported genesis. +func (i *ICS4Wrapper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + return &types.GenesisState{ + Params: i.GetParams(ctx), + } +} diff --git a/x/ibc-rate-limit/genesis_test.go b/x/ibc-rate-limit/genesis_test.go new file mode 100644 index 00000000000..4389d98f1e1 --- /dev/null +++ b/x/ibc-rate-limit/genesis_test.go @@ -0,0 +1,43 @@ +package ibc_rate_limit_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + + "github.com/osmosis-labs/osmosis/v14/app/apptesting" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" +) + +type GenesisTestSuite struct { + apptesting.KeeperTestHelper +} + +func TestGenesisTestSuite(t *testing.T) { + suite.Run(t, new(GenesisTestSuite)) +} + +func (suite *GenesisTestSuite) SetupTest() { + suite.Setup() +} + +func (suite *GenesisTestSuite) TestInitExportGenesis() { + testAddress := sdk.AccAddress([]byte("addr1_______________")).String() + suite.SetupTest() + k := suite.App.RateLimitingICS4Wrapper + + initialGenesis := types.GenesisState{ + Params: types.Params{ + ContractAddress: testAddress, + }, + } + + k.InitGenesis(suite.Ctx, initialGenesis) + + suite.Require().Equal(testAddress, k.GetParams(suite.Ctx).ContractAddress) + + exportedGenesis := k.ExportGenesis(suite.Ctx) + + suite.Require().Equal(initialGenesis, *exportedGenesis) +} diff --git a/x/ibc-rate-limit/ibc_module.go b/x/ibc-rate-limit/ibc_module.go index c0cd1e81544..22706d48f40 100644 --- a/x/ibc-rate-limit/ibc_module.go +++ b/x/ibc-rate-limit/ibc_module.go @@ -128,7 +128,7 @@ func (im *IBCModule) OnRecvPacket( return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrBadMessage, err.Error()) } - contract := im.ics4Middleware.GetParams(ctx) + contract := im.ics4Middleware.GetContractAddress(ctx) if contract == "" { // The contract has not been configured. Continue as usual return im.app.OnRecvPacket(ctx, packet, relayer) @@ -202,7 +202,7 @@ func (im *IBCModule) RevertSentPacket( ctx sdk.Context, packet exported.PacketI, ) error { - contract := im.ics4Middleware.GetParams(ctx) + contract := im.ics4Middleware.GetContractAddress(ctx) if contract == "" { // The contract has not been configured. Continue as usual return nil diff --git a/x/ibc-rate-limit/ibcratelimitmodule/module.go b/x/ibc-rate-limit/ibcratelimitmodule/module.go new file mode 100644 index 00000000000..cbce61bec66 --- /dev/null +++ b/x/ibc-rate-limit/ibcratelimitmodule/module.go @@ -0,0 +1,148 @@ +package ibcratelimitmodule + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + + ibcratelimit "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit" + ibcratelimitclient "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client" + ibcratelimitcli "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/cli" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/grpc" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/queryproto" + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +type AppModuleBasic struct{} + +func (AppModuleBasic) Name() string { return types.ModuleName } + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { +} + +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the ibc-rate-limit module. +func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// --------------------------------------- +// Interfaces. +func (b AppModuleBasic) RegisterRESTRoutes(ctx client.Context, r *mux.Router) { +} + +func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + queryproto.RegisterQueryHandlerClient(context.Background(), mux, queryproto.NewQueryClient(clientCtx)) //nolint:errcheck +} + +func (b AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +func (b AppModuleBasic) GetQueryCmd() *cobra.Command { + return ibcratelimitcli.GetQueryCmd() +} + +// RegisterInterfaces registers interfaces and implementations of the ibc-rate-limit module. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + ics4wrapper ibcratelimit.ICS4Wrapper +} + +func NewAppModule(ics4wrapper ibcratelimit.ICS4Wrapper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + ics4wrapper: ics4wrapper, + } +} + +// Name returns the txfees module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the txfees module's message routing key. +func (am AppModule) Route() sdk.Route { + return sdk.Route{} +} + +// QuerierRoute returns the ibc-rate-limit module's query routing key. +func (AppModule) QuerierRoute() string { return types.RouterKey } + +// LegacyQuerierHandler is a no-op. Needed to meet AppModule interface. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { + return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) + } +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + queryproto.RegisterQueryServer(cfg.QueryServer(), grpc.Querier{Q: ibcratelimitclient.Querier{K: am.ics4wrapper}}) +} + +// RegisterInvariants registers the txfees module's invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the txfees module's genesis initialization It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + am.ics4wrapper.InitGenesis(ctx, genState) + + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the txfees module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.ics4wrapper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the txfees module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock executes all ABCI EndBlock logic respective to the txfees module. It +// returns no validator updates. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/ibc-rate-limit/ics4_wrapper.go b/x/ibc-rate-limit/ics4_wrapper.go index 52c9bd33a9e..d0b193b0e82 100644 --- a/x/ibc-rate-limit/ics4_wrapper.go +++ b/x/ibc-rate-limit/ics4_wrapper.go @@ -11,6 +11,8 @@ import ( channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" "github.com/cosmos/ibc-go/v4/modules/core/exported" + + "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" ) var ( @@ -27,8 +29,7 @@ type ICS4Wrapper struct { } func (i *ICS4Wrapper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { - //TODO implement me - panic("implement me") + return i.channel.GetAppVersion(ctx, portID, channelID) } func NewICS4Middleware( @@ -36,6 +37,9 @@ func NewICS4Middleware( accountKeeper *authkeeper.AccountKeeper, contractKeeper *wasmkeeper.PermissionedKeeper, bankKeeper *bankkeeper.BaseKeeper, paramSpace paramtypes.Subspace, ) ICS4Wrapper { + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } return ICS4Wrapper{ channel: channel, accountKeeper: accountKeeper, @@ -51,7 +55,7 @@ func NewICS4Middleware( // If the contract param is not configured, or the contract doesn't have a configuration for the (channel+denom) being // used, transfers are not prevented and handled by the wrapped IBC app func (i *ICS4Wrapper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.PacketI) error { - contract := i.GetParams(ctx) + contract := i.GetContractAddress(ctx) if contract == "" { // The contract has not been configured. Continue as usual return i.channel.SendPacket(ctx, chanCap, packet) @@ -77,7 +81,24 @@ func (i *ICS4Wrapper) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilityt return i.channel.WriteAcknowledgement(ctx, chanCap, packet, ack) } -func (i *ICS4Wrapper) GetParams(ctx sdk.Context) (contract string) { - i.paramSpace.GetIfExists(ctx, []byte("contract"), &contract) - return contract +func (i *ICS4Wrapper) GetContractAddress(ctx sdk.Context) (contract string) { + return i.GetParams(ctx).ContractAddress +} + +func (i *ICS4Wrapper) GetParams(ctx sdk.Context) (params types.Params) { + // This was previously done via i.paramSpace.GetParamSet(ctx, ¶ms). That will + // panic if the params don't exist. This is a workaround to avoid that panic. + // Params should be refactored to just use a raw kvstore. + empty := types.Params{} + for _, pair := range params.ParamSetPairs() { + i.paramSpace.GetIfExists(ctx, pair.Key, pair.Value) + } + if params == empty { + return types.DefaultParams() + } + return params +} + +func (i *ICS4Wrapper) SetParams(ctx sdk.Context, params types.Params) { + i.paramSpace.SetParamSet(ctx, ¶ms) } diff --git a/x/ibc-rate-limit/module.go b/x/ibc-rate-limit/module.go deleted file mode 100644 index 85e4fe13e5e..00000000000 --- a/x/ibc-rate-limit/module.go +++ /dev/null @@ -1,58 +0,0 @@ -package ibc_rate_limit - -import ( - "context" - "encoding/json" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/types/module" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - - ibcratelimitcli "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/client/cli" - "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" -) - -var _ module.AppModuleBasic = AppModuleBasic{} - -type AppModuleBasic struct{} - -func (AppModuleBasic) Name() string { return types.ModuleName } - -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { -} - -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return nil -} - -// ValidateGenesis performs genesis state validation for the ibc-rate-limit module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - return nil -} - -// --------------------------------------- -// Interfaces. -func (b AppModuleBasic) RegisterRESTRoutes(ctx client.Context, r *mux.Router) { -} - -func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) //nolint:errcheck -} - -func (b AppModuleBasic) GetTxCmd() *cobra.Command { - return nil -} - -func (b AppModuleBasic) GetQueryCmd() *cobra.Command { - return ibcratelimitcli.GetQueryCmd() -} - -// RegisterInterfaces registers interfaces and implementations of the ibc-rate-limit module. -func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { -} diff --git a/x/ibc-rate-limit/types/genesis.go b/x/ibc-rate-limit/types/genesis.go new file mode 100644 index 00000000000..9167936c6bb --- /dev/null +++ b/x/ibc-rate-limit/types/genesis.go @@ -0,0 +1,17 @@ +package types + +// DefaultGenesis creates a default GenesisState object. +func DefaultGenesis() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + return nil +} diff --git a/x/ibc-rate-limit/types/genesis.pb.go b/x/ibc-rate-limit/types/genesis.pb.go new file mode 100644 index 00000000000..23b83f28bcb --- /dev/null +++ b/x/ibc-rate-limit/types/genesis.pb.go @@ -0,0 +1,329 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/ibc-rate-limit/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the ibc-rate-limit module's genesis state. +type GenesisState struct { + // params are all the parameters of the module + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_14e381f6ddb4f706, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "osmosis.ibcratelimit.v1beta1.GenesisState") +} + +func init() { + proto.RegisterFile("osmosis/ibc-rate-limit/v1beta1/genesis.proto", fileDescriptor_14e381f6ddb4f706) +} + +var fileDescriptor_14e381f6ddb4f706 = []byte{ + // 248 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xc9, 0x2f, 0xce, 0xcd, + 0x2f, 0xce, 0x2c, 0xd6, 0xcf, 0x4c, 0x4a, 0xd6, 0x2d, 0x4a, 0x2c, 0x49, 0xd5, 0xcd, 0xc9, 0xcc, + 0xcd, 0x2c, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, + 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x81, 0xaa, 0xd6, 0xcb, 0x4c, 0x4a, + 0x06, 0x29, 0x06, 0xab, 0xd5, 0x83, 0xaa, 0x95, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd4, + 0x07, 0xb1, 0x20, 0x7a, 0xa4, 0x24, 0x93, 0xc1, 0x9a, 0xe2, 0x21, 0x12, 0x10, 0x0e, 0x4c, 0x2a, + 0x3d, 0x3f, 0x3f, 0x3d, 0x27, 0x55, 0x1f, 0xcc, 0x4b, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0x84, + 0x4a, 0x69, 0x13, 0x70, 0x57, 0x41, 0x62, 0x51, 0x62, 0x2e, 0xd4, 0x1c, 0xa5, 0x20, 0x2e, 0x1e, + 0x77, 0x88, 0x3b, 0x83, 0x4b, 0x12, 0x4b, 0x52, 0x85, 0x9c, 0xb8, 0xd8, 0x20, 0xf2, 0x12, 0x8c, + 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x2a, 0x7a, 0xf8, 0xdc, 0xad, 0x17, 0x00, 0x56, 0xeb, 0xc4, 0x72, + 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x54, 0xa7, 0x53, 0xc8, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, + 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, + 0xcb, 0x31, 0x44, 0x59, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, + 0xcd, 0xd5, 0xcd, 0x49, 0x4c, 0x2a, 0x86, 0x71, 0xf4, 0xcb, 0x0c, 0x4d, 0xf4, 0x2b, 0xd0, 0x1d, + 0x5e, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x76, 0xb0, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, + 0xf2, 0xd7, 0xd1, 0xc2, 0x77, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/ibc-rate-limit/types/keys.go b/x/ibc-rate-limit/types/keys.go index 28eb2fcc106..85a5a0726cd 100644 --- a/x/ibc-rate-limit/types/keys.go +++ b/x/ibc-rate-limit/types/keys.go @@ -1,5 +1,14 @@ package types +import "strings" + const ( ModuleName = "rate-limited-ibc" // IBC at the end to avoid conflicts with the ibc prefix + +) + +var ( + // RouterKey is the message route. Can only contain + // alphanumeric characters. + RouterKey = strings.ReplaceAll(ModuleName, "-", "") ) diff --git a/x/ibc-rate-limit/types/params.go b/x/ibc-rate-limit/types/params.go index 30d5c6126b4..35b17286338 100644 --- a/x/ibc-rate-limit/types/params.go +++ b/x/ibc-rate-limit/types/params.go @@ -41,7 +41,7 @@ func (p Params) Validate() error { } // Implements params.ParamSet. -func (p Params) ParamSetPairs() paramtypes.ParamSetPairs { +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyContractAddress, &p.ContractAddress, validateContractAddress), }