From 30a144b3d04a393ec225fc8a9256082c133b9644 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Fri, 2 Apr 2021 17:41:35 +0200 Subject: [PATCH] InitGenesis in migrations when fromVersion==0 (#9007) * InitGenesis in migrations when fromVersion==0 * Add test * Fix test * Fix comment * cdc=>codec * Don't break Configurator * Remove method * Add comments * Add more comments * Update types/module/module.go Co-authored-by: technicallyty <48813565+technicallyty@users.noreply.github.com> * Update types/module/module.go Co-authored-by: technicallyty <48813565+technicallyty@users.noreply.github.com> * Update types/module/module.go Co-authored-by: technicallyty <48813565+technicallyty@users.noreply.github.com> Co-authored-by: technicallyty <48813565+technicallyty@users.noreply.github.com> --- app.go | 18 +----------------- app_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/app.go b/app.go index 7d62f2e8445d..e3771e2fc105 100644 --- a/app.go +++ b/app.go @@ -339,7 +339,7 @@ func NewSimApp( app.mm.RegisterInvariants(&app.CrisisKeeper) app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) - app.configurator = module.NewConfigurator(app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) app.mm.RegisterServices(app.configurator) // add test gRPC service for testing gRPC queries in isolation @@ -536,22 +536,6 @@ func (app *SimApp) RegisterTendermintService(clientCtx client.Context) { tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) } -// RunMigrations performs in-place store migrations for all modules. This -// function MUST be only called by x/upgrade UpgradeHandler. -// -// `migrateFromVersions` is a map of moduleName to fromVersion (unit64), where -// fromVersion denotes the version from which we should migrate the module, the -// target version being the module's latest ConsensusVersion. -// -// Example: -// cfg := module.NewConfigurator(...) -// app.UpgradeKeeper.SetUpgradeHandler("store-migration", func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) { -// return app.RunMigrations(ctx, vm) -// }) -func (app *SimApp) RunMigrations(ctx sdk.Context, migrateFromVersions module.VersionMap) (module.VersionMap, error) { - return app.mm.RunMigrations(ctx, app.configurator, migrateFromVersions) -} - // RegisterSwaggerAPI registers swagger route with API Server func RegisterSwaggerAPI(ctx client.Context, rtr *mux.Router) { statikFS, err := fs.New() diff --git a/app_test.go b/app_test.go index c4aa9885b5d8..2f9c5e2c3d19 100644 --- a/app_test.go +++ b/app_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" @@ -12,11 +13,13 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/tests/mocks" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/vesting" "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/cosmos/cosmos-sdk/x/bank" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/capability" "github.com/cosmos/cosmos-sdk/x/crisis" @@ -80,7 +83,7 @@ func TestRunMigrations(t *testing.T) { bApp.SetCommitMultiStoreTracer(nil) bApp.SetInterfaceRegistry(encCfg.InterfaceRegistry) app.BaseApp = bApp - app.configurator = module.NewConfigurator(app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) // We register all modules on the Configurator, except x/bank. x/bank will // serve as the test subject on which we run the migration tests. @@ -160,8 +163,8 @@ func TestRunMigrations(t *testing.T) { // Run migrations only for bank. That's why we put the initial // version for bank as 1, and for all other modules, we put as // their latest ConsensusVersion. - _, err = app.RunMigrations( - app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}), + _, err = app.mm.RunMigrations( + app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}), app.configurator, module.VersionMap{ "bank": 1, "auth": auth.AppModule{}.ConsensusVersion(), @@ -185,12 +188,58 @@ func TestRunMigrations(t *testing.T) { require.EqualError(t, err, tc.expRunErrMsg) } else { require.NoError(t, err) + // Make sure bank's migration is called. require.Equal(t, tc.expCalled, called) } }) } } +func TestInitGenesisOnMigration(t *testing.T) { + db := dbm.NewMemDB() + encCfg := MakeTestEncodingConfig() + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) + ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + + // Create a mock module. This module will serve as the new module we're + // adding during a migration. + mockCtrl := gomock.NewController(t) + t.Cleanup(mockCtrl.Finish) + mockModule := mocks.NewMockAppModule(mockCtrl) + mockDefaultGenesis := json.RawMessage(`{"key": "value"}`) + mockModule.EXPECT().DefaultGenesis(gomock.Eq(app.appCodec)).Times(1).Return(mockDefaultGenesis) + mockModule.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(app.appCodec), gomock.Eq(mockDefaultGenesis)).Times(1).Return(nil) + + app.mm.Modules["mock"] = mockModule + + // Run migrations only for "mock" module. That's why we put the initial + // version for bank as 0 (to run its InitGenesis), and for all other + // modules, we put their latest ConsensusVersion to skip migrations. + _, err := app.mm.RunMigrations(ctx, app.configurator, + module.VersionMap{ + "mock": 0, + "bank": bank.AppModule{}.ConsensusVersion(), + "auth": auth.AppModule{}.ConsensusVersion(), + "authz": authz.AppModule{}.ConsensusVersion(), + "staking": staking.AppModule{}.ConsensusVersion(), + "mint": mint.AppModule{}.ConsensusVersion(), + "distribution": distribution.AppModule{}.ConsensusVersion(), + "slashing": slashing.AppModule{}.ConsensusVersion(), + "gov": gov.AppModule{}.ConsensusVersion(), + "params": params.AppModule{}.ConsensusVersion(), + "upgrade": upgrade.AppModule{}.ConsensusVersion(), + "vesting": vesting.AppModule{}.ConsensusVersion(), + "feegrant": feegrant.AppModule{}.ConsensusVersion(), + "evidence": evidence.AppModule{}.ConsensusVersion(), + "crisis": crisis.AppModule{}.ConsensusVersion(), + "genutil": genutil.AppModule{}.ConsensusVersion(), + "capability": capability.AppModule{}.ConsensusVersion(), + }, + ) + require.NoError(t, err) +} + func TestUpgradeStateOnGenesis(t *testing.T) { encCfg := MakeTestEncodingConfig() db := dbm.NewMemDB()