diff --git a/CHANGELOG.md b/CHANGELOG.md index 16334bd3c98..cc976fd96cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (interchain-accounts) [\#1037](https://github.com/cosmos/ibc-go/pull/1037) Add a function `InitModule` to the interchain accounts `AppModule`. This function should be called within the upgrade handler when adding the interchain accounts module to a chain. It should be called in place of InitGenesis (set the consensus version in the version map). * (testing) [\#942](https://github.com/cosmos/ibc-go/pull/942) `NewTestChain` will create 4 validators in validator set by default. A new constructor function `NewTestChainWithValSet` is provided for test writers who want custom control over the validator set of test chains. * (testing) [\#904](https://github.com/cosmos/ibc-go/pull/904) Add `ParsePacketFromEvents` function to the testing package. Useful when sending/relaying packets via the testing package. * (testing) [\#893](https://github.com/cosmos/ibc-go/pull/893) Support custom private keys for testing. diff --git a/docs/migrations/v2-to-v3.md b/docs/migrations/v2-to-v3.md index 89336d69b10..1a9220abcbe 100644 --- a/docs/migrations/v2-to-v3.md +++ b/docs/migrations/v2-to-v3.md @@ -39,17 +39,24 @@ Please see the [ICS27 documentation](../apps/interchain-accounts/overview.md) fo If the chain will adopt ICS27, it must set the appropriate params during the execution of the upgrade handler in `app.go`: ```go app.UpgradeKeeper.SetUpgradeHandler("v3", - func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - // set ICS27 Host submodule params - app.ICAHostKeeper.SetParams(ctx, icahosttypes.Params{ - HostEnabled: true, - AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...], - }) + func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // set the ICS27 consensus version so InitGenesis is not run + fromVM[icatypes.ModuleName] = icamodule.ConsensusVersion() - // set ICS27 Controller submodule params - app.ICAControllerKeeper.SetParams(ctx, icacontrollertypes.Params{ + + // create ICS27 Controller submodule params + controllerParams := icacontrollertypes.Params{ ControllerEnabled: true, - }) + } + + // create ICS27 Host submodule params + hostParams := icahosttypes.Params{ + HostEnabled: true, + AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...], + } + + // initialize ICS27 module + icamodule.InitModule(ctx, controllerParams, hostParams) ... diff --git a/modules/apps/27-interchain-accounts/module.go b/modules/apps/27-interchain-accounts/module.go index b11c611e0c9..969c07caf9d 100644 --- a/modules/apps/27-interchain-accounts/module.go +++ b/modules/apps/27-interchain-accounts/module.go @@ -24,6 +24,7 @@ import ( hosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" ) var ( @@ -101,6 +102,18 @@ func NewAppModule(controllerKeeper *controllerkeeper.Keeper, hostKeeper *hostkee } } +// InitModule will initialize the interchain accounts moudule. It should only be +// called once and as an alternative to InitGenesis. +func (am AppModule) InitModule(ctx sdk.Context, controllerParams controllertypes.Params, hostParams hosttypes.Params) { + am.controllerKeeper.SetParams(ctx, controllerParams) + am.hostKeeper.SetParams(ctx, hostParams) + + cap := am.hostKeeper.BindPort(ctx, types.PortID) + if err := am.hostKeeper.ClaimCapability(ctx, cap, ibchost.PortPath(types.PortID)); err != nil { + panic(fmt.Sprintf("could not claim port capability: %v", err)) + } +} + // RegisterInvariants implements the AppModule interface func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { } diff --git a/modules/apps/27-interchain-accounts/module_test.go b/modules/apps/27-interchain-accounts/module_test.go new file mode 100644 index 00000000000..de5f51ae921 --- /dev/null +++ b/modules/apps/27-interchain-accounts/module_test.go @@ -0,0 +1,74 @@ +package ica_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" + controllertypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller/types" + hosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v3/testing" + "github.com/cosmos/ibc-go/v3/testing/simapp" +) + +type InterchainAccountsTestSuite struct { + suite.Suite + + coordinator *ibctesting.Coordinator +} + +func TestICATestSuite(t *testing.T) { + suite.Run(t, new(InterchainAccountsTestSuite)) +} + +func (suite *InterchainAccountsTestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) +} + +func (suite *InterchainAccountsTestSuite) TestInitModule() { + app := simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, simapp.MakeTestEncodingConfig(), simapp.EmptyAppOptions{}) + icamodule, ok := app.GetModuleManager().Modules[types.ModuleName].(ica.AppModule) + suite.Require().True(ok) + + header := tmproto.Header{ + ChainID: "testchain", + Height: 1, + Time: suite.coordinator.CurrentTime.UTC(), + } + + ctx := app.GetBaseApp().NewContext(true, header) + + // ensure params are not set + suite.Require().Panics(func() { + app.ICAControllerKeeper.GetParams(ctx) + }) + suite.Require().Panics(func() { + app.ICAHostKeeper.GetParams(ctx) + }) + + controllerParams := controllertypes.DefaultParams() + controllerParams.ControllerEnabled = true + + hostParams := hosttypes.DefaultParams() + expAllowMessages := []string{"sdk.Msg"} + hostParams.HostEnabled = true + hostParams.AllowMessages = expAllowMessages + + suite.Require().False(app.IBCKeeper.PortKeeper.IsBound(ctx, types.PortID)) + + icamodule.InitModule(ctx, controllerParams, hostParams) + + controllerParams = app.ICAControllerKeeper.GetParams(ctx) + suite.Require().True(controllerParams.ControllerEnabled) + + hostParams = app.ICAHostKeeper.GetParams(ctx) + suite.Require().True(hostParams.HostEnabled) + suite.Require().Equal(expAllowMessages, hostParams.AllowMessages) + + suite.Require().True(app.IBCKeeper.PortKeeper.IsBound(ctx, types.PortID)) +} diff --git a/testing/simapp/app.go b/testing/simapp/app.go index a2b78e7d260..15add30faaf 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -571,6 +571,12 @@ func (app *SimApp) ModuleAccountAddrs() map[string]bool { return modAccAddrs } +// GetModuleManager returns the app module manager +// NOTE: used for testing purposes +func (app *SimApp) GetModuleManager() *module.Manager { + return app.mm +} + // LegacyAmino returns SimApp's amino codec. // // NOTE: This is solely to be used for testing purposes as it may be desirable