diff --git a/baseapp/abci.go b/baseapp/abci.go index b3e3f76d52..3bdef31bfb 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -630,7 +630,7 @@ func (app *BaseApp) createQueryContext(height int64, prove bool) (sdk.Context, e // branch the commit-multistore for safety ctx := sdk.NewContext( - cacheMS, app.checkState.ctx.BlockHeader(), true, app.logger, + cacheMS, app.checkState.ctx.BlockHeader(), true, app.upgradeChecker, app.logger, ).WithMinGasPrices(app.minGasPrices).WithBlockHeight(height) return ctx, nil diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 0ccdc626fa..5e54b98b7a 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -433,7 +433,7 @@ func (app *BaseApp) setCheckState(header tmproto.Header) { ms := app.cms.CacheMultiStore() app.checkState = &state{ ms: ms, - ctx: sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices).WithUpgradeChecker(app.upgradeChecker), + ctx: sdk.NewContext(ms, header, true, app.upgradeChecker, app.logger).WithMinGasPrices(app.minGasPrices), } } @@ -445,7 +445,7 @@ func (app *BaseApp) setDeliverState(header tmproto.Header) { ms := app.cms.CacheMultiStore() app.deliverState = &state{ ms: ms, - ctx: sdk.NewContext(ms, header, false, app.logger).WithUpgradeChecker(app.upgradeChecker), + ctx: sdk.NewContext(ms, header, false, app.upgradeChecker, app.logger), } } diff --git a/baseapp/block_gas_test.go b/baseapp/block_gas_test.go index a3fbe8773a..72715d3b7b 100644 --- a/baseapp/block_gas_test.go +++ b/baseapp/block_gas_test.go @@ -66,7 +66,7 @@ func TestBaseApp_BlockGas(t *testing.T) { encCfg.InterfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}, ) - app = simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, map[int64]bool{}, "", 0, encCfg, simapp.EmptyAppOptions{}, routerOpt) + app = simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, "", 0, encCfg, simapp.EmptyAppOptions{}, routerOpt) genState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.MarshalIndent(genState, "", " ") require.NoError(t, err) diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index 6489595bc8..8e836e1067 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -39,15 +39,15 @@ func (app *BaseApp) SimDeliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, // Context with current {check, deliver}State of the app used by tests. func (app *BaseApp) NewContext(isCheckTx bool, header tmproto.Header) sdk.Context { if isCheckTx { - return sdk.NewContext(app.checkState.ms, header, true, app.logger). + return sdk.NewContext(app.checkState.ms, header, true, app.upgradeChecker, app.logger). WithMinGasPrices(app.minGasPrices) } - return sdk.NewContext(app.deliverState.ms, header, false, app.logger) + return sdk.NewContext(app.deliverState.ms, header, false, app.upgradeChecker, app.logger) } func (app *BaseApp) NewUncachedContext(isCheckTx bool, header tmproto.Header) sdk.Context { - return sdk.NewContext(app.cms, header, isCheckTx, app.logger) + return sdk.NewContext(app.cms, header, isCheckTx, app.upgradeChecker, app.logger) } func (app *BaseApp) GetContextForDeliverTx(txBytes []byte) sdk.Context { diff --git a/server/export_test.go b/server/export_test.go index 0bf955a257..34374d7337 100644 --- a/server/export_test.go +++ b/server/export_test.go @@ -129,7 +129,7 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) db := dbm.NewMemDB() encCfg := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(logger, db, nil, true, map[int64]bool{}, tempDir, 0, encCfg, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(logger, db, nil, true, tempDir, 0, encCfg, simapp.EmptyAppOptions{}) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ") @@ -160,13 +160,13 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t var simApp *simapp.SimApp if height != -1 { - simApp = simapp.NewSimApp(logger, db, nil, false, map[int64]bool{}, "", 0, encCfg, appOptons) + simApp = simapp.NewSimApp(logger, db, nil, false, "", 0, encCfg, appOptons) if err := simApp.LoadHeight(height); err != nil { return types.ExportedApp{}, err } } else { - simApp = simapp.NewSimApp(logger, db, nil, true, map[int64]bool{}, "", 0, encCfg, appOptons) + simApp = simapp.NewSimApp(logger, db, nil, true, "", 0, encCfg, appOptons) } return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/server/start.go b/server/start.go index 09267253e9..b0536138a0 100644 --- a/server/start.go +++ b/server/start.go @@ -38,18 +38,17 @@ import ( const ( // Tendermint full-node start flags - flagWithTendermint = "with-tendermint" - flagAddress = "address" - flagTransport = "transport" - flagTraceStore = "trace-store" - flagCPUProfile = "cpu-profile" - FlagMinGasPrices = "minimum-gas-prices" - FlagHaltHeight = "halt-height" - FlagHaltTime = "halt-time" - FlagInterBlockCache = "inter-block-cache" - FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades" - FlagTrace = "trace" - FlagInvCheckPeriod = "inv-check-period" + flagWithTendermint = "with-tendermint" + flagAddress = "address" + flagTransport = "transport" + flagTraceStore = "trace-store" + flagCPUProfile = "cpu-profile" + FlagMinGasPrices = "minimum-gas-prices" + FlagHaltHeight = "halt-height" + FlagHaltTime = "halt-time" + FlagInterBlockCache = "inter-block-cache" + FlagTrace = "trace" + FlagInvCheckPeriod = "inv-check-period" FlagPruning = "pruning" FlagPruningKeepRecent = "pruning-keep-recent" @@ -157,7 +156,6 @@ is performed. Note, when enabled, gRPC will also be automatically enabled. cmd.Flags().String(flagTransport, "socket", "Transport protocol: socket, grpc") cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file") cmd.Flags().String(FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)") - cmd.Flags().IntSlice(FlagUnsafeSkipUpgrades, []int{}, "Skip a set of upgrade heights to continue the old binary") cmd.Flags().Uint64(FlagHaltHeight, 0, "Block height at which to gracefully halt the chain and shutdown the node") cmd.Flags().Uint64(FlagHaltTime, 0, "Minimum block time (in Unix seconds) at which to gracefully halt the chain and shutdown the node") cmd.Flags().Bool(FlagInterBlockCache, true, "Enable inter-block caching") diff --git a/simapp/app.go b/simapp/app.go index ef06bda2e9..9d848ef531 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -206,7 +206,7 @@ func init() { // NewSimApp returns a reference to an initialized SimApp. func NewSimApp( - logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool, + logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, homePath string, invCheckPeriod uint, encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *SimApp { @@ -361,20 +361,10 @@ func NewSimApp( upgradekeeper.RegisterUpgradeHandler(upgradeHandler), upgradekeeper.RegisterUpgradeInitializer(upgradeInitlizier), } - app.UpgradeKeeper, err = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, upgradeKeeperOpts...) + app.UpgradeKeeper, err = upgradekeeper.NewKeeper(keys[upgradetypes.StoreKey], appCodec, homePath, upgradeKeeperOpts...) if err != nil { panic(err) } - defer func() { - ms := app.CommitMultiStore() - ctx := sdk.NewContext(ms, tmproto.Header{ChainID: app.ChainID(), Height: app.LastBlockHeight()}, true, app.Logger()) - if loadLatest { - err = app.UpgradeKeeper.InitUpgraded(ctx) - if err != nil { - panic(err) - } - } - }() /**** Module Options ****/ @@ -500,6 +490,18 @@ func NewSimApp( if err := app.LoadLatestVersion(); err != nil { tmos.Exit(err.Error()) } + + // Execute the upgraded register, such as the newly added Msg type + // ex. + // app.GovKeeper.Router().RegisterService(...) + ms := app.CommitMultiStore() + ctx := sdk.NewContext(ms, tmproto.Header{ChainID: app.ChainID(), Height: app.LastBlockHeight()}, true, app.UpgradeKeeper.IsUpgraded, app.Logger()) + if loadLatest { + err = app.UpgradeKeeper.InitUpgraded(ctx) + if err != nil { + panic(err) + } + } } return app diff --git a/simapp/app_test.go b/simapp/app_test.go index babd35a9d5..2ed758713a 100644 --- a/simapp/app_test.go +++ b/simapp/app_test.go @@ -42,13 +42,12 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { db := dbm.NewMemDB() logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) app := NewSimappWithCustomOptions(t, false, SetupOptions{ - Logger: logger, - DB: db, - InvCheckPeriod: 0, - EncConfig: encCfg, - HomePath: DefaultNodeHome, - SkipUpgradeHeights: map[int64]bool{}, - AppOpts: EmptyAppOptions{}, + Logger: logger, + DB: db, + InvCheckPeriod: 0, + EncConfig: encCfg, + HomePath: DefaultNodeHome, + AppOpts: EmptyAppOptions{}, }) for acc := range maccPerms { @@ -63,7 +62,7 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { logger2 := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) // Making a new app object with the db, so that initchain hasn't been called - app2 := NewSimApp(logger2, db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) + app2 := NewSimApp(logger2, db, nil, true, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) _, err := app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } @@ -77,7 +76,7 @@ func TestRunMigrations(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{}) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) // Create a new baseapp and configurator for the purpose of this test. bApp := baseapp.NewBaseApp(appName, logger, db, encCfg.TxConfig.TxDecoder()) @@ -207,7 +206,7 @@ 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{}) + app := NewSimApp(logger, db, nil, true, 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 @@ -252,13 +251,12 @@ func TestUpgradeStateOnGenesis(t *testing.T) { db := dbm.NewMemDB() logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) app := NewSimappWithCustomOptions(t, false, SetupOptions{ - Logger: logger, - DB: db, - InvCheckPeriod: 0, - EncConfig: encCfg, - HomePath: DefaultNodeHome, - SkipUpgradeHeights: map[int64]bool{}, - AppOpts: EmptyAppOptions{}, + Logger: logger, + DB: db, + InvCheckPeriod: 0, + EncConfig: encCfg, + HomePath: DefaultNodeHome, + AppOpts: EmptyAppOptions{}, }) // make sure the upgrade keeper has version map in state diff --git a/simapp/sim_bench_test.go b/simapp/sim_bench_test.go index 788299dc11..f35210970e 100644 --- a/simapp/sim_bench_test.go +++ b/simapp/sim_bench_test.go @@ -30,7 +30,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { require.NoError(b, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( @@ -77,7 +77,7 @@ func BenchmarkInvariants(b *testing.B) { require.NoError(b, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( diff --git a/simapp/sim_test.go b/simapp/sim_test.go index bde9aa5859..860d5b9ada 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -70,7 +70,7 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // run randomized simulation @@ -108,7 +108,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -148,7 +148,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) var genesisState GenesisState @@ -217,7 +217,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -262,7 +262,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) newApp.InitChain(abci.RequestInitChain{ @@ -313,7 +313,7 @@ func TestAppStateDeterminism(t *testing.T) { } db := dbm.NewMemDB() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index ba594b5687..fada920dfd 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -254,11 +254,6 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a cache = store.NewCommitKVStoreCacheManager() } - skipUpgradeHeights := make(map[int64]bool) - for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { - skipUpgradeHeights[int64(h)] = true - } - pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) if err != nil { panic(err) @@ -280,7 +275,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a ) return simapp.NewSimApp( - logger, db, traceStore, true, skipUpgradeHeights, + logger, db, traceStore, true, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), a.encCfg, @@ -313,13 +308,13 @@ func (a appCreator) appExport( } if height != -1 { - simApp = simapp.NewSimApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) + simApp = simapp.NewSimApp(logger, db, traceStore, false, homePath, uint(1), a.encCfg, appOpts) if err := simApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - simApp = simapp.NewSimApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) + simApp = simapp.NewSimApp(logger, db, traceStore, true, homePath, uint(1), a.encCfg, appOpts) } return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index b043926a9d..ba9db29065 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -58,19 +58,18 @@ var DefaultConsensusParams = &abci.ConsensusParams{ // SetupOptions defines arguments that are passed into `Simapp` constructor. type SetupOptions struct { - Logger log.Logger - DB *dbm.MemDB - InvCheckPeriod uint - HomePath string - SkipUpgradeHeights map[int64]bool - EncConfig params.EncodingConfig - AppOpts types.AppOptions + Logger log.Logger + DB *dbm.MemDB + InvCheckPeriod uint + HomePath string + EncConfig params.EncodingConfig + AppOpts types.AppOptions } func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) { db := dbm.NewMemDB() encCdc := MakeTestEncodingConfig() - app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, EmptyAppOptions{}) + app := NewSimApp(log.NewNopLogger(), db, nil, true, DefaultNodeHome, invCheckPeriod, encCdc, EmptyAppOptions{}) if withGenesis { return app, NewDefaultGenesisState(encCdc.Codec) } @@ -96,7 +95,7 @@ func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptio Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), } - app := NewSimApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts) + app := NewSimApp(options.Logger, options.DB, nil, true, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts) genesisState := NewDefaultGenesisState(app.appCodec) genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) diff --git a/simapp/upgrades.go b/simapp/upgrades.go index d6bd283402..31a9060c4a 100644 --- a/simapp/upgrades.go +++ b/simapp/upgrades.go @@ -26,7 +26,7 @@ func (app SimApp) RegisterUpgradeHandlers() { panic(err) } - if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + if upgradeInfo.Name == UpgradeName { storeUpgrades := storetypes.StoreUpgrades{ Added: []string{ group.ModuleName, diff --git a/store/rootmulti/rollback_test.go b/store/rootmulti/rollback_test.go index 36fb13e636..673e442d46 100644 --- a/store/rootmulti/rollback_test.go +++ b/store/rootmulti/rollback_test.go @@ -15,13 +15,12 @@ import ( func TestRollback(t *testing.T) { db := dbm.NewMemDB() options := simapp.SetupOptions{ - Logger: log.NewNopLogger(), - DB: db, - InvCheckPeriod: 0, - EncConfig: simapp.MakeTestEncodingConfig(), - HomePath: simapp.DefaultNodeHome, - SkipUpgradeHeights: map[int64]bool{}, - AppOpts: simapp.EmptyAppOptions{}, + Logger: log.NewNopLogger(), + DB: db, + InvCheckPeriod: 0, + EncConfig: simapp.MakeTestEncodingConfig(), + HomePath: simapp.DefaultNodeHome, + AppOpts: simapp.EmptyAppOptions{}, } app := simapp.NewSimappWithCustomOptions(t, false, options) app.Commit() @@ -49,7 +48,7 @@ func TestRollback(t *testing.T) { require.Equal(t, target, app.LastBlockHeight()) // recreate app to have clean check state - app = simapp.NewSimApp(options.Logger, options.DB, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, options.InvCheckPeriod, options.EncConfig, options.AppOpts) + app = simapp.NewSimApp(options.Logger, options.DB, nil, true, simapp.DefaultNodeHome, options.InvCheckPeriod, options.EncConfig, options.AppOpts) store = app.NewContext(true, tmproto.Header{}).KVStore(app.GetKey("bank")) require.Equal(t, []byte("value5"), store.Get([]byte("key"))) diff --git a/testutil/context.go b/testutil/context.go index 1addf17c28..6a6aa24b65 100644 --- a/testutil/context.go +++ b/testutil/context.go @@ -20,7 +20,7 @@ func DefaultContext(key storetypes.StoreKey, tkey storetypes.StoreKey) sdk.Conte if err != nil { panic(err) } - ctx := sdk.NewContext(cms, tmproto.Header{}, false, log.NewNopLogger()) + ctx := sdk.NewContext(cms, tmproto.Header{}, false, nil, log.NewNopLogger()) return ctx } diff --git a/testutil/network/network.go b/testutil/network/network.go index 1d9fa9b927..5cea4706e3 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -60,7 +60,7 @@ type AppConstructor = func(val Validator) servertypes.Application func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor { return func(val Validator) servertypes.Application { return simapp.NewSimApp( - val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, + val.Ctx.Logger, dbm.NewMemDB(), nil, true, val.Ctx.Config.RootDir, 0, encodingCfg, simapp.EmptyAppOptions{}, baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), diff --git a/types/context.go b/types/context.go index 9609703d9a..2add85e60c 100644 --- a/types/context.go +++ b/types/context.go @@ -99,19 +99,20 @@ func (c Context) Err() error { } // create a new context -func NewContext(ms MultiStore, header tmproto.Header, isCheckTx bool, logger log.Logger) Context { +func NewContext(ms MultiStore, header tmproto.Header, isCheckTx bool, upgradeChecker func(Context, string) bool, logger log.Logger) Context { // https://github.com/gogo/protobuf/issues/519 header.Time = header.Time.UTC() return Context{ - baseCtx: context.Background(), - ms: ms, - header: header, - chainID: header.ChainID, - checkTx: isCheckTx, - logger: logger, - gasMeter: storetypes.NewInfiniteGasMeter(), - minGasPrice: DecCoins{}, - eventManager: NewEventManager(), + baseCtx: context.Background(), + ms: ms, + header: header, + chainID: header.ChainID, + checkTx: isCheckTx, + logger: logger, + gasMeter: storetypes.NewInfiniteGasMeter(), + minGasPrice: DecCoins{}, + eventManager: NewEventManager(), + upgradeChecker: upgradeChecker, } } @@ -248,12 +249,6 @@ func (c Context) WithTxSize(s uint64) Context { return c } -// WithUpgradeChecker returns a Context with an upgrade checker -func (c Context) WithUpgradeChecker(checker func(ctx Context, name string) bool) Context { - c.upgradeChecker = checker - return c -} - // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil diff --git a/types/context_test.go b/types/context_test.go index f5c7cadeb5..c2e9dcae52 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -99,7 +99,7 @@ func (s *contextTestSuite) TestContextWithCustom() { minGasPrices := types.DecCoins{types.NewInt64DecCoin("feetoken", 1)} headerHash := []byte("headerHash") - ctx = types.NewContext(nil, header, ischeck, logger) + ctx = types.NewContext(nil, header, ischeck, nil, logger) s.Require().Equal(header, ctx.BlockHeader()) ctx = ctx. @@ -149,7 +149,7 @@ func (s *contextTestSuite) TestContextHeader() { addr := secp256k1.GenPrivKey().PubKey().Address() proposer := types.ConsAddress(addr) - ctx = types.NewContext(nil, tmproto.Header{}, false, nil) + ctx = types.NewContext(nil, tmproto.Header{}, false, nil, nil) ctx = ctx. WithBlockHeight(height). @@ -204,7 +204,7 @@ func (s *contextTestSuite) TestContextHeaderClone() { for name, tc := range cases { tc := tc s.T().Run(name, func(t *testing.T) { - ctx := types.NewContext(nil, tc.h, false, nil) + ctx := types.NewContext(nil, tc.h, false, nil, nil) s.Require().Equal(tc.h.Height, ctx.BlockHeight()) s.Require().Equal(tc.h.Time.UTC(), ctx.BlockTime()) @@ -218,7 +218,7 @@ func (s *contextTestSuite) TestContextHeaderClone() { } func (s *contextTestSuite) TestUnwrapSDKContext() { - sdkCtx := types.NewContext(nil, tmproto.Header{}, false, nil) + sdkCtx := types.NewContext(nil, tmproto.Header{}, false, nil, nil) ctx := types.WrapSDKContext(sdkCtx) sdkCtx2 := types.UnwrapSDKContext(ctx) s.Require().Equal(sdkCtx, sdkCtx2) diff --git a/types/module/module_test.go b/types/module/module_test.go index 926a4a4ab3..b98b72ca04 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -195,7 +195,7 @@ func TestManager_InitGenesis(t *testing.T) { require.NotNil(t, mm) require.Equal(t, 2, len(mm.Modules)) - ctx := sdk.NewContext(nil, tmproto.Header{}, false, log.NewNopLogger()) + ctx := sdk.NewContext(nil, tmproto.Header{}, false, nil, log.NewNopLogger()) interfaceRegistry := types.NewInterfaceRegistry() cdc := codec.NewProtoCodec(interfaceRegistry) genesisData := map[string]json.RawMessage{"module1": json.RawMessage(`{"key": "value"}`)} diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index 2e69427c5a..b734b62bf9 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -150,7 +150,7 @@ func TestStdSignBytes(t *testing.T) { } func TestTxValidateBasic(t *testing.T) { - ctx := sdk.NewContext(nil, tmproto.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) + ctx := sdk.NewContext(nil, tmproto.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses priv1, _, addr1 := testdata.KeyTestPubAddr() diff --git a/x/auth/module_test.go b/x/auth/module_test.go index 6f527c587e..d429f3c800 100644 --- a/x/auth/module_test.go +++ b/x/auth/module_test.go @@ -17,7 +17,7 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) diff --git a/x/capability/genesis_test.go b/x/capability/genesis_test.go index 34a09960e7..87533f99f0 100644 --- a/x/capability/genesis_test.go +++ b/x/capability/genesis_test.go @@ -35,7 +35,7 @@ func (suite *CapabilityTestSuite) TestGenesis() { // and initialize app from exported genesis state above. db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - newApp := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + newApp := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) newKeeper := keeper.NewKeeper(suite.cdc, newApp.GetKey(types.StoreKey), newApp.GetMemKey(types.MemStoreKey)) newSk1 := newKeeper.ScopeToModule(banktypes.ModuleName) diff --git a/x/distribution/module_test.go b/x/distribution/module_test.go index 70e2e50ea8..ba342e5d9a 100644 --- a/x/distribution/module_test.go +++ b/x/distribution/module_test.go @@ -18,7 +18,7 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go index 26d933e6ff..a592f0d7d8 100644 --- a/x/gov/genesis_test.go +++ b/x/gov/genesis_test.go @@ -73,7 +73,7 @@ func TestImportExportQueues(t *testing.T) { } db := dbm.NewMemDB() - app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 0, simapp.MakeTestEncodingConfig(), simapp.EmptyAppOptions{}) + app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 0, simapp.MakeTestEncodingConfig(), simapp.EmptyAppOptions{}) app2.InitChain( abci.RequestInitChain{ diff --git a/x/gov/module_test.go b/x/gov/module_test.go index c43f570dba..f3fb679aa0 100644 --- a/x/gov/module_test.go +++ b/x/gov/module_test.go @@ -18,7 +18,7 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) diff --git a/x/gov/simulation/proposals_test.go b/x/gov/simulation/proposals_test.go index dcd6f3c3f0..da226d793b 100644 --- a/x/gov/simulation/proposals_test.go +++ b/x/gov/simulation/proposals_test.go @@ -18,7 +18,7 @@ func TestProposalContents(t *testing.T) { s := rand.NewSource(1) r := rand.New(s) - ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil) + ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil, nil) accounts := simtypes.RandomAccounts(r, 3) // execute ProposalContents function diff --git a/x/group/keeper/genesis_test.go b/x/group/keeper/genesis_test.go index 59a101bf3c..b5d8731bb3 100644 --- a/x/group/keeper/genesis_test.go +++ b/x/group/keeper/genesis_test.go @@ -46,7 +46,7 @@ func (s *GenesisTestSuite) SetupSuite() { checkTx := false db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) s.app = app s.sdkCtx = app.BaseApp.NewUncachedContext(checkTx, tmproto.Header{}) diff --git a/x/group/keeper/invariants_test.go b/x/group/keeper/invariants_test.go index 013f5e3a65..e815238315 100644 --- a/x/group/keeper/invariants_test.go +++ b/x/group/keeper/invariants_test.go @@ -42,7 +42,7 @@ func (s *invariantTestSuite) SetupSuite() { cms := store.NewCommitMultiStore(db) cms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) _ = cms.LoadLatestVersion() - sdkCtx := sdk.NewContext(cms, tmproto.Header{}, false, log.NewNopLogger()) + sdkCtx := sdk.NewContext(cms, tmproto.Header{}, false, nil, log.NewNopLogger()) s.ctx = sdkCtx s.cdc = cdc diff --git a/x/mint/module_test.go b/x/mint/module_test.go index ecf0a1511b..5c5df2261d 100644 --- a/x/mint/module_test.go +++ b/x/mint/module_test.go @@ -18,7 +18,7 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) diff --git a/x/params/simulation/operations_test.go b/x/params/simulation/operations_test.go index 5ed1ba8a50..a5a290c5c4 100644 --- a/x/params/simulation/operations_test.go +++ b/x/params/simulation/operations_test.go @@ -43,7 +43,7 @@ func TestSimulateParamChangeProposalContent(t *testing.T) { s := rand.NewSource(1) r := rand.New(s) - ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil) + ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil, nil) accounts := simtypes.RandomAccounts(r, 3) paramChangePool := []simtypes.ParamChange{MockParamChange{1}, MockParamChange{2}, MockParamChange{3}} diff --git a/x/params/simulation/proposals_test.go b/x/params/simulation/proposals_test.go index 2902cb08aa..70fa4fc506 100644 --- a/x/params/simulation/proposals_test.go +++ b/x/params/simulation/proposals_test.go @@ -19,7 +19,7 @@ func TestProposalContents(t *testing.T) { s := rand.NewSource(1) r := rand.New(s) - ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil) + ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil, nil) accounts := simtypes.RandomAccounts(r, 3) paramChangePool := []simtypes.ParamChange{MockParamChange{1}, MockParamChange{2}, MockParamChange{3}} diff --git a/x/params/types/subspace_test.go b/x/params/types/subspace_test.go index 2f57119d01..8da5e4b8cb 100644 --- a/x/params/types/subspace_test.go +++ b/x/params/types/subspace_test.go @@ -41,7 +41,7 @@ func (suite *SubspaceTestSuite) SetupTest() { suite.cdc = encCfg.Codec suite.amino = encCfg.Amino - suite.ctx = sdk.NewContext(ms, tmproto.Header{}, false, log.NewNopLogger()) + suite.ctx = sdk.NewContext(ms, tmproto.Header{}, false, nil, log.NewNopLogger()) suite.ss = ss.WithKeyTable(paramKeyTable()) } diff --git a/x/simulation/params_test.go b/x/simulation/params_test.go index 90eb4f22a0..7c0fd2642d 100644 --- a/x/simulation/params_test.go +++ b/x/simulation/params_test.go @@ -39,7 +39,7 @@ func TestNewWeightedProposalContent(t *testing.T) { require.Equal(t, key, pContent.AppParamsKey()) require.Equal(t, weight, pContent.DefaultWeight()) - ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil) + ctx := sdk.NewContext(nil, tmproto.Header{}, true, nil, nil) require.Equal(t, content, pContent.ContentSimulatorFn()(nil, ctx, nil)) } diff --git a/x/staking/module_test.go b/x/staking/module_test.go index 3f1e5d9168..2f2ed14989 100644 --- a/x/staking/module_test.go +++ b/x/staking/module_test.go @@ -18,7 +18,7 @@ import ( func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) genesisState := simapp.GenesisStateWithSingleValidator(t, app) stateBytes, err := tmjson.Marshal(genesisState) diff --git a/x/upgrade/abci.go b/x/upgrade/abci.go index 3930fa2f47..73ad4253cc 100644 --- a/x/upgrade/abci.go +++ b/x/upgrade/abci.go @@ -28,21 +28,11 @@ func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { if !found { return } - logger := ctx.Logger() // To make sure clear upgrade is executed at the same block executed := false for _, plan := range plans { if plan.ShouldExecute(ctx) { - // If skip upgrade has been set for current height, we clear the upgrade plan - if k.IsSkipHeight(ctx.BlockHeight()) { - skipUpgradeMsg := fmt.Sprintf("UPGRADE \"%s\" SKIPPED at %d: %s", plan.Name, plan.Height, plan.Info) - logger.Info(skipUpgradeMsg) - - // Clear the upgrade plan at current height - k.ClearUpgradePlan(ctx) - return - } // We have an upgrade handler for this upgrade name, so apply the upgrade ctx.Logger().Info(fmt.Sprintf("applying upgrade \"%s\" at %s", plan.Name, plan.DueAt())) diff --git a/x/upgrade/abci_test.go b/x/upgrade/abci_test.go index 2bde60a9fd..caf50ec12b 100644 --- a/x/upgrade/abci_test.go +++ b/x/upgrade/abci_test.go @@ -29,16 +29,15 @@ type TestSuite struct { var s TestSuite -func setupTest(t *testing.T, height int64, skip map[int64]bool) TestSuite { +func setupTest(t *testing.T, height int64) TestSuite { db := dbm.NewMemDB() app := simapp.NewSimappWithCustomOptions(t, false, simapp.SetupOptions{ - Logger: log.NewNopLogger(), - SkipUpgradeHeights: skip, - DB: db, - InvCheckPeriod: 0, - HomePath: simapp.DefaultNodeHome, - EncConfig: simapp.MakeTestEncodingConfig(), - AppOpts: simapp.EmptyAppOptions{}, + Logger: log.NewNopLogger(), + DB: db, + InvCheckPeriod: 0, + HomePath: simapp.DefaultNodeHome, + EncConfig: simapp.MakeTestEncodingConfig(), + AppOpts: simapp.EmptyAppOptions{}, }) s.keeper = app.UpgradeKeeper @@ -50,19 +49,19 @@ func setupTest(t *testing.T, height int64, skip map[int64]bool) TestSuite { } func TestRequireName(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{}) require.Error(t, err) } func TestRequireFutureBlock(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: s.ctx.BlockHeight() - 1}) require.Error(t, err) } func TestDoHeightUpgrade(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) t.Log("Verify can schedule an upgrade") err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}) @@ -72,7 +71,7 @@ func TestDoHeightUpgrade(t *testing.T) { } func TestCanOverwriteScheduleUpgrade(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) t.Log("Can overwrite plan") err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: s.ctx.BlockHeight() + 10}) require.NoError(t, err) @@ -118,13 +117,14 @@ func VerifyDoUpgradeWithCtx(t *testing.T, newCtx sdk.Context, proposalName strin } func TestHaltIfTooNew(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) t.Log("Verify that we don't panic with registered plan not in database at all") var called int s.keeper.SetUpgradeHandler("future", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) { called++ return vm, nil }) + s.keeper.SetUpgradeInitializer("future", func() error { return nil }) newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} @@ -161,7 +161,7 @@ func VerifyCleared(t *testing.T, newCtx sdk.Context) { } func TestCanClear(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) t.Log("Verify upgrade is scheduled") err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: s.ctx.BlockHeight() + 100}) require.NoError(t, err) @@ -194,149 +194,15 @@ func VerifyDone(t *testing.T, newCtx sdk.Context, name string) { require.NotZero(t, height) } -func VerifySet(t *testing.T, skipUpgradeHeights map[int64]bool) { - t.Log("Verify if the skip upgrade has been set") - - for k := range skipUpgradeHeights { - require.True(t, s.keeper.IsSkipHeight(k)) - } -} - -func TestContains(t *testing.T) { - var skipOne int64 = 11 - s := setupTest(t, 10, map[int64]bool{skipOne: true}) - - VerifySet(t, map[int64]bool{skipOne: true}) - t.Log("case where array contains the element") - require.True(t, s.keeper.IsSkipHeight(11)) - - t.Log("case where array doesn't contain the element") - require.False(t, s.keeper.IsSkipHeight(4)) -} - -func TestSkipUpgradeSkippingAll(t *testing.T) { - var ( - skipOne int64 = 11 - skipTwo int64 = 20 - ) - s := setupTest(t, 10, map[int64]bool{skipOne: true, skipTwo: true}) - - newCtx := s.ctx - - req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} - err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: skipOne}) - require.NoError(t, err) - - t.Log("Verify if skip upgrade flag clears upgrade plan in both cases") - VerifySet(t, map[int64]bool{skipOne: true, skipTwo: true}) - - newCtx = newCtx.WithBlockHeight(skipOne) - require.NotPanics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - t.Log("Verify a second proposal also is being cleared") - err = s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test2", Height: skipTwo}) - require.NoError(t, err) - - newCtx = newCtx.WithBlockHeight(skipTwo) - require.NotPanics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - // To ensure verification is being done only after both upgrades are cleared - t.Log("Verify if both proposals are cleared") - VerifyCleared(t, s.ctx) - VerifyNotDone(t, s.ctx, "test") - VerifyNotDone(t, s.ctx, "test2") -} - -func TestUpgradeSkippingOne(t *testing.T) { - var ( - skipOne int64 = 11 - skipTwo int64 = 20 - ) - s := setupTest(t, 10, map[int64]bool{skipOne: true}) - - newCtx := s.ctx - - req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} - err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: skipOne}) - require.NoError(t, err) - - t.Log("Verify if skip upgrade flag clears upgrade plan in one case and does upgrade on another") - VerifySet(t, map[int64]bool{skipOne: true}) - - // Setting block height of proposal test - newCtx = newCtx.WithBlockHeight(skipOne) - require.NotPanics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - t.Log("Verify the second proposal is not skipped") - err = s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test2", Height: skipTwo}) - require.NoError(t, err) - // Setting block height of proposal test2 - newCtx = newCtx.WithBlockHeight(skipTwo) - VerifyDoUpgradeWithCtx(t, newCtx, "test2") - - t.Log("Verify first proposal is cleared and second is done") - VerifyNotDone(t, s.ctx, "test") - VerifyDone(t, s.ctx, "test2") -} - -func TestUpgradeSkippingOnlyTwo(t *testing.T) { - var ( - skipOne int64 = 11 - skipTwo int64 = 20 - skipThree int64 = 25 - ) - s := setupTest(t, 10, map[int64]bool{skipOne: true, skipTwo: true}) - - newCtx := s.ctx - - req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} - err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: skipOne}) - require.NoError(t, err) - - t.Log("Verify if skip upgrade flag clears upgrade plan in both cases and does third upgrade") - VerifySet(t, map[int64]bool{skipOne: true, skipTwo: true}) - - // Setting block height of proposal test - newCtx = newCtx.WithBlockHeight(skipOne) - require.NotPanics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - // A new proposal with height in skipUpgradeHeights - err = s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test2", Height: skipTwo}) - require.NoError(t, err) - // Setting block height of proposal test2 - newCtx = newCtx.WithBlockHeight(skipTwo) - require.NotPanics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - t.Log("Verify a new proposal is not skipped") - err = s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test3", Height: skipThree}) - require.NoError(t, err) - newCtx = newCtx.WithBlockHeight(skipThree) - VerifyDoUpgradeWithCtx(t, newCtx, "test3") - - t.Log("Verify two proposals are cleared and third is done") - VerifyNotDone(t, s.ctx, "test") - VerifyNotDone(t, s.ctx, "test2") - VerifyDone(t, s.ctx, "test3") -} - -func TestUpgradeWithoutSkip(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) +func TestUpgrade(t *testing.T) { + s := setupTest(t, 10) newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}) s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + s.keeper.SetUpgradeInitializer("test", func() error { return nil }) require.NoError(t, err) t.Log("Verify if upgrade happens without skip upgrade") require.NotPanics(t, func() { @@ -348,7 +214,7 @@ func TestUpgradeWithoutSkip(t *testing.T) { } func TestDumpUpgradeInfoToFile(t *testing.T) { - s := setupTest(t, 10, map[int64]bool{}) + s := setupTest(t, 10) require := require.New(t) // require no error when the upgrade info file does not exist @@ -380,8 +246,7 @@ func TestDumpUpgradeInfoToFile(t *testing.T) { // TODO: add testcase to for `no upgrade handler is present for last applied upgrade`. func TestBinaryVersion(t *testing.T) { - var skipHeight int64 = 15 - s := setupTest(t, 10, map[int64]bool{skipHeight: true}) + s := setupTest(t, 10) testCases := []struct { name string diff --git a/x/upgrade/keeper/grpc_query_test.go b/x/upgrade/keeper/grpc_query_test.go index 9a0ab17f88..dd0c8eb489 100644 --- a/x/upgrade/keeper/grpc_query_test.go +++ b/x/upgrade/keeper/grpc_query_test.go @@ -117,6 +117,9 @@ func (suite *UpgradeTestSuite) TestAppliedCurrentPlan() { suite.app.UpgradeKeeper.SetUpgradeHandler(planName, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + suite.app.UpgradeKeeper.SetUpgradeInitializer(planName, func() error { + return nil + }) suite.app.UpgradeKeeper.ApplyUpgrade(suite.ctx, plan) req = &types.QueryAppliedPlanRequest{Name: planName} diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index c342783fef..1d371885f6 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -24,7 +24,6 @@ import ( type Keeper struct { homePath string // root directory of app config - skipUpgradeHeights map[int64]bool // map of heights to skip for an upgrade storeKey storetypes.StoreKey // key to access x/upgrade store cdc codec.BinaryCodec // App-wide binary codec upgradeHandlers map[string]types.UpgradeHandler // map of plan name to upgrade handler @@ -37,10 +36,9 @@ type Keeper struct { // storeKey - a store key with which to access upgrade's store // cdc - the app-wide binary codec // homePath - root directory of the application's config -func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, homePath string, opts ...KeeperOption) (Keeper, error) { +func NewKeeper(storeKey storetypes.StoreKey, cdc codec.BinaryCodec, homePath string, opts ...KeeperOption) (Keeper, error) { keeper := Keeper{ homePath: homePath, - skipUpgradeHeights: skipUpgradeHeights, storeKey: storeKey, cdc: cdc, upgradeHandlers: make(map[string]types.UpgradeHandler), @@ -326,8 +324,19 @@ func (k Keeper) HasHandler(name string) bool { // ApplyUpgrade will execute the handler associated with the Plan and mark the plan as done. func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) { - handler := k.upgradeHandlers[plan.Name] + initializer := k.upgradeInitializer[plan.Name] + if initializer == nil { + ctx.Logger().Error("missing initializer to upgrade [" + plan.Name + "]") + return + } + + err := initializer() + if err != nil { + ctx.Logger().Error("failed to init upgrade ["+plan.Name+"]", "err", err) + return + } + handler := k.upgradeHandlers[plan.Name] if handler == nil { ctx.Logger().Error("missing handler to upgrade [" + plan.Name + "]") return @@ -345,11 +354,6 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) { k.setDone(ctx, plan.Name) } -// IsSkipHeight checks if the given height is part of skipUpgradeHeights -func (k Keeper) IsSkipHeight(height int64) bool { - return k.skipUpgradeHeights[height] -} - // DumpUpgradeInfoToDisk writes upgrade information to UpgradeInfoFileName. func (k Keeper) DumpUpgradeInfoToDisk(height int64, p types.Plan) error { upgradeInfoFilePath, err := k.GetUpgradeInfoPath() @@ -421,10 +425,8 @@ func (k Keeper) IsUpgraded(ctx sdk.Context, name string) bool { if height == 0 { return false } - if height <= ctx.BlockHeight() { - return true - } - return false + + return height <= ctx.BlockHeight() } // InitUpgraded execute the upgrade initializer that the upgrade is already applied. diff --git a/x/upgrade/keeper/keeper_test.go b/x/upgrade/keeper/keeper_test.go index 0b28f88c54..ee91bf1c31 100644 --- a/x/upgrade/keeper/keeper_test.go +++ b/x/upgrade/keeper/keeper_test.go @@ -29,7 +29,7 @@ func (s *KeeperTestSuite) SetupTest() { app := simapp.Setup(s.T(), false) homeDir := filepath.Join(s.T().TempDir(), "x_upgrade_keeper_test") app.UpgradeKeeper, err = keeper.NewKeeper( // recreate keeper in order to use a custom home Path - make(map[int64]bool), app.GetKey(types.StoreKey), app.AppCodec(), homeDir, + app.GetKey(types.StoreKey), app.AppCodec(), homeDir, ) if err != nil { s.T().Fatal(err) @@ -125,6 +125,7 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { s.app.UpgradeKeeper.SetUpgradeHandler("all-good", func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + s.app.UpgradeKeeper.SetUpgradeInitializer("all-good", func() error { return nil }) s.app.UpgradeKeeper.ApplyUpgrade(s.ctx, types.Plan{ Name: "all-good", Info: "some text here", @@ -210,6 +211,7 @@ func (s *KeeperTestSuite) TestMigrations() { vm["bank"] = vm["bank"] + 1 return vm, nil }) + s.app.UpgradeKeeper.SetUpgradeInitializer("dummy", func() error { return nil }) dummyPlan := types.Plan{ Name: "dummy", Info: "some text here", @@ -233,6 +235,7 @@ func (s *KeeperTestSuite) TestLastCompletedUpgrade() { keeper.SetUpgradeHandler("test0", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + keeper.SetUpgradeInitializer("test0", func() error { return nil }) keeper.ApplyUpgrade(s.ctx, types.Plan{ Name: "test0", @@ -247,6 +250,7 @@ func (s *KeeperTestSuite) TestLastCompletedUpgrade() { keeper.SetUpgradeHandler("test1", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + keeper.SetUpgradeInitializer("test1", func() error { return nil }) newCtx := s.ctx.WithBlockHeight(15) keeper.ApplyUpgrade(newCtx, types.Plan{ @@ -270,6 +274,7 @@ func (s *KeeperTestSuite) TestLastCompletedUpgradeOrdering() { keeper.SetUpgradeHandler("test-v0.9", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + keeper.SetUpgradeInitializer("test-v0.9", func() error { return nil }) keeper.ApplyUpgrade(s.ctx, types.Plan{ Name: "test-v0.9", @@ -284,6 +289,7 @@ func (s *KeeperTestSuite) TestLastCompletedUpgradeOrdering() { keeper.SetUpgradeHandler("test-v0.10", func(_ sdk.Context, _ types.Plan, vm module.VersionMap) (module.VersionMap, error) { return vm, nil }) + keeper.SetUpgradeInitializer("test-v0.10", func() error { return nil }) newCtx := s.ctx.WithBlockHeight(15) keeper.ApplyUpgrade(newCtx, types.Plan{ diff --git a/x/upgrade/types/handler.go b/x/upgrade/types/handler.go index a1d102dedc..87bc8f3c5d 100644 --- a/x/upgrade/types/handler.go +++ b/x/upgrade/types/handler.go @@ -7,6 +7,7 @@ import ( // UpgradeHandler specifies the type of function that is called when an upgrade // is applied. +// ex. Setting a new store in Keeper // // `fromVM` is a VersionMap of moduleName to fromVersion (unit64), where // fromVersion denotes the version from which we should migrate the module, the @@ -21,10 +22,9 @@ import ( // modified inside the upgrade handler, e.g. to skip running InitGenesis or // migrations for certain modules when calling the `module.Manager#RunMigrations` // function. -// -// Please also refer to docs/core/upgrade.md for more information. type UpgradeHandler func(ctx sdk.Context, plan Plan, fromVM module.VersionMap) (module.VersionMap, error) // UpgradeInitializer specifies the function type to be called // when the app is restarted after an upgrade. +// ex. RegisterInterface for module type UpgradeInitializer func() error diff --git a/x/upgrade/types/plan_test.go b/x/upgrade/types/plan_test.go index 832dc51ee8..817d4295f2 100644 --- a/x/upgrade/types/plan_test.go +++ b/x/upgrade/types/plan_test.go @@ -139,7 +139,7 @@ func TestShouldExecute(t *testing.T) { for name, tc := range cases { tc := tc // copy to local variable for scopelint t.Run(name, func(t *testing.T) { - ctx := sdk.NewContext(nil, tmproto.Header{Height: tc.ctxHeight, Time: tc.ctxTime}, false, log.NewNopLogger()) + ctx := sdk.NewContext(nil, tmproto.Header{Height: tc.ctxHeight, Time: tc.ctxTime}, false, nil, log.NewNopLogger()) should := tc.p.ShouldExecute(ctx) assert.Equal(t, tc.expected, should) })