From 6437be01a2f88345960c60e380d5c6748d4ab348 Mon Sep 17 00:00:00 2001 From: Freddy Li Date: Tue, 20 Apr 2021 15:19:12 -0400 Subject: [PATCH] merge pr #775 (#868) * merge pr #775 * unit test fix Co-authored-by: Freddy Li --- CHANGELOG.md | 15 ++++++++------- importer/importer_test.go | 3 ++- x/evm/keeper/abci.go | 6 ++++-- x/evm/keeper/msg_server.go | 3 +-- x/evm/keeper/statedb.go | 4 ++-- x/evm/keeper/statedb_test.go | 5 +++-- x/evm/types/state_transition.go | 32 ++++---------------------------- x/evm/types/statedb.go | 10 +++++++--- x/evm/types/statedb_test.go | 5 +++-- 9 files changed, 34 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7ac98f63..05d0455b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (faucet) [\#678](https://github.com/cosmos/ethermint/pull/678) Faucet module has been removed in favor of client libraries such as [`@cosmjs/faucet`](https://github.com/cosmos/cosmjs/tree/master/packages/faucet). * (evm) [\#670](https://github.com/cosmos/ethermint/pull/670) Migrate types to the ones defined by the protobuf messages, which are required for the stargate release. +* (eth) [\#845](https://github.com/cosmos/ethermint/pull/845) The `eth` namespace must be included in the list of API's as default to run the rpc server without error. ### Bug Fixes @@ -48,6 +49,13 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (api) [\#687](https://github.com/cosmos/ethermint/issues/687) Returns error for a transaction with an incorrect nonce. * (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. * (evm) [\#672](https://github.com/cosmos/ethermint/issues/672) Fix panic of `wrong Block.Header.AppHash` when restart a node with snapshot. +* (evm) [\#775](https://github.com/cosmos/ethermint/issues/775) MisUse of headHash as blockHash when create EVM context. +* (evm) [\#799](https://github.com/cosmos/ethermint/issues/799) Fix wrong precision in calculation of gas fee. +* (evm) [\#767](https://github.com/cosmos/ethermint/issues/767) Fix error of timeout when using Truffle to deploy contract. +* (evm) [\#751](https://github.com/cosmos/ethermint/issues/751) Fix misused method to calculate block hash in evm related function. +* (evm) [\#721](https://github.com/cosmos/ethermint/issues/721) Fix mismatch block hash in rpc response when use eth.getBlock. +* (evm) [\#730](https://github.com/cosmos/ethermint/issues/730) Fix 'EIP2028' not open when Istanbul version has been enabled. +* (app) [\#749](https://github.com/cosmos/ethermint/issues/749) Fix panic in `AnteHandler` when gas price larger than 100000 ### Features * (api) [\#825](https://github.com/cosmos/ethermint/pull/825) Individually enable the api modules. Will be implemented in the latest version of ethermint with the upcoming stargate upgrade. @@ -141,7 +149,6 @@ corresponding Ethereum API namespace: ### API Breaking -* (eth) [\#845](https://github.com/cosmos/ethermint/pull/845) The `eth` namespace must be included in the list of API's as default to run the rpc server without error. * (types) [\#503](https://github.com/cosmos/ethermint/pull/503) The `types.DenomDefault` constant for `"aphoton"` has been renamed to `types.AttoPhoton`. ### Improvements @@ -209,12 +216,6 @@ corresponding Ethereum API namespace: ### Bug Fixes -* (evm) [\#799](https://github.com/cosmos/ethermint/issues/799) Fix wrong precision in calculation of gas fee. -* (evm) [\#767](https://github.com/cosmos/ethermint/issues/767) Fix error of timeout when using Truffle to deploy contract. -* (evm) [\#751](https://github.com/cosmos/ethermint/issues/751) Fix misused method to calculate block hash in evm related function. -* (evm) [\#721](https://github.com/cosmos/ethermint/issues/721) Fix mismatch block hash in rpc response when use eth.getBlock. -* (evm) [\#730](https://github.com/cosmos/ethermint/issues/730) Fix 'EIP2028' not open when Istanbul version has been enabled. -* (app) [\#749](https://github.com/cosmos/ethermint/issues/749) Fix panic in `AnteHandler` when gas price larger than 100000 * (rpc) [\#305](https://github.com/cosmos/ethermint/issues/305) Update `eth_getTransactionCount` to check for account existence before getting sequence and return 0 as the nonce if it doesn't exist. * (`x/evm`) [\#319](https://github.com/cosmos/ethermint/pull/319) Fix `SetBlockHash` that was setting the incorrect height during `BeginBlock`. * (`x/evm`) [\#176](https://github.com/cosmos/ethermint/issues/176) Updated Web3 transaction hash from using RLP hash. Now all transaction hashes exposed are amino hashes: diff --git a/importer/importer_test.go b/importer/importer_test.go index 26dad474f..abf222e70 100644 --- a/importer/importer_test.go +++ b/importer/importer_test.go @@ -264,7 +264,8 @@ func TestImportBlocks(t *testing.T) { } for i, tx := range block.Transactions() { - evmKeeper.Prepare(ctx, tx.Hash(), block.Hash(), i) + evmKeeper.Prepare(ctx, tx.Hash(), i) + evmKeeper.CommitStateDB.SetBlockHash(block.Hash()) receipt, gas, err := applyTransaction( chainConfig, chainContext, nil, gp, evmKeeper, header, tx, usedGas, vmConfig, diff --git a/x/evm/keeper/abci.go b/x/evm/keeper/abci.go index 4ff63646b..af1a9da57 100644 --- a/x/evm/keeper/abci.go +++ b/x/evm/keeper/abci.go @@ -22,10 +22,12 @@ func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) // Set the hash -> height and height -> hash mapping. - hash := req.Header.LastBlockId.GetHash() + currentHash := req.Hash height := req.Header.GetHeight() - 1 - k.SetHeightHash(ctx, uint64(height), common.BytesToHash(hash)) + k.SetHeightHash(ctx, uint64(height), common.BytesToHash(currentHash)) + //k.SetBlockHash(ctx, currentHash, height) + k.CommitStateDB.SetBlockHash(common.BytesToHash(currentHash)) // reset counters that are used on CommitStateDB.Prepare k.Bloom = big.NewInt(0) diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 3c9497295..5fd8a3613 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -66,8 +66,7 @@ func (k Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*ty // other nodes, causing a consensus error if !st.Simulate { // Prepare db for logs - blockHash := types.HashFromContext(ctx) - k.Prepare(ctx, ethHash, blockHash, k.TxCount) + k.CommitStateDB.Prepare(ethHash, k.TxCount) k.TxCount++ } diff --git a/x/evm/keeper/statedb.go b/x/evm/keeper/statedb.go index 272404b64..1deb6455c 100644 --- a/x/evm/keeper/statedb.go +++ b/x/evm/keeper/statedb.go @@ -225,8 +225,8 @@ func (k *Keeper) Reset(ctx sdk.Context, root ethcmn.Hash) error { } // Prepare calls CommitStateDB.Prepare using the passed in context -func (k *Keeper) Prepare(ctx sdk.Context, thash, bhash ethcmn.Hash, txi int) { - k.CommitStateDB.WithContext(ctx).Prepare(thash, bhash, txi) +func (k *Keeper) Prepare(ctx sdk.Context, thash ethcmn.Hash, txi int) { + k.CommitStateDB.WithContext(ctx).Prepare(thash, txi) } // CreateAccount calls CommitStateDB.CreateAccount using the passed in context diff --git a/x/evm/keeper/statedb_test.go b/x/evm/keeper/statedb_test.go index b317f235f..66c9baeb1 100644 --- a/x/evm/keeper/statedb_test.go +++ b/x/evm/keeper/statedb_test.go @@ -18,7 +18,7 @@ import ( func (suite *KeeperTestSuite) TestBloomFilter() { // Prepare db for logs tHash := ethcmn.BytesToHash([]byte{0x1}) - suite.app.EvmKeeper.Prepare(suite.ctx, tHash, ethcmn.Hash{}, 0) + suite.app.EvmKeeper.Prepare(suite.ctx, tHash, 0) contractAddress := ethcmn.BigToAddress(big.NewInt(1)) log := ethtypes.Log{Address: contractAddress, Topics: []ethcmn.Hash{}} @@ -360,7 +360,8 @@ func (suite *KeeperTestSuite) TestSuiteDB_Prepare() { bhash := ethcmn.BytesToHash([]byte("bhash")) txi := 1 - suite.app.EvmKeeper.Prepare(suite.ctx, thash, bhash, txi) + suite.app.EvmKeeper.Prepare(suite.ctx, thash, txi) + suite.app.EvmKeeper.CommitStateDB.SetBlockHash(bhash) suite.Require().Equal(txi, suite.app.EvmKeeper.TxIndex(suite.ctx)) suite.Require().Equal(bhash, suite.app.EvmKeeper.BlockHash(suite.ctx)) diff --git a/x/evm/types/state_transition.go b/x/evm/types/state_transition.go index e8bba1c6a..0a3ee7598 100644 --- a/x/evm/types/state_transition.go +++ b/x/evm/types/state_transition.go @@ -4,8 +4,6 @@ import ( "errors" "math/big" - tmtypes "github.com/tendermint/tendermint/types" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -49,16 +47,16 @@ type ExecutionResult struct { } // GetHashFn implements vm.GetHashFunc for Ethermint. It handles 3 cases: -// 1. The requested height matches the current height from context (and thus same epoch number) +// 1. The requested height matches the current height (and thus same epoch number) // 2. The requested height is from an previous height from the same chain epoch // 3. The requested height is from a height greater than the latest one func GetHashFn(ctx sdk.Context, csdb *CommitStateDB) vm.GetHashFunc { return func(height uint64) common.Hash { switch { case ctx.BlockHeight() == int64(height): - // Case 1: The requested height matches the one from the context so we can retrieve the header - // hash directly from the context. - return HashFromContext(ctx) + // Case 1: The requested height matches the one from the CommitStateDB so we can retrieve the block + // hash directly from the CommitStateDB. + return csdb.bhash case ctx.BlockHeight() > int64(height): // Case 2: if the chain is not the current height we need to retrieve the hash from the store for the @@ -252,25 +250,3 @@ func (st StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (*Ex return executionResult, nil } - -// HashFromContext returns the Ethereum Header hash from the context's Tendermint -// block header. -func HashFromContext(ctx sdk.Context) common.Hash { - // cast the ABCI header to tendermint Header type - protoHeader := ctx.BlockHeader() - tmHeader, err := tmtypes.HeaderFromProto(&protoHeader) - if err != nil { - return common.Hash{} - } - - // get the Tendermint block hash from the current header - tmBlockHash := tmHeader.Hash() - - // NOTE: if the validator set hash is missing the hash will be returned as nil, - // so we need to check for this case to prevent a panic when calling Bytes() - if tmBlockHash == nil { - return common.Hash{} - } - - return common.BytesToHash(tmBlockHash.Bytes()) -} diff --git a/x/evm/types/statedb.go b/x/evm/types/statedb.go index 5967e3dcf..d26c815f5 100644 --- a/x/evm/types/statedb.go +++ b/x/evm/types/statedb.go @@ -169,6 +169,11 @@ func (csdb *CommitStateDB) SetCode(addr ethcmn.Address, code []byte) { so.SetCode(ethcrypto.Keccak256Hash(code), code) } +// SetBlockHash sets the block hash +func (csdb *CommitStateDB) SetBlockHash(hash ethcmn.Hash) { + csdb.bhash = hash +} + // ---------------------------------------------------------------------------- // Transaction logs // Required for upgrade logic or ease of querying. @@ -731,11 +736,10 @@ func (csdb *CommitStateDB) clearJournalAndRefund() { csdb.refund = 0 } -// Prepare sets the current transaction hash and index and block hash which is +// Prepare sets the current transaction hash and index which is // used when the EVM emits new state logs. -func (csdb *CommitStateDB) Prepare(thash, bhash ethcmn.Hash, txi int) { +func (csdb *CommitStateDB) Prepare(thash ethcmn.Hash, txi int) { csdb.thash = thash - csdb.bhash = bhash csdb.txIndex = txi } diff --git a/x/evm/types/statedb_test.go b/x/evm/types/statedb_test.go index 8293a3b52..c4bc85207 100644 --- a/x/evm/types/statedb_test.go +++ b/x/evm/types/statedb_test.go @@ -84,7 +84,7 @@ func (suite *StateDBTestSuite) TestGetHeightHash() { func (suite *StateDBTestSuite) TestBloomFilter() { // Prepare db for logs tHash := ethcmn.BytesToHash([]byte{0x1}) - suite.stateDB.Prepare(tHash, ethcmn.Hash{}, 0) + suite.stateDB.Prepare(tHash, 0) contractAddress := ethcmn.BigToAddress(big.NewInt(1)) log := ethtypes.Log{ Address: contractAddress, @@ -433,7 +433,8 @@ func (suite *StateDBTestSuite) TestSuiteDB_Prepare() { bhash := ethcmn.BytesToHash([]byte("bhash")) txi := 1 - suite.stateDB.Prepare(thash, bhash, txi) + suite.stateDB.Prepare(thash, txi) + suite.stateDB.SetBlockHash(bhash) suite.Require().Equal(txi, suite.stateDB.TxIndex()) suite.Require().Equal(bhash, suite.stateDB.BlockHash())