diff --git a/CHANGELOG.md b/CHANGELOG.md index 37438cc8b7..78b87a6287 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Added - [#1340](https://github.com/regen-network/regen-ledger/pull/1340) Add Cosmos SDK group module to app configuration +- [#1441](https://github.com/regen-network/regen-ledger/pull/1441) Add interchain accounts module #### Changed diff --git a/app/app.go b/app/app.go index 9da3e9cad9..b339a59219 100644 --- a/app/app.go +++ b/app/app.go @@ -11,6 +11,11 @@ import ( govclient "github.com/cosmos/cosmos-sdk/x/gov/client" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" + ica "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts" + icahost "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/host" + icahosttypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types" + "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "github.com/spf13/cast" @@ -87,7 +92,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - + icahostkeeper "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/host/keeper" "github.com/cosmos/ibc-go/v5/modules/apps/transfer" ibctransferkeeper "github.com/cosmos/ibc-go/v5/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v5/modules/apps/transfer/types" @@ -151,6 +156,7 @@ var ( upgradeclient.LegacyProposalHandler, upgradeclient.LegacyCancelProposalHandler, }, ), + ica.AppModuleBasic{}, ) // module account permissions @@ -158,6 +164,7 @@ var ( perms := map[string][]string{ authtypes.FeeCollectorName: nil, distrtypes.ModuleName: nil, + icatypes.ModuleName: nil, minttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, @@ -177,7 +184,7 @@ func init() { sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(2), nil)) } -// Extended ABCI application +// RegenApp extends an ABCI application. type RegenApp struct { *baseapp.BaseApp cdc *codec.LegacyAmino @@ -203,6 +210,7 @@ type RegenApp struct { UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + ICAHostKeeper *icahostkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper @@ -212,7 +220,7 @@ type RegenApp struct { // make scoped keepers public for test purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedTransferKeeper capabilitykeeper.ScopedKeeper - ScopedIBCMockKeeper capabilitykeeper.ScopedKeeper + ScopedICAHostKeeper capabilitykeeper.ScopedKeeper // the module manager ModuleManager *module.Manager @@ -248,6 +256,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest authzkeeper.StoreKey, ibchost.StoreKey, ibctransfertypes.StoreKey, group.StoreKey, ecocredit.ModuleName, data.ModuleName, + icahosttypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) @@ -271,8 +280,9 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest // add capability keeper and ScopeToModule for ibc module app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey]) - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) - scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + app.ScopedIBCKeeper = app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + app.ScopedTransferKeeper = app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + app.ScopedICAHostKeeper = app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) // Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating // their scoped modules in `NewApp` with `ScopeToModule` @@ -317,7 +327,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest // Create IBC Keeper app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, + appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, app.ScopedIBCKeeper, ) // register the proposal types @@ -333,14 +343,30 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest 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, app.ScopedTransferKeeper, ) transferModule := transfer.NewAppModule(app.TransferKeeper) transferIBCModule := transfer.NewIBCModule(app.TransferKeeper) + icaHostKeeper := icahostkeeper.NewKeeper( + appCodec, + app.keys[icahosttypes.StoreKey], + app.GetSubspace(icahosttypes.SubModuleName), + app.IBCKeeper.ChannelKeeper, + &app.IBCKeeper.PortKeeper, + app.AccountKeeper, + app.ScopedICAHostKeeper, + app.MsgServiceRouter(), + ) + app.ICAHostKeeper = &icaHostKeeper + + icaHostIBCModule := icahost.NewIBCModule(*app.ICAHostKeeper) + // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() - ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule) + ibcRouter. + AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). + AddRoute(ibctransfertypes.ModuleName, transferIBCModule) app.IBCKeeper.SetRouter(ibcRouter) // create evidence keeper with router @@ -406,6 +432,8 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest ecocreditMod, dataMod, groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + // TODO: wire up controller https://github.com/regen-network/regen-ledger/issues/1453 + ica.NewAppModule(nil, app.ICAHostKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -437,6 +465,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest // ibc modules ibchost.ModuleName, ibctransfertypes.ModuleName, + icatypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( crisistypes.ModuleName, @@ -462,6 +491,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest // ibc modules ibchost.ModuleName, ibctransfertypes.ModuleName, + icatypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are // properly initialized with tokens from genesis accounts. @@ -492,6 +522,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest // ibc modules ibctransfertypes.ModuleName, ibchost.ModuleName, + icatypes.ModuleName, ) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) app.ModuleManager.RegisterServices(app.configurator) @@ -544,9 +575,6 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest } } - app.ScopedIBCKeeper = scopedIBCKeeper - app.ScopedTransferKeeper = scopedTransferKeeper - return app } @@ -712,6 +740,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibchost.ModuleName) paramsKeeper.Subspace(ecocredit.DefaultParamspace) + paramsKeeper.Subspace(icahosttypes.SubModuleName) return paramsKeeper } diff --git a/app/stable_appconfig.go b/app/appconfig.go similarity index 55% rename from app/stable_appconfig.go rename to app/appconfig.go index aade16775a..2005530d5a 100644 --- a/app/stable_appconfig.go +++ b/app/appconfig.go @@ -1,6 +1,8 @@ package app import ( + "fmt" + "github.com/cosmos/cosmos-sdk/client" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -8,6 +10,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/group" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + ica "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts" + icacontrollertypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types" "github.com/regen-network/regen-ledger/x/data" "github.com/regen-network/regen-ledger/x/ecocredit" @@ -17,12 +23,39 @@ func (app *RegenApp) registerUpgradeHandlers() { upgradeName := "v5.0" app.UpgradeKeeper.SetUpgradeHandler(upgradeName, func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // set regen module consensus version fromVM[ecocredit.ModuleName] = 2 fromVM[data.ModuleName] = 1 app.UpgradeKeeper.SetModuleVersionMap(ctx, fromVM) + // manually set the ICA params + // the ICA module's default genesis has host and controller enabled. + // we want these to be enabled via gov param change. + + // Add Interchain Accounts host module + // set the ICS27 consensus version so InitGenesis is not run + fromVM[icatypes.ModuleName] = app.ModuleManager.Modules[icatypes.ModuleName].ConsensusVersion() + + // create ICS27 Controller submodule params, controller module not enabled. + controllerParams := icacontrollertypes.Params{ControllerEnabled: false} + + // create ICS27 Host submodule params, host module not enabled. + hostParams := icahosttypes.Params{ + HostEnabled: false, + AllowMessages: []string{}, + } + + mod, found := app.ModuleManager.Modules[icatypes.ModuleName] + if !found { + panic(fmt.Sprintf("module %s is not in the module manager", icatypes.ModuleName)) + } + + icaMod, ok := mod.(ica.AppModule) + if !ok { + panic(fmt.Sprintf("expected module %s to be type %T, got %T", icatypes.ModuleName, ica.AppModule{}, mod)) + } + icaMod.InitModule(ctx, controllerParams, hostParams) + // transfer module consensus version has been bumped to 2 return app.ModuleManager.RunMigrations(ctx, app.configurator, fromVM) }) @@ -36,6 +69,7 @@ func (app *RegenApp) registerUpgradeHandlers() { storeUpgrades := storetypes.StoreUpgrades{ Added: []string{ group.ModuleName, + icahosttypes.StoreKey, }, } diff --git a/app/simulation/app_after_import_test.go b/app/simulation/app_after_import_test.go index accde38b58..d8e919fc6c 100644 --- a/app/simulation/app_after_import_test.go +++ b/app/simulation/app_after_import_test.go @@ -45,6 +45,9 @@ func TestAppAfterImport(t *testing.T) { ) require.Equal(t, regen.AppName, app.Name()) + // TODO: remove after https://github.com/cosmos/ibc-go/issues/2151 is resolved + removeICAFromSimulation(app) + // run randomized simulation stopEarly, simParams, simErr := simulateFromSeed(t, app, config) diff --git a/app/simulation/app_import_export_test.go b/app/simulation/app_import_export_test.go index e82a1c6eb4..a4b95f8e02 100644 --- a/app/simulation/app_import_export_test.go +++ b/app/simulation/app_import_export_test.go @@ -62,6 +62,9 @@ func TestAppImportExport(t *testing.T) { ) require.Equal(t, regen.AppName, app.Name()) + // TODO: remove after https://github.com/cosmos/ibc-go/issues/2151 is resolved + removeICAFromSimulation(app) + // run randomized simulation _, simParams, simErr := simulateFromSeed(t, app, config) diff --git a/app/simulation/utils.go b/app/simulation/utils.go index 3cf002be1f..b15c2b5484 100644 --- a/app/simulation/utils.go +++ b/app/simulation/utils.go @@ -10,6 +10,7 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" + ica "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts" regen "github.com/regen-network/regen-ledger/v4/app" ) @@ -50,3 +51,21 @@ func simulateFromSeed(t *testing.T, app *regen.RegenApp, config simtypes.Config) app.AppCodec(), ) } + +// removeICAFromSimulation is a utility function that removes from genesis exporting due to a panic bug. +// +// TODO: remove after https://github.com/cosmos/ibc-go/issues/2151 is resolved +func removeICAFromSimulation(app *regen.RegenApp) { + remove := func(target string, mods []string) []string { + for i, mod := range mods { + if mod == target { + return append(mods[:i], mods[i+1:]...) + } + } + return mods + } + + icaModName := ica.AppModule{}.Name() + + app.ModuleManager.OrderExportGenesis = remove(icaModName, app.ModuleManager.OrderExportGenesis) +}