From ffbb20765562a2a8cffbba7e4305654f2dc316a9 Mon Sep 17 00:00:00 2001 From: KamiD <44460798+KamiD@users.noreply.github.com> Date: Thu, 7 Jan 2021 19:55:01 +0800 Subject: [PATCH] fix panic when start a node with snapshot (#673) * fix panic when start a node with snapshot * change the return value of evm.NewKeeper to a pointer, roll back the before change * add changelog * fix importer test --- CHANGELOG.md | 1 + app/ethermint.go | 2 +- importer/importer_test.go | 8 ++++---- x/evm/genesis_test.go | 8 ++++---- x/evm/handler.go | 6 +++--- x/evm/handler_test.go | 2 +- x/evm/keeper/keeper.go | 4 ++-- x/evm/keeper/keeper_test.go | 2 +- x/evm/module.go | 12 ++++++------ 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b1222d55..34db7f958 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* (evm) [\#672](https://github.com/cosmos/ethermint/issues/672) Fix panic of `wrong Block.Header.AppHash` when restart a node with snapshot * (evm) [\#674](https://github.com/cosmos/ethermint/issues/674) Reset all cache after account data has been committed in `EndBlock` to make sure every node state consistent ## [v0.4.0] - 2020-12-15 diff --git a/app/ethermint.go b/app/ethermint.go index 4b793e383..b9dfba57b 100644 --- a/app/ethermint.go +++ b/app/ethermint.go @@ -125,7 +125,7 @@ type EthermintApp struct { UpgradeKeeper upgrade.Keeper ParamsKeeper params.Keeper EvidenceKeeper evidence.Keeper - EvmKeeper evm.Keeper + EvmKeeper *evm.Keeper FaucetKeeper faucet.Keeper // the module manager diff --git a/importer/importer_test.go b/importer/importer_test.go index 27f4e2e4b..005f893de 100644 --- a/importer/importer_test.go +++ b/importer/importer_test.go @@ -99,7 +99,7 @@ func trapSignals() { } // nolint: interfacer -func createAndTestGenesis(t *testing.T, cms sdk.CommitMultiStore, ak auth.AccountKeeper, evmKeeper evm.Keeper) { +func createAndTestGenesis(t *testing.T, cms sdk.CommitMultiStore, ak auth.AccountKeeper, evmKeeper *evm.Keeper) { genBlock := ethcore.DefaultGenesisBlock() ms := cms.CacheMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, logger) @@ -285,7 +285,7 @@ func TestImportBlocks(t *testing.T) { // reward. The total reward consists of the static block reward and rewards for // included uncles. The coinbase of each uncle block is also rewarded. func accumulateRewards( - config *ethparams.ChainConfig, evmKeeper evm.Keeper, + config *ethparams.ChainConfig, evmKeeper *evm.Keeper, header *ethtypes.Header, uncles []*ethtypes.Header, ) { @@ -318,7 +318,7 @@ func accumulateRewards( // Code is pulled from go-ethereum 1.9 because the StateDB interface does not include the // SetBalance function implementation // Ref: https://github.com/ethereum/go-ethereum/blob/52f2461774bcb8cdd310f86b4bc501df5b783852/consensus/misc/dao.go#L74 -func applyDAOHardFork(evmKeeper evm.Keeper) { +func applyDAOHardFork(evmKeeper *evm.Keeper) { // Retrieve the contract to refund balances into if !evmKeeper.CommitStateDB.Exist(ethparams.DAORefundContract) { evmKeeper.CommitStateDB.CreateAccount(ethparams.DAORefundContract) @@ -339,7 +339,7 @@ func applyDAOHardFork(evmKeeper evm.Keeper) { // Ref: https://github.com/ethereum/go-ethereum/blob/52f2461774bcb8cdd310f86b4bc501df5b783852/core/state_processor.go#L88 func applyTransaction( config *ethparams.ChainConfig, bc ethcore.ChainContext, author *ethcmn.Address, - gp *ethcore.GasPool, evmKeeper evm.Keeper, header *ethtypes.Header, + gp *ethcore.GasPool, evmKeeper *evm.Keeper, header *ethtypes.Header, tx *ethtypes.Transaction, usedGas *uint64, cfg ethvm.Config, ) (*ethtypes.Receipt, uint64, error) { msg, err := tx.AsMessage(ethtypes.MakeSigner(config, header.Number)) diff --git a/x/evm/genesis_test.go b/x/evm/genesis_test.go index 01b99f205..5d593d436 100644 --- a/x/evm/genesis_test.go +++ b/x/evm/genesis_test.go @@ -16,10 +16,10 @@ import ( func (suite *EvmTestSuite) TestExportImport() { var genState types.GenesisState suite.Require().NotPanics(func() { - genState = evm.ExportGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper) + genState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper) }) - _ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, genState) + _ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper, genState) } func (suite *EvmTestSuite) TestInitGenesis() { @@ -102,13 +102,13 @@ func (suite *EvmTestSuite) TestInitGenesis() { if tc.expPanic { suite.Require().Panics( func() { - _ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, tc.genState) + _ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper, tc.genState) }, ) } else { suite.Require().NotPanics( func() { - _ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, tc.genState) + _ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, suite.app.AccountKeeper, tc.genState) }, ) } diff --git a/x/evm/handler.go b/x/evm/handler.go index 82d271899..d1347f4a1 100644 --- a/x/evm/handler.go +++ b/x/evm/handler.go @@ -13,7 +13,7 @@ import ( ) // NewHandler returns a handler for Ethermint type messages. -func NewHandler(k Keeper) sdk.Handler { +func NewHandler(k *Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { @@ -28,7 +28,7 @@ func NewHandler(k Keeper) sdk.Handler { } // handleMsgEthereumTx handles an Ethereum specific tx -func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*sdk.Result, error) { +func handleMsgEthereumTx(ctx sdk.Context, k *Keeper, msg types.MsgEthereumTx) (*sdk.Result, error) { // execute state transition res, err := k.EthereumTx(ctx, msg) if err != nil { @@ -42,7 +42,7 @@ func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*s } // handleMsgEthermint handles an sdk.StdTx for an Ethereum state transition -func handleMsgEthermint(ctx sdk.Context, k Keeper, msg types.MsgEthermint) (*sdk.Result, error) { +func handleMsgEthermint(ctx sdk.Context, k *Keeper, msg types.MsgEthermint) (*sdk.Result, error) { // parse the chainID from a string to a base-10 integer chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) if err != nil { diff --git a/x/evm/handler_test.go b/x/evm/handler_test.go index 3aefc98a5..93ce59f59 100644 --- a/x/evm/handler_test.go +++ b/x/evm/handler_test.go @@ -46,7 +46,7 @@ func (suite *EvmTestSuite) SetupTest() { suite.app = app.Setup(checkTx) suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()}) suite.handler = evm.NewHandler(suite.app.EvmKeeper) - suite.querier = keeper.NewQuerier(suite.app.EvmKeeper) + suite.querier = keeper.NewQuerier(*suite.app.EvmKeeper) suite.codec = codec.New() } diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 43763c51a..b61df17e1 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -44,14 +44,14 @@ type Keeper struct { // NewKeeper generates new evm module keeper func NewKeeper( cdc *codec.Codec, storeKey sdk.StoreKey, paramSpace params.Subspace, ak types.AccountKeeper, -) Keeper { +) *Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) } // NOTE: we pass in the parameter space to the CommitStateDB in order to use custom denominations for the EVM operations - return Keeper{ + return &Keeper{ cdc: cdc, storeKey: storeKey, accountKeeper: ak, diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index df7796e0c..27ee25902 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -43,7 +43,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.app = app.Setup(checkTx) suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()}) - suite.querier = keeper.NewQuerier(suite.app.EvmKeeper) + suite.querier = keeper.NewQuerier(*suite.app.EvmKeeper) suite.address = ethcmn.HexToAddress(addrHex) balance := sdk.NewCoins(ethermint.NewPhotonCoin(sdk.ZeroInt())) diff --git a/x/evm/module.go b/x/evm/module.go index 34b882944..c3eea99e8 100644 --- a/x/evm/module.go +++ b/x/evm/module.go @@ -69,12 +69,12 @@ func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { // AppModule implements an application module for the evm module. type AppModule struct { AppModuleBasic - keeper Keeper + keeper *Keeper ak types.AccountKeeper } // NewAppModule creates a new AppModule Object -func NewAppModule(k Keeper, ak types.AccountKeeper) AppModule { +func NewAppModule(k *Keeper, ak types.AccountKeeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, keeper: k, @@ -89,7 +89,7 @@ func (AppModule) Name() string { // RegisterInvariants interface for registering invariants func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { - keeper.RegisterInvariants(ir, am.keeper) + keeper.RegisterInvariants(ir, *am.keeper) } // Route specifies path for transactions @@ -109,7 +109,7 @@ func (am AppModule) QuerierRoute() string { // NewQuerierHandler sets up new querier handler for module func (am AppModule) NewQuerierHandler() sdk.Querier { - return keeper.NewQuerier(am.keeper) + return keeper.NewQuerier(*am.keeper) } // BeginBlock function for module at start of each block @@ -126,11 +126,11 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { var genesisState types.GenesisState types.ModuleCdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, am.ak, genesisState) + return InitGenesis(ctx, *am.keeper, am.ak, genesisState) } // ExportGenesis exports the genesis state to be used by daemon func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper, am.ak) + gs := ExportGenesis(ctx, *am.keeper, am.ak) return types.ModuleCdc.MustMarshalJSON(gs) }