From 1f50c8fe20e2c8679fefc936de3ac0610d2f21e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:29:31 +0200 Subject: [PATCH] refactor: remove ics27 channel capability migration introduced in v6 (#7053) * refactor: remove ics27 migration introduced in v6 * changelog * fix: remove v6 upgrade handler from simapp * chore: remove V5 upgrade handler const --- CHANGELOG.md | 1 + docs/docs/05-migrations/14-v9-to-v10.md | 5 +- .../controller/keeper/migrations.go | 33 --- .../controller/keeper/migrations_test.go | 72 ------- .../controller/migrations/v6/migrations.go | 78 ------- .../migrations/v6/migrations_test.go | 199 ------------------ modules/apps/27-interchain-accounts/module.go | 4 - simapp/upgrades/upgrades.go | 27 --- 8 files changed, 5 insertions(+), 414 deletions(-) delete mode 100644 modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go delete mode 100644 modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a75108ce43..39fa4c483eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,6 +92,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (core/04-channel) [\#6902](https://github.com/cosmos/ibc-go/pull/6902) Add channel version to core application callbacks. * (core/03-connection, core/02-client) [\#6937](https://github.com/cosmos/ibc-go/pull/6937) Remove 'ConsensusHost' interface, also removing self client and consensus state validation in the connection handshake. * (core/24-host) [\#6882](https://github.com/cosmos/ibc-go/issues/6882) All functions ending in `Path` have been removed from 24-host in favour of their sybling functions ending in `Key`. +* (apps/27-interchain-accounts) [\#7053](https://github.com/cosmos/ibc-go/pull/7053) Remove ICS27 channel capability migration introduced in v6. ### State Machine Breaking diff --git a/docs/docs/05-migrations/14-v9-to-v10.md b/docs/docs/05-migrations/14-v9-to-v10.md index 5cbe3610be4..f35f15de487 100644 --- a/docs/docs/05-migrations/14-v9-to-v10.md +++ b/docs/docs/05-migrations/14-v9-to-v10.md @@ -6,6 +6,7 @@ There are four sections based on the four potential user groups of this document - [Chains](#chains) - [IBC Apps](#ibc-apps) + - [ICS27 - Interchain Accounts](#ics27---interchain-accounts) - [Relayers](#relayers) - [IBC Light Clients](#ibc-light-clients) @@ -17,7 +18,9 @@ There are four sections based on the four potential user groups of this document ## IBC Apps -- No relevant changes were made in this release. +### ICS27 - Interchain Accounts + +The channel capability migration introduced in v6 has been removed. Chains must upgrade from v6 or higher. ## Relayers diff --git a/modules/apps/27-interchain-accounts/controller/keeper/migrations.go b/modules/apps/27-interchain-accounts/controller/keeper/migrations.go index ac6e2fb41c7..ad69ceacc65 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/migrations.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/migrations.go @@ -1,16 +1,9 @@ package keeper import ( - "fmt" - - errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" controllertypes "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/types" - host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ) // Migrator is a struct for handling in-place store migrations. @@ -25,32 +18,6 @@ func NewMigrator(k *Keeper) Migrator { } } -// AssertChannelCapabilityMigrations checks that all channel capabilities generated using the interchain accounts controller port prefix -// are owned by the controller submodule and ibc. -func (m Migrator) AssertChannelCapabilityMigrations(ctx sdk.Context) error { - if m.keeper != nil { - filteredChannels := m.keeper.channelKeeper.GetAllChannelsWithPortPrefix(ctx, icatypes.ControllerPortPrefix) - for _, ch := range filteredChannels { - name := host.ChannelCapabilityPath(ch.PortId, ch.ChannelId) - capability, found := m.keeper.scopedKeeper.GetCapability(ctx, name) - if !found { - m.keeper.Logger(ctx).Error(fmt.Sprintf("failed to find capability: %s", name)) - return errorsmod.Wrapf(capabilitytypes.ErrCapabilityNotFound, "failed to find capability: %s", name) - } - - isAuthenticated := m.keeper.scopedKeeper.AuthenticateCapability(ctx, capability, name) - if !isAuthenticated { - m.keeper.Logger(ctx).Error(fmt.Sprintf("expected capability owner: %s", controllertypes.SubModuleName)) - return errorsmod.Wrapf(capabilitytypes.ErrCapabilityNotOwned, "expected capability owner: %s", controllertypes.SubModuleName) - } - - m.keeper.SetMiddlewareEnabled(ctx, ch.PortId, ch.ConnectionHops[0]) - m.keeper.Logger(ctx).Info("successfully migrated channel capability", "name", name) - } - } - return nil -} - // MigrateParams migrates the controller submodule's parameters from the x/params to self store. func (m Migrator) MigrateParams(ctx sdk.Context) error { if m.keeper != nil { diff --git a/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go b/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go index 45562f1788e..f4d25b37ea7 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go @@ -5,80 +5,8 @@ import ( icacontrollerkeeper "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/keeper" icacontrollertypes "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v9/testing" ) -func (suite *KeeperTestSuite) TestAssertChannelCapabilityMigrations() { - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "success", - func() {}, - true, - }, - { - "channel with different port is filtered out", - func() { - portIDWithOutPrefix := ibctesting.MockPort - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portIDWithOutPrefix, ibctesting.FirstChannelID, channeltypes.Channel{ - ConnectionHops: []string{ibctesting.FirstConnectionID}, - }) - }, - true, - }, - { - "capability not found", - func() { - portIDWithPrefix := fmt.Sprintf("%s%s", icatypes.ControllerPortPrefix, "port-without-capability") - suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portIDWithPrefix, ibctesting.FirstChannelID, channeltypes.Channel{ - ConnectionHops: []string{ibctesting.FirstConnectionID}, - }) - }, - false, - }, - } - - for _, ordering := range []channeltypes.Order{channeltypes.UNORDERED, channeltypes.ORDERED} { - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - - path := NewICAPath(suite.chainA, suite.chainB, ordering) - path.SetupConnections() - - err := SetupICAPath(path, ibctesting.TestAccAddress) - suite.Require().NoError(err) - - tc.malleate() - - migrator := icacontrollerkeeper.NewMigrator(&suite.chainA.GetSimApp().ICAControllerKeeper) - err = migrator.AssertChannelCapabilityMigrations(suite.chainA.GetContext()) - - if tc.expPass { - suite.Require().NoError(err) - - isMiddlewareEnabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareEnabled( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, - path.EndpointA.ConnectionID, - ) - - suite.Require().True(isMiddlewareEnabled) - } else { - suite.Require().Error(err) - } - }) - } - } -} - func (suite *KeeperTestSuite) TestMigratorMigrateParams() { testCases := []struct { msg string diff --git a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go deleted file mode 100644 index 8e2a4f29fb9..00000000000 --- a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go +++ /dev/null @@ -1,78 +0,0 @@ -package v6 - -import ( - "cosmossdk.io/store/prefix" - storetypes "cosmossdk.io/store/types" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - - capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" - capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - controllertypes "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/types" - ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported" -) - -// MigrateICS27ChannelCapability performs a search on a prefix store using the provided store key and module name. -// It retrieves the associated channel capability index and reassigns ownership to the ICS27 controller submodule. -func MigrateICS27ChannelCapability( - ctx sdk.Context, - cdc codec.BinaryCodec, - capabilityStoreKey storetypes.StoreKey, - capabilityKeeper *capabilitykeeper.Keeper, - module string, // the name of the scoped keeper for the underlying app module -) error { - // construct a prefix store using the x/capability index prefix: index->capability owners - prefixStore := prefix.NewStore(ctx.KVStore(capabilityStoreKey), capabilitytypes.KeyPrefixIndexCapability) - iterator := storetypes.KVStorePrefixIterator(prefixStore, nil) - defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) - - for ; iterator.Valid(); iterator.Next() { - // unmarshal the capability index value and set of owners - index := capabilitytypes.IndexFromKey(iterator.Key()) - - var owners capabilitytypes.CapabilityOwners - cdc.MustUnmarshal(iterator.Value(), &owners) - - if !hasIBCOwner(owners.GetOwners()) { - continue - } - - for _, owner := range owners.GetOwners() { - if owner.Module == module { - // remove the owner from the set - owners.Remove(owner) - - // reassign the owner module to icacontroller - owner.Module = controllertypes.SubModuleName - - // add the controller submodule to the set of owners - if err := owners.Set(owner); err != nil { - return err - } - - // set the new owners for the current capability index - capabilityKeeper.SetOwners(ctx, index, owners) - } - } - } - - // initialise the x/capability memstore - capabilityKeeper.InitMemStore(ctx) - - return nil -} - -func hasIBCOwner(owners []capabilitytypes.Owner) bool { - if len(owners) != 2 { - return false - } - - for _, owner := range owners { - if owner.Module == ibcexported.ModuleName { - return true - } - } - - return false -} diff --git a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go deleted file mode 100644 index e7f79b81fed..00000000000 --- a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package v6_test - -import ( - "testing" - - testifysuite "github.com/stretchr/testify/suite" - - sdk "github.com/cosmos/cosmos-sdk/types" - - capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/migrations/v6" - "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v9/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v9/testing" - ibcmock "github.com/cosmos/ibc-go/v9/testing/mock" -) - -type MigrationsTestSuite struct { - testifysuite.Suite - - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain - - coordinator *ibctesting.Coordinator - path *ibctesting.Path -} - -func (suite *MigrationsTestSuite) SetupTest() { - version := icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) - - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) - - suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) - suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) - - suite.path = ibctesting.NewPath(suite.chainA, suite.chainB) - suite.path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID - suite.path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID - suite.path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED - suite.path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED - suite.path.EndpointA.ChannelConfig.Version = version - suite.path.EndpointB.ChannelConfig.Version = version -} - -func (suite *MigrationsTestSuite) SetupPath() error { - if err := suite.RegisterInterchainAccount(suite.path.EndpointA, ibctesting.TestAccAddress); err != nil { - return err - } - - if err := suite.path.EndpointB.ChanOpenTry(); err != nil { - return err - } - - if err := suite.path.EndpointA.ChanOpenAck(); err != nil { - return err - } - - return suite.path.EndpointB.ChanOpenConfirm() -} - -func (*MigrationsTestSuite) RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { - portID, err := icatypes.NewControllerPortID(owner) - if err != nil { - return err - } - - channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version, channeltypes.ORDERED); err != nil { - return err - } - - // commit state changes for proof verification - endpoint.Chain.NextBlock() - - // update port/channel ids - endpoint.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) - endpoint.ChannelConfig.PortID = portID - - return nil -} - -func TestKeeperTestSuite(t *testing.T) { - testifysuite.Run(t, new(MigrationsTestSuite)) -} - -func (suite *MigrationsTestSuite) TestMigrateICS27ChannelCapability() { - suite.SetupTest() - suite.path.SetupConnections() - - err := suite.SetupPath() - suite.Require().NoError(err) - - // create additional capabilities to cover edge cases - suite.CreateMockCapabilities() - - // create and claim a new capability with ibc/mock for "channel-1" - // note: suite.SetupPath() now claims the channel capability using icacontroller for "channel-0" - capName := host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, channeltypes.FormatChannelIdentifier(1)) - - capability, err := suite.chainA.GetSimApp().ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), capName) - suite.Require().NoError(err) - - err = suite.chainA.GetSimApp().ScopedICAMockKeeper.ClaimCapability(suite.chainA.GetContext(), capability, capName) - suite.Require().NoError(err) - - // assert the capability is owned by the mock module - capability, found := suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(suite.chainA.GetContext(), capName) - suite.Require().NotNil(capability) - suite.Require().True(found) - - isAuthenticated := suite.chainA.GetSimApp().ScopedICAMockKeeper.AuthenticateCapability(suite.chainA.GetContext(), capability, capName) - suite.Require().True(isAuthenticated) - - capability, found = suite.chainA.GetSimApp().ScopedICAControllerKeeper.GetCapability(suite.chainA.GetContext(), capName) - suite.Require().Nil(capability) - suite.Require().False(found) - - suite.ResetMemStore() // empty the x/capability in-memory store - - err = v6.MigrateICS27ChannelCapability( - suite.chainA.GetContext(), - suite.chainA.Codec, - suite.chainA.GetSimApp().GetKey(capabilitytypes.StoreKey), - suite.chainA.GetSimApp().CapabilityKeeper, - ibcmock.ModuleName+types.SubModuleName, - ) - - suite.Require().NoError(err) - - // assert the capability is now owned by the ICS27 controller submodule - capability, found = suite.chainA.GetSimApp().ScopedICAControllerKeeper.GetCapability(suite.chainA.GetContext(), capName) - suite.Require().NotNil(capability) - suite.Require().True(found) - - isAuthenticated = suite.chainA.GetSimApp().ScopedICAControllerKeeper.AuthenticateCapability(suite.chainA.GetContext(), capability, capName) - suite.Require().True(isAuthenticated) - - capability, found = suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(suite.chainA.GetContext(), capName) - suite.Require().Nil(capability) - suite.Require().False(found) - - // ensure channel capability for "channel-0" is still owned by the controller - capName = host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID) - capability, found = suite.chainA.GetSimApp().ScopedICAControllerKeeper.GetCapability(suite.chainA.GetContext(), capName) - suite.Require().NotNil(capability) - suite.Require().True(found) - - isAuthenticated = suite.chainA.GetSimApp().ScopedICAControllerKeeper.AuthenticateCapability(suite.chainA.GetContext(), capability, capName) - suite.Require().True(isAuthenticated) - - suite.AssertMockCapabiltiesUnchanged() -} - -// CreateMockCapabilities creates an additional two capabilities used for testing purposes: -// 1. A capability with a single owner -// 2. A capability with two owners, neither of which is "ibc" -func (suite *MigrationsTestSuite) CreateMockCapabilities() { - capability, err := suite.chainA.GetSimApp().ScopedIBCMockKeeper.NewCapability(suite.chainA.GetContext(), "mock_one") - suite.Require().NoError(err) - suite.Require().NotNil(capability) - - capability, err = suite.chainA.GetSimApp().ScopedICAMockKeeper.NewCapability(suite.chainA.GetContext(), "mock_two") - suite.Require().NoError(err) - suite.Require().NotNil(capability) - - err = suite.chainA.GetSimApp().ScopedIBCMockKeeper.ClaimCapability(suite.chainA.GetContext(), capability, "mock_two") - suite.Require().NoError(err) -} - -// AssertMockCapabiltiesUnchanged authenticates the mock capabilities created at the start of the test to ensure they remain unchanged -func (suite *MigrationsTestSuite) AssertMockCapabiltiesUnchanged() { - capability, found := suite.chainA.GetSimApp().ScopedIBCMockKeeper.GetCapability(suite.chainA.GetContext(), "mock_one") - suite.Require().True(found) - suite.Require().NotNil(capability) - - capability, found = suite.chainA.GetSimApp().ScopedIBCMockKeeper.GetCapability(suite.chainA.GetContext(), "mock_two") - suite.Require().True(found) - suite.Require().NotNil(capability) - - isAuthenticated := suite.chainA.GetSimApp().ScopedICAMockKeeper.AuthenticateCapability(suite.chainA.GetContext(), capability, "mock_two") - suite.Require().True(isAuthenticated) -} - -// ResetMemstore removes all existing fwd and rev capability kv pairs and deletes `KeyMemInitialised` from the x/capability memstore. -// This effectively mocks a new chain binary being started. Migration code is run against persisted state only and allows the memstore to be reinitialised. -func (suite *MigrationsTestSuite) ResetMemStore() { - memStore := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetMemKey(capabilitytypes.MemStoreKey)) - memStore.Delete(capabilitytypes.KeyMemInitialized) - - iterator := memStore.Iterator(nil, nil) - defer sdk.LogDeferred(suite.chainA.GetContext().Logger(), func() error { return iterator.Close() }) - - for ; iterator.Valid(); iterator.Next() { - memStore.Delete(iterator.Key()) - } -} diff --git a/modules/apps/27-interchain-accounts/module.go b/modules/apps/27-interchain-accounts/module.go index ede08eaa29d..293be361b51 100644 --- a/modules/apps/27-interchain-accounts/module.go +++ b/modules/apps/27-interchain-accounts/module.go @@ -134,10 +134,6 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { } controllerMigrator := controllerkeeper.NewMigrator(am.controllerKeeper) - if err := cfg.RegisterMigration(types.ModuleName, 1, controllerMigrator.AssertChannelCapabilityMigrations); err != nil { - panic(fmt.Errorf("failed to migrate interchainaccounts app from version 1 to 2 (channel capabilities owned by controller submodule check): %v", err)) - } - hostMigrator := hostkeeper.NewMigrator(am.hostKeeper) if err := cfg.RegisterMigration(types.ModuleName, 2, func(ctx sdk.Context) error { if err := hostMigrator.MigrateParams(ctx); err != nil { diff --git a/simapp/upgrades/upgrades.go b/simapp/upgrades/upgrades.go index ddc14baaf8f..863318da367 100644 --- a/simapp/upgrades/upgrades.go +++ b/simapp/upgrades/upgrades.go @@ -3,7 +3,6 @@ package upgrades import ( "context" - storetypes "cosmossdk.io/store/types" upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -14,18 +13,12 @@ import ( paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" - capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" - "github.com/cosmos/ibc-go/v9/modules/apps/27-interchain-accounts/controller/migrations/v6" clientkeeper "github.com/cosmos/ibc-go/v9/modules/core/02-client/keeper" "github.com/cosmos/ibc-go/v9/modules/core/exported" ibctmmigrations "github.com/cosmos/ibc-go/v9/modules/light-clients/07-tendermint/migrations" ) const ( - // V5 defines the upgrade name for the ibc-go/v5 upgrade handler. - V5 = "normal upgrade" // NOTE: keeping as "normal upgrade" as existing tags depend on this name - // V6 defines the upgrade name for the ibc-go/v6 upgrade handler. - V6 = "v6" // V7 defines the upgrade name for the ibc-go/v7 upgrade handler. V7 = "v7" // V7_1 defines the upgrade name for the ibc-go/v7.1 upgrade handler. @@ -49,26 +42,6 @@ func CreateDefaultUpgradeHandler( } } -// CreateV6UpgradeHandler creates an upgrade handler for the ibc-go/v6 SimApp upgrade. -// NOTE: The v6.MigrateICS27ChannelCapabiliity function can be omitted if chains do not yet implement an ICS27 controller module -func CreateV6UpgradeHandler( - mm *module.Manager, - configurator module.Configurator, - cdc codec.BinaryCodec, - capabilityStoreKey *storetypes.KVStoreKey, - capabilityKeeper *capabilitykeeper.Keeper, - moduleName string, -) upgradetypes.UpgradeHandler { - return func(ctx context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - if err := v6.MigrateICS27ChannelCapability(sdkCtx, cdc, capabilityStoreKey, capabilityKeeper, moduleName); err != nil { - return nil, err - } - - return mm.RunMigrations(ctx, configurator, vm) - } -} - // CreateV7UpgradeHandler creates an upgrade handler for the ibc-go/v7 SimApp upgrade. func CreateV7UpgradeHandler( mm *module.Manager,