diff --git a/protocol/app/ante/msg_type_test.go b/protocol/app/ante/msg_type_test.go index bf88eac62e..e746e603fa 100644 --- a/protocol/app/ante/msg_type_test.go +++ b/protocol/app/ante/msg_type_test.go @@ -1,11 +1,12 @@ package ante_test import ( - errorsmod "cosmossdk.io/errors" "fmt" - "golang.org/x/exp/slices" "testing" + errorsmod "cosmossdk.io/errors" + "golang.org/x/exp/slices" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/protocol/app/app.go b/protocol/app/app.go index 0c414ae3ce..8af600e5f8 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -169,6 +169,11 @@ import ( vestmoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/vest/types" // IBC + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" "github.com/cosmos/ibc-go/v7/modules/apps/transfer" ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" @@ -238,16 +243,13 @@ type App struct { ParamsKeeper paramskeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly IBCKeeper *ibckeeper.Keeper + ICAHostKeeper icahostkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper RatelimitKeeper ratelimitmodulekeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper - // make scoped keepers public for test purposes - ScopedIBCKeeper capabilitykeeper.ScopedKeeper - ScopedTransferKeeper capabilitykeeper.ScopedKeeper - PricesKeeper pricesmodulekeeper.Keeper AssetsKeeper assetsmodulekeeper.Keeper @@ -348,6 +350,7 @@ func New( govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, ibcexported.StoreKey, ibctransfertypes.StoreKey, ratelimitmoduletypes.StoreKey, + icahosttypes.StoreKey, evidencetypes.StoreKey, capabilitytypes.StoreKey, pricesmoduletypes.StoreKey, @@ -416,10 +419,6 @@ func New( memKeys[capabilitytypes.MemStoreKey], ) - // grant capabilities for the ibc and ibc-transfer modules - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) - scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) - // add keepers app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, @@ -519,6 +518,14 @@ func New( // Set legacy router for backwards compatibility with gov v1beta1 govKeeper.SetLegacyRouter(govRouter) + // grant capabilities for the ibc, ibc-transfer and ICAHostKeeper modules + + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) + scopedIBCTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) + + app.CapabilityKeeper.Seal() + // Create IBC Keeper app.IBCKeeper = ibckeeper.NewKeeper( appCodec, @@ -529,11 +536,24 @@ func New( scopedIBCKeeper, ) + // Create ICA Host Keeper + app.ICAHostKeeper = icahostkeeper.NewKeeper( + appCodec, + keys[icahosttypes.StoreKey], // key + app.getSubspace(icahosttypes.SubModuleName), // paramSpace + app.IBCKeeper.ChannelKeeper, // ics4Wrapper, may be replaced with middleware such as ics29 fee + app.IBCKeeper.ChannelKeeper, // channelKeeper + &app.IBCKeeper.PortKeeper, // portKeeper + app.AccountKeeper, // accountKeeper + scopedICAHostKeeper, // scopedKeeper + app.MsgServiceRouter(), // msgRouter + ) + // Create Transfer Keepers app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, keys[ibctransfertypes.StoreKey], app.getSubspace(ibctransfertypes.ModuleName), app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, + app.AccountKeeper, app.BankKeeper, scopedIBCTransferKeeper, ) transferModule := transfer.NewAppModule(app.TransferKeeper) transferIBCModule := transfer.NewIBCModule(app.TransferKeeper) @@ -550,9 +570,13 @@ func New( // TODO(CORE-834): Add ratelimitKeeper to the IBC transfer stack. + icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) // Create static IBC router, add transfer route, then set and seal it ibcRouter := ibcporttypes.NewRouter() + // Ordering of `AddRoute` does not matter. ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule) + ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) + app.IBCKeeper.SetRouter(ibcRouter) // create evidence keeper with router @@ -956,6 +980,7 @@ func New( upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), + ica.NewAppModule(nil, &app.ICAHostKeeper), params.NewAppModule(app.ParamsKeeper), consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), transferModule, @@ -999,6 +1024,7 @@ func New( feegrant.ModuleName, paramstypes.ModuleName, consensusparamtypes.ModuleName, + icatypes.ModuleName, pricesmoduletypes.ModuleName, assetsmoduletypes.ModuleName, bridgemoduletypes.ModuleName, @@ -1035,6 +1061,7 @@ func New( ibctransfertypes.ModuleName, ratelimitmoduletypes.ModuleName, consensusparamtypes.ModuleName, + icatypes.ModuleName, pricesmoduletypes.ModuleName, assetsmoduletypes.ModuleName, bridgemoduletypes.ModuleName, @@ -1075,6 +1102,7 @@ func New( ratelimitmoduletypes.ModuleName, feegrant.ModuleName, consensusparamtypes.ModuleName, + icatypes.ModuleName, pricesmoduletypes.ModuleName, assetsmoduletypes.ModuleName, blocktimemoduletypes.ModuleName, @@ -1111,6 +1139,7 @@ func New( ratelimitmoduletypes.ModuleName, feegrant.ModuleName, consensusparamtypes.ModuleName, + icatypes.ModuleName, pricesmoduletypes.ModuleName, assetsmoduletypes.ModuleName, blocktimemoduletypes.ModuleName, @@ -1232,9 +1261,6 @@ func New( } app.initializeRateLimiters() - app.ScopedIBCKeeper = scopedIBCKeeper - app.ScopedTransferKeeper = scopedTransferKeeper - // Report out app version and git commit. This will be run when validators restart. version := version.NewInfo() app.Logger().Info( @@ -1524,6 +1550,7 @@ func initParamsKeeper( paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1.ParamKeyTable()) //nolint:staticcheck paramsKeeper.Subspace(crisistypes.ModuleName) paramsKeeper.Subspace(ibctransfertypes.ModuleName) + paramsKeeper.Subspace(icahosttypes.SubModuleName) paramsKeeper.Subspace(ibcexported.ModuleName) return paramsKeeper diff --git a/protocol/app/app_test.go b/protocol/app/app_test.go index ded9ee8b8d..1c770932dc 100644 --- a/protocol/app/app_test.go +++ b/protocol/app/app_test.go @@ -1,13 +1,14 @@ package app_test import ( - "github.com/dydxprotocol/v4-chain/protocol/mocks" - "gopkg.in/typ.v4/slices" "reflect" "strings" "testing" "time" + "github.com/dydxprotocol/v4-chain/protocol/mocks" + "gopkg.in/typ.v4/slices" + delaymsgmodule "github.com/dydxprotocol/v4-chain/protocol/x/delaymsg" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -29,6 +30,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/upgrade" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" "github.com/cosmos/ibc-go/v7/modules/apps/transfer" ibc "github.com/cosmos/ibc-go/v7/modules/core" ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" @@ -199,6 +201,7 @@ func TestModuleBasics(t *testing.T) { feegrantmodule.AppModuleBasic{}, ibc.AppModuleBasic{}, ibctm.AppModuleBasic{}, + ica.AppModuleBasic{}, upgrade.AppModuleBasic{}, transfer.AppModuleBasic{}, consensus.AppModuleBasic{}, diff --git a/protocol/app/basic_manager/basic_manager.go b/protocol/app/basic_manager/basic_manager.go index 2bfafe027d..1bedee9624 100644 --- a/protocol/app/basic_manager/basic_manager.go +++ b/protocol/app/basic_manager/basic_manager.go @@ -36,6 +36,7 @@ import ( subaccountsmodule "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts" vestmodule "github.com/dydxprotocol/v4-chain/protocol/x/vest" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" "github.com/cosmos/ibc-go/v7/modules/apps/transfer" ibc "github.com/cosmos/ibc-go/v7/modules/core" ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" @@ -69,6 +70,7 @@ var ( feegrantmodule.AppModuleBasic{}, ibc.AppModuleBasic{}, ibctm.AppModuleBasic{}, + ica.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, diff --git a/protocol/app/module_accounts.go b/protocol/app/module_accounts.go index 0880c5e1fc..3958427f7c 100644 --- a/protocol/app/module_accounts.go +++ b/protocol/app/module_accounts.go @@ -5,6 +5,7 @@ import ( distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" "github.com/dydxprotocol/v4-chain/protocol/app/config" @@ -33,6 +34,7 @@ var ( stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + icatypes.ModuleName: nil, // -------- dYdX custom module accounts -------- // bridge module account mints tokens for bridged funds. bridgemoduletypes.ModuleName: {authtypes.Minter}, @@ -53,7 +55,7 @@ var ( delaymsgtypes.ModuleName: nil, } // Blocked module accounts which cannot receive external funds. - // By default, all native SDK module accounts are blocked. This prevents + // By default, all non-custom modules (except for gov) are blocked. This prevents // unexpected violation of invariants (for example, https://github.com/cosmos/cosmos-sdk/issues/4795) blockedModuleAccounts = map[string]bool{ authtypes.FeeCollectorName: true, @@ -61,6 +63,7 @@ var ( stakingtypes.BondedPoolName: true, stakingtypes.NotBondedPoolName: true, ibctransfertypes.ModuleName: true, + icatypes.ModuleName: true, } ) diff --git a/protocol/app/module_accounts_test.go b/protocol/app/module_accounts_test.go index b2d9efd57d..f02430ea46 100644 --- a/protocol/app/module_accounts_test.go +++ b/protocol/app/module_accounts_test.go @@ -7,6 +7,7 @@ import ( distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" "github.com/dydxprotocol/v4-chain/protocol/app" bridgemoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/bridge/types" @@ -34,6 +35,7 @@ func TestModuleAccountsToAddresses(t *testing.T) { vestmoduletypes.CommunityTreasuryAccountName: "dydx15ztc7xy42tn2ukkc0qjthkucw9ac63pgp70urn", vestmoduletypes.CommunityVesterAccountName: "dydx1wxje320an3karyc6mjw4zghs300dmrjkwn7xtk", delaymsgtypes.ModuleName: "dydx1mkkvp26dngu6n8rmalaxyp3gwkjuzztq5zx6tr", + icatypes.ModuleName: "dydx1vlthgax23ca9syk7xgaz347xmf4nunefw3cnv8", } require.True(t, len(expectedModuleAccToAddresses) == len(app.GetMaccPerms())) @@ -50,6 +52,7 @@ func TestBlockedAddresses(t *testing.T) { "dydx1tygms3xhhs3yv487phx3dw4a95jn7t7lgzm605": true, "dydx1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3uz8teq": true, "dydx1yl6hdjhmkf37639730gffanpzndzdpmh8xcdh5": true, + "dydx1vlthgax23ca9syk7xgaz347xmf4nunefw3cnv8": true, } require.Equal(t, expectedBlockedAddresses, app.BlockedAddresses()) } @@ -66,6 +69,7 @@ func TestMaccPerms(t *testing.T) { "not_bonded_tokens_pool": {"burner", "staking"}, "subaccounts": nil, "transfer": {"minter", "burner"}, + "interchainaccounts": nil, "rewards_treasury": nil, "rewards_vester": nil, "community_treasury": nil, @@ -84,6 +88,7 @@ func TestModuleAccountAddrs(t *testing.T) { "dydx1tygms3xhhs3yv487phx3dw4a95jn7t7lgzm605": true, // x/staking.notBondedPool "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky": true, // x/ gov "dydx1yl6hdjhmkf37639730gffanpzndzdpmh8xcdh5": true, // ibc transfer + "dydx1vlthgax23ca9syk7xgaz347xmf4nunefw3cnv8": true, // interchainaccounts "dydx1v88c3xv9xyv3eetdx0tvcmq7ung3dywp5upwc6": true, // x/subaccount "dydx1c7ptc87hkd54e3r7zjy92q29xkq7t79w64slrq": true, // x/clob.insuranceFund "dydx16wrau2x4tsg033xfrrdpae6kxfn9kyuerr5jjp": true, // x/rewards.treasury diff --git a/protocol/app/msgs/all_msgs.go b/protocol/app/msgs/all_msgs.go index 541533a8cd..9de7b901e3 100644 --- a/protocol/app/msgs/all_msgs.go +++ b/protocol/app/msgs/all_msgs.go @@ -287,6 +287,15 @@ var ( "/ibc.lightclients.tendermint.v1.ConsensusState": {}, "/ibc.lightclients.tendermint.v1.Header": {}, "/ibc.lightclients.tendermint.v1.Misbehaviour": {}, + + // ica messages + // Note: the `interchain_accounts.controller` messages are not actually used by the app, + // since ICA Controller Keeper is initialized as nil. + // However, since the ica.AppModuleBasic{} needs to be passed to basic_mananger as a whole, these messages + // registered in the interface registry. + "/ibc.applications.interchain_accounts.v1.InterchainAccount": {}, + "/ibc.applications.interchain_accounts.controller.v1.MsgSendTx": {}, + "/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount": {}, } // DisallowMsgs are messages that cannot be externally submitted. diff --git a/protocol/app/msgs/normal_msgs.go b/protocol/app/msgs/normal_msgs.go index d9948fe0b2..968fa4072d 100644 --- a/protocol/app/msgs/normal_msgs.go +++ b/protocol/app/msgs/normal_msgs.go @@ -206,5 +206,8 @@ var ( "/ibc.lightclients.tendermint.v1.ConsensusState": nil, "/ibc.lightclients.tendermint.v1.Header": nil, "/ibc.lightclients.tendermint.v1.Misbehaviour": nil, + + // ica + "/ibc.applications.interchain_accounts.v1.InterchainAccount": nil, } ) diff --git a/protocol/app/msgs/normal_msgs_test.go b/protocol/app/msgs/normal_msgs_test.go index 1de856906a..0f344b8837 100644 --- a/protocol/app/msgs/normal_msgs_test.go +++ b/protocol/app/msgs/normal_msgs_test.go @@ -125,6 +125,9 @@ func TestNormalMsgs_Key(t *testing.T) { "/dydxprotocol.sending.MsgWithdrawFromSubaccount", "/dydxprotocol.sending.MsgWithdrawFromSubaccountResponse", + // ibc application module: ICA + "/ibc.applications.interchain_accounts.v1.InterchainAccount", + // ibc.applications "/ibc.applications.transfer.v1.MsgTransfer", "/ibc.applications.transfer.v1.MsgTransferResponse", diff --git a/protocol/app/msgs/unsupported_msgs.go b/protocol/app/msgs/unsupported_msgs.go index b892e9aae4..e492b08ee4 100644 --- a/protocol/app/msgs/unsupported_msgs.go +++ b/protocol/app/msgs/unsupported_msgs.go @@ -3,6 +3,8 @@ package msgs import ( sdk "github.com/cosmos/cosmos-sdk/types" govbeta "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ) var ( @@ -11,5 +13,10 @@ var ( // gov "/cosmos.gov.v1beta1.MsgSubmitProposal": &govbeta.MsgSubmitProposal{}, "/cosmos.gov.v1beta1.MsgSubmitProposalResponse": nil, + + // ICA Controller messages - these are not used since ICA Controller is disabled. + "/ibc.applications.interchain_accounts.controller.v1.MsgSendTx": &icacontrollertypes.MsgSendTx{}, + "/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount": &icacontrollertypes. + MsgRegisterInterchainAccount{}, } ) diff --git a/protocol/app/msgs/unsupported_msgs_test.go b/protocol/app/msgs/unsupported_msgs_test.go index d0d5deba6e..3ec1e68c1a 100644 --- a/protocol/app/msgs/unsupported_msgs_test.go +++ b/protocol/app/msgs/unsupported_msgs_test.go @@ -13,6 +13,10 @@ func TestUnsupportedMsgSamples_Key(t *testing.T) { expectedMsgs := []string{ "/cosmos.gov.v1beta1.MsgSubmitProposal", "/cosmos.gov.v1beta1.MsgSubmitProposalResponse", + + // ICA Controller messages + "/ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount", + "/ibc.applications.interchain_accounts.controller.v1.MsgSendTx", } require.Equal(t, expectedMsgs, lib.GetSortedKeys[sort.StringSlice](msgs.UnsupportedMsgSamples)) diff --git a/protocol/app/simulation_test.go b/protocol/app/simulation_test.go index 7d5d8cac51..91b92d3dfd 100644 --- a/protocol/app/simulation_test.go +++ b/protocol/app/simulation_test.go @@ -41,6 +41,7 @@ import ( simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" exportedtypes "github.com/cosmos/ibc-go/v7/modules/core/exported" "github.com/dydxprotocol/v4-chain/protocol/app" @@ -114,6 +115,7 @@ var genesisModuleOrder = []string{ exportedtypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName, + icatypes.ModuleName, pricestypes.ModuleName, assetstypes.ModuleName, perpetualstypes.ModuleName, diff --git a/protocol/app/testdata/default_genesis_state.json b/protocol/app/testdata/default_genesis_state.json index fe1481f288..c5a8148673 100644 --- a/protocol/app/testdata/default_genesis_state.json +++ b/protocol/app/testdata/default_genesis_state.json @@ -301,6 +301,27 @@ "next_channel_sequence": "0" } }, + "interchainaccounts": { + "controller_genesis_state": { + "active_channels": [], + "interchain_accounts": [], + "params": { + "controller_enabled": true + }, + "ports": [] + }, + "host_genesis_state": { + "active_channels": [], + "interchain_accounts": [], + "params": { + "allow_messages": [ + "*" + ], + "host_enabled": true + }, + "port": "icahost" + } + }, "params": null, "perpetuals": { "perpetuals": [], diff --git a/protocol/app/upgrades/v3.0.0/constants.go b/protocol/app/upgrades/v3.0.0/constants.go index dff9f6df95..3f4b127123 100644 --- a/protocol/app/upgrades/v3.0.0/constants.go +++ b/protocol/app/upgrades/v3.0.0/constants.go @@ -2,6 +2,7 @@ package v_3_0_0 import ( store "github.com/cosmos/cosmos-sdk/store/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" "github.com/dydxprotocol/v4-chain/protocol/app/upgrades" ratelimittypes "github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types" ) @@ -15,6 +16,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{ Added: []string{ ratelimittypes.StoreKey, + icahosttypes.StoreKey, }, }, } diff --git a/protocol/app/upgrades/v3.0.0/upgrade.go b/protocol/app/upgrades/v3.0.0/upgrade.go index 6cf6242494..b1210d0ad1 100644 --- a/protocol/app/upgrades/v3.0.0/upgrade.go +++ b/protocol/app/upgrades/v3.0.0/upgrade.go @@ -7,7 +7,16 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" bridgemoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/bridge/types" clobmoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" rewardsmoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/rewards/types" @@ -16,6 +25,27 @@ import ( ) var ( + ICAHostAllowMessages = []string{ + // IBC transfer messages + sdk.MsgTypeURL(&ibctransfertypes.MsgTransfer{}), + + // Bank messages + sdk.MsgTypeURL(&banktypes.MsgSend{}), + + // Staking messages + sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}), + sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}), + sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}), + sdk.MsgTypeURL(&stakingtypes.MsgCancelUnbondingDelegation{}), + + // Distribution messages + sdk.MsgTypeURL(&distrtypes.MsgSetWithdrawAddress{}), + sdk.MsgTypeURL(&distrtypes.MsgWithdrawDelegatorReward{}), + sdk.MsgTypeURL(&distrtypes.MsgFundCommunityPool{}), + + // Gov messages + sdk.MsgTypeURL(&govtypesv1.MsgVote{}), + } // List of module accounts to check in state. // These include all dYdX custom module accounts. ModuleAccsToInitialize = []string{ @@ -93,6 +123,32 @@ func InitializeModuleAccs(ctx sdk.Context, ak authkeeper.AccountKeeper) { } } +func IcaHostKeeperUpgradeHandler( + ctx sdk.Context, + vm module.VersionMap, + mm *module.Manager, +) { + icaAppModule, ok := mm.Modules[icatypes.ModuleName].(ica.AppModule) + if !ok { + panic("Modules[icatypes.ModuleName] is not of type ica.AppModule") + } + // Add Interchain Accounts host module + // set the ICS27 consensus version so InitGenesis is not run + // initialize ICS27 module + vm[icatypes.ModuleName] = icaAppModule.ConsensusVersion() + + // controller submodule is not enabled. + controllerParams := icacontrollertypes.Params{} + + // host submodule params + hostParams := icahosttypes.Params{ + HostEnabled: true, + AllowMessages: ICAHostAllowMessages, + } + + icaAppModule.InitModule(ctx, controllerParams, hostParams) +} + func CreateUpgradeHandler( mm *module.Manager, configurator module.Configurator, @@ -103,6 +159,9 @@ func CreateUpgradeHandler( InitializeModuleAccs(ctx, ak) // TODO(CORE-824): Initialize ratelimit module params to desired state. + + // TODO(CORE-848): Any unit test after a v3.0.0 upgrade test is added. + IcaHostKeeperUpgradeHandler(ctx, vm, mm) return mm.RunMigrations(ctx, configurator, vm) } } diff --git a/protocol/app/upgrades/v3.0.0/upgrade_test.go b/protocol/app/upgrades/v3.0.0/upgrade_test.go new file mode 100644 index 0000000000..6f826305ff --- /dev/null +++ b/protocol/app/upgrades/v3.0.0/upgrade_test.go @@ -0,0 +1,26 @@ +package v_3_0_0 + +import ( + "github.com/stretchr/testify/require" + + "testing" +) + +func TestICAHostAllowMessages(t *testing.T) { + require.Equal( + t, + []string{ + "/ibc.applications.transfer.v1.MsgTransfer", + "/cosmos.bank.v1beta1.MsgSend", + "/cosmos.staking.v1beta1.MsgDelegate", + "/cosmos.staking.v1beta1.MsgBeginRedelegate", + "/cosmos.staking.v1beta1.MsgUndelegate", + "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation", + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + "/cosmos.gov.v1.MsgVote", + }, + ICAHostAllowMessages, + ) +} diff --git a/protocol/lib/ante/app_injected_msg_test.go b/protocol/lib/ante/app_injected_msg_test.go index 61883a65eb..256775a563 100644 --- a/protocol/lib/ante/app_injected_msg_test.go +++ b/protocol/lib/ante/app_injected_msg_test.go @@ -83,7 +83,6 @@ func TestIsAppInjectedMsg_Invalid(t *testing.T) { delete(allMsgsMinusAppInjected, key) } allNonNilSampleMsgs := testmsgs.GetNonNilSampleMsgs(allMsgsMinusAppInjected) - require.Len(t, allNonNilSampleMsgs, 85) for _, sampleMsg := range allNonNilSampleMsgs { t.Run(sampleMsg.Name, func(t *testing.T) { diff --git a/protocol/lib/ante/disallow_msg_test.go b/protocol/lib/ante/disallow_msg_test.go index 38698c6cd1..1eebec22be 100644 --- a/protocol/lib/ante/disallow_msg_test.go +++ b/protocol/lib/ante/disallow_msg_test.go @@ -14,8 +14,6 @@ import ( func TestIsDisallowExternalSubmitMsg(t *testing.T) { // All disallow msgs should return true. disallowSampleMsgs := testmsgs.GetNonNilSampleMsgs(appmsgs.DisallowMsgs) - // +1 for "/cosmos.auth.v1beta1.MsgUpdateParams" not having a corresponding Response msg type. - require.Len(t, disallowSampleMsgs, len(appmsgs.DisallowMsgs)/2+1) for _, sampleMsg := range disallowSampleMsgs { result := ante.IsDisallowExternalSubmitMsg(sampleMsg.Msg) if ante.IsNestedMsg(sampleMsg.Msg) { diff --git a/protocol/lib/ante/unsupported_msgs.go b/protocol/lib/ante/unsupported_msgs.go index 67c63f3bf5..4e46d93d25 100644 --- a/protocol/lib/ante/unsupported_msgs.go +++ b/protocol/lib/ante/unsupported_msgs.go @@ -3,12 +3,17 @@ package ante import ( sdk "github.com/cosmos/cosmos-sdk/types" govbeta "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ) // IsUnsupportedMsg returns true if the msg is unsupported by the app. func IsUnsupportedMsg(msg sdk.Msg) bool { switch msg.(type) { case + // ICA Controller messages + *icacontrollertypes.MsgSendTx, + *icacontrollertypes.MsgRegisterInterchainAccount, // ------- CosmosSDK default modules // gov *govbeta.MsgSubmitProposal: diff --git a/protocol/lib/ante/unsupported_msgs_test.go b/protocol/lib/ante/unsupported_msgs_test.go index e4bfa9e752..5b7163c65e 100644 --- a/protocol/lib/ante/unsupported_msgs_test.go +++ b/protocol/lib/ante/unsupported_msgs_test.go @@ -47,7 +47,6 @@ func TestIsUnsupportedMsg_Invalid(t *testing.T) { func TestIsUnsupportedMsg_Valid(t *testing.T) { sampleMsgs := testmsgs.GetNonNilSampleMsgs(appmsgs.UnsupportedMsgSamples) - require.Len(t, sampleMsgs, len(appmsgs.UnsupportedMsgSamples)/2) for _, sampleMsg := range sampleMsgs { t.Run(sampleMsg.Name, func(t *testing.T) { diff --git a/protocol/scripts/genesis/sample_pregenesis.json b/protocol/scripts/genesis/sample_pregenesis.json index 489ec0456b..acff7f1206 100644 --- a/protocol/scripts/genesis/sample_pregenesis.json +++ b/protocol/scripts/genesis/sample_pregenesis.json @@ -808,6 +808,36 @@ } } }, + "interchainaccounts": { + "controller_genesis_state": { + "active_channels": [], + "interchain_accounts": [], + "params": { + "controller_enabled": true + }, + "ports": [] + }, + "host_genesis_state": { + "active_channels": [], + "interchain_accounts": [], + "params": { + "allow_messages": [ + "/ibc.applications.transfer.v1.MsgTransfer", + "/cosmos.bank.v1beta1.MsgSend", + "/cosmos.staking.v1beta1.MsgDelegate", + "/cosmos.staking.v1beta1.MsgBeginRedelegate", + "/cosmos.staking.v1beta1.MsgUndelegate", + "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation", + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + "/cosmos.gov.v1.MsgVote" + ], + "host_enabled": true + }, + "port": "icahost" + } + }, "perpetuals": { "liquidity_tiers": [ { diff --git a/protocol/testing/genesis.sh b/protocol/testing/genesis.sh index 6efae9d71f..efa9aa9216 100755 --- a/protocol/testing/genesis.sh +++ b/protocol/testing/genesis.sh @@ -1434,6 +1434,9 @@ function edit_genesis() { dasel put -t int -f "$GENESIS" '.app_state.delaymsg.delayed_messages.[0].block_height' -v '378000' # Uncomment the following to schedule the message to execute in ~120 days (at 1.6s per block.) # dasel put -t int -f "$GENESIS" '.app_state.delaymsg.delayed_messages.[0].block_height' -v '6480000' + + # ICA Host Params + update_ica_host_params } function add_subaccount() { @@ -1572,6 +1575,22 @@ function update_genesis_use_test_volatile_market() { dasel put -t int -f "$GENESIS" '.app_state.clob.clob_pairs.last().quantum_conversion_exponent' -v '-8' } +# Modify the genesis file with ICA Host params that are consistent with +# v3.0.0 upgrade. +function update_ica_host_params() { + dasel put -t json -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages' -v '[]' + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/ibc.applications.transfer.v1.MsgTransfer" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.bank.v1beta1.MsgSend" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.staking.v1beta1.MsgDelegate" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.staking.v1beta1.MsgBeginRedelegate" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.staking.v1beta1.MsgUndelegate" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.distribution.v1beta1.MsgFundCommunityPool" + dasel put -t string -f "$GENESIS" '.app_state.interchainaccounts.host_genesis_state.params.allow_messages.[]' -v "/cosmos.gov.v1.MsgVote" +} + # Modify the genesis file to only use fixed price exchange. function update_all_markets_with_fixed_price_exchange() { GENESIS=$1/genesis.json diff --git a/protocol/testutil/encoding/utils.go b/protocol/testutil/encoding/utils.go index 8bc634c7aa..f769e9e907 100644 --- a/protocol/testutil/encoding/utils.go +++ b/protocol/testutil/encoding/utils.go @@ -23,6 +23,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" "github.com/cosmos/gogoproto/proto" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" "github.com/cosmos/ibc-go/v7/modules/apps/transfer" ibc "github.com/cosmos/ibc-go/v7/modules/core" ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" @@ -63,6 +64,7 @@ func GetTestEncodingCfg() testutil.TestEncodingConfig { feetiers.AppModuleBasic{}, ibc.AppModuleBasic{}, ibctm.AppModuleBasic{}, + ica.AppModuleBasic{}, upgrade.AppModuleBasic{}, transfer.AppModuleBasic{}, consensus.AppModuleBasic{},