From ac180f102ac338d0cad48ece1221af37403ca28f Mon Sep 17 00:00:00 2001 From: yihuang Date: Wed, 15 Mar 2023 11:22:57 +0800 Subject: [PATCH 1/6] Problem: repeated tx sender recovery is wastful Solution: - only do once in ante handler, reuse the result * Update CHANGELOG.md Signed-off-by: yihuang * Update x/evm/types/msg.go Co-authored-by: mmsqe Signed-off-by: yihuang * return value * fix unit test --------- Signed-off-by: yihuang Co-authored-by: mmsqe --- CHANGELOG.md | 1 + x/evm/keeper/msg_server.go | 2 +- x/evm/keeper/state_transition.go | 7 ++-- .../keeper/state_transition_benchmark_test.go | 8 +++-- x/evm/types/msg.go | 34 ++++++++++++++++++- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0904e251f7..19a1e651e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (evm) [#1582](https://github.com/evmos/ethermint/pull/1582) Cleanup `evm` files * (evm) [#1544](https://github.com/evmos/ethermint/pull/1544) Migrate deprecated event emitting to new `TypedEvent` * (deps) [#1532](https://github.com/evmos/ethermint/pull/1532) Upgrade Go-Ethereum version to [`v1.10.26`](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.26). +* (ante) [#227](https://github.com/crypto-org-chain/ethermint/pull/227) Reuse sender recovery result. ### Bug Fixes diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 0e1b7eb6d5..0a96b48917 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -56,7 +56,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t labels = append(labels, telemetry.NewLabel("execution", "call")) } - response, err := k.ApplyTransaction(ctx, tx) + response, err := k.ApplyTransaction(ctx, msg) if err != nil { return nil, errorsmod.Wrap(err, "failed to apply transaction") } diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index ad90dba5fd..3c5ab28ff5 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -146,7 +146,7 @@ func (k Keeper) GetHashFn(ctx sdk.Context) vm.GetHashFunc { // returning. // // For relevant discussion see: https://github.com/cosmos/cosmos-sdk/discussions/9072 -func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*types.MsgEthereumTxResponse, error) { +func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { var ( bloom *big.Int bloomReceipt ethtypes.Bloom @@ -156,7 +156,8 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t if err != nil { return nil, errorsmod.Wrap(err, "failed to load evm config") } - txConfig := k.TxConfig(ctx, tx.Hash()) + ethTx := tx.AsTransaction() + txConfig := k.TxConfig(ctx, ethTx.Hash()) // get the signer according to the chain rules from the config and block height signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight())) @@ -206,7 +207,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t } receipt := ðtypes.Receipt{ - Type: tx.Type(), + Type: ethTx.Type(), PostState: nil, // TODO: intermediate state root CumulativeGasUsed: cumulativeGasUsed, Bloom: bloomReceipt, diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 77df3af9ef..68e93d1ce5 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -46,7 +46,7 @@ func newSignedEthTx( addr sdk.Address, krSigner keyring.Signer, ethSigner ethtypes.Signer, -) (*ethtypes.Transaction, error) { +) (*evmtypes.MsgEthereumTx, error) { var ethTx *ethtypes.Transaction switch txData := txData.(type) { case *ethtypes.AccessListTx: @@ -72,7 +72,11 @@ func newSignedEthTx( return nil, err } - return ethTx, nil + var msg evmtypes.MsgEthereumTx + if err := msg.FromEthereumTx(ethTx); err != nil { + return nil, err + } + return &msg, nil } func newEthMsgTx( diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index f227e36a75..eadbd4d12c 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -35,6 +35,7 @@ import ( "github.com/evmos/ethermint/types" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" ) @@ -325,7 +326,38 @@ func (msg MsgEthereumTx) AsTransaction() *ethtypes.Transaction { // AsMessage creates an Ethereum core.Message from the msg fields func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (core.Message, error) { - return msg.AsTransaction().AsMessage(signer, baseFee) + txData, err := UnpackTxData(msg.Data) + if err != nil { + return nil, err + } + + gasPrice, gasFeeCap, gasTipCap := txData.GetGasPrice(), txData.GetGasFeeCap(), txData.GetGasTipCap() + if baseFee != nil { + gasPrice = math.BigMin(gasPrice.Add(gasTipCap, baseFee), gasFeeCap) + } + var from common.Address + if len(msg.From) > 0 { + from = common.HexToAddress(msg.From) + } else { + // heavy path + from, err = signer.Sender(msg.AsTransaction()) + if err != nil { + return nil, err + } + } + ethMsg := ethtypes.NewMessage( + from, + txData.GetTo(), + txData.GetNonce(), + txData.GetValue(), + txData.GetGas(), + gasPrice, gasFeeCap, gasTipCap, + txData.GetData(), + txData.GetAccessList(), + false, + ) + + return ethMsg, nil } // GetSender extracts the sender address from the signature values using the latest signer for the given chainID. From f55dfec9def8fbeaaca42e7780347965a64789ff Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 16 Mar 2023 09:22:08 +0800 Subject: [PATCH 2/6] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a1e651e9..be1bd73a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,7 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (evm) [#1582](https://github.com/evmos/ethermint/pull/1582) Cleanup `evm` files * (evm) [#1544](https://github.com/evmos/ethermint/pull/1544) Migrate deprecated event emitting to new `TypedEvent` * (deps) [#1532](https://github.com/evmos/ethermint/pull/1532) Upgrade Go-Ethereum version to [`v1.10.26`](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.26). -* (ante) [#227](https://github.com/crypto-org-chain/ethermint/pull/227) Reuse sender recovery result. +* (ante) [#1717](https://github.com/evmos/ethermint/pull/1717) Reuse sender recovery result. ### Bug Fixes From 15f484f39b43f96571a773c96b3f2e9bef1e48b8 Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 16 Mar 2023 09:48:16 +0800 Subject: [PATCH 3/6] Update x/evm/types/msg.go --- x/evm/types/msg.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index eadbd4d12c..01de895636 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -337,6 +337,7 @@ func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (co } var from common.Address if len(msg.From) > 0 { + // user can't set arbitrary value in `From` field in transaction, the SigVerify ante handler will verify the signature and recover the sender address and populate the `From` field, so the other code can use it directly when available. from = common.HexToAddress(msg.From) } else { // heavy path From b59de37871c37eabd4be8f0ce2e4174a302a0315 Mon Sep 17 00:00:00 2001 From: Freddy Caceres Date: Fri, 24 Mar 2023 14:23:50 -0700 Subject: [PATCH 4/6] rename parameter --- x/evm/keeper/state_transition.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index 3c5ab28ff5..5327052a37 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -146,7 +146,7 @@ func (k Keeper) GetHashFn(ctx sdk.Context) vm.GetHashFunc { // returning. // // For relevant discussion see: https://github.com/cosmos/cosmos-sdk/discussions/9072 -func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { +func (k *Keeper) ApplyTransaction(ctx sdk.Context, msgEth *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { var ( bloom *big.Int bloomReceipt ethtypes.Bloom @@ -156,12 +156,12 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *types.MsgEthereumTx) (*ty if err != nil { return nil, errorsmod.Wrap(err, "failed to load evm config") } - ethTx := tx.AsTransaction() + ethTx := msgEth.AsTransaction() txConfig := k.TxConfig(ctx, ethTx.Hash()) // get the signer according to the chain rules from the config and block height signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight())) - msg, err := tx.AsMessage(signer, cfg.BaseFee) + msg, err := msgEth.AsMessage(signer, cfg.BaseFee) if err != nil { return nil, errorsmod.Wrap(err, "failed to return ethereum transaction as core message") } From a5ca2c9106e5d62d9fdefe077feea38984ec1d68 Mon Sep 17 00:00:00 2001 From: Freddy Caceres Date: Fri, 24 Mar 2023 14:27:43 -0700 Subject: [PATCH 5/6] separate lines --- x/evm/types/msg.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index 01de895636..f908da81b8 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -337,7 +337,10 @@ func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (co } var from common.Address if len(msg.From) > 0 { - // user can't set arbitrary value in `From` field in transaction, the SigVerify ante handler will verify the signature and recover the sender address and populate the `From` field, so the other code can use it directly when available. + // user can't set arbitrary value in `From` field in transaction, + // the SigVerify ante handler will verify the signature and recover + // the sender address and populate the `From` field, so the other code can + // use it directly when available. from = common.HexToAddress(msg.From) } else { // heavy path From bfa7d6aae3724fa276478361c0b6d109ba696315 Mon Sep 17 00:00:00 2001 From: Freddy Caceres Date: Fri, 24 Mar 2023 14:28:34 -0700 Subject: [PATCH 6/6] run gofumpt --- x/evm/types/msg.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index f908da81b8..71164c593e 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -340,7 +340,7 @@ func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (co // user can't set arbitrary value in `From` field in transaction, // the SigVerify ante handler will verify the signature and recover // the sender address and populate the `From` field, so the other code can - // use it directly when available. + // use it directly when available. from = common.HexToAddress(msg.From) } else { // heavy path