From 8e9320e8f226b3c70f15d7b9a330581e1279df7c Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 22 Sep 2023 23:42:40 +0800 Subject: [PATCH] Problem: sender address verification is not decoupled from execution (#358) * Problem: sender address verification is not decoupled from execution WIP: #355 Solution: - to decouple sender address verification from execution, we must first enforce user setting the From field in the msg * changelog * fix GetSenderLegacy * cleanup * fix unit tests * reduce overhead of debug log * lazy init the btree in cache store because many stores are never touched * fix mutation --- CHANGELOG.md | 1 + app/ante/ante_test.go | 66 ++++--- app/ante/authz_test.go | 10 +- app/ante/eth.go | 6 +- app/ante/eth_test.go | 18 +- app/ante/handler_options.go | 2 +- app/ante/setup.go | 5 - app/ante/setup_test.go | 4 +- app/ante/signverify_test.go | 12 +- app/ante/sigs_test.go | 2 +- app/ante/sigverify.go | 24 +-- app/ante/utils_test.go | 3 +- encoding/config_test.go | 2 +- indexer/kv_indexer_test.go | 2 +- proto/ethermint/evm/v1/tx.proto | 5 +- rpc/backend/backend_suite_test.go | 18 +- rpc/backend/call_tx.go | 2 +- rpc/backend/call_tx_test.go | 2 + rpc/backend/tracing_test.go | 4 +- rpc/backend/tx_info.go | 2 +- rpc/backend/utils.go | 2 +- store/cachekv/internal/btree.go | 34 +++- store/cachekv/internal/memiterator.go | 4 + store/cachemulti/store.go | 2 +- x/evm/client/cli/tx.go | 16 +- x/evm/handler_test.go | 4 +- x/evm/keeper/benchmark_test.go | 4 +- x/evm/keeper/integration_test.go | 4 +- x/evm/keeper/keeper_test.go | 6 +- x/evm/keeper/msg_server.go | 7 +- x/evm/keeper/state_transition.go | 4 +- .../keeper/state_transition_benchmark_test.go | 8 +- x/evm/keeper/state_transition_test.go | 5 +- x/evm/keeper/statedb.go | 29 ++- x/evm/keeper/statedb_test.go | 8 +- x/evm/keeper/utils_test.go | 6 +- x/evm/simulation/operations.go | 2 +- x/evm/types/msg.go | 108 +++++----- x/evm/types/msg_test.go | 52 +++-- x/evm/types/tx.pb.go | 185 +++++++++++------- x/evm/types/tx_args.go | 5 +- x/evm/types/utils.go | 9 + x/feemarket/keeper/integration_test.go | 3 +- 43 files changed, 390 insertions(+), 307 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03322b6a66..e789af389a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ - (eip712) [#1746](https://github.com/evmos/ethermint/pull/1746) Add EIP712 support for multiple messages and schemas - (feemarket) [#1790](https://github.com/evmos/ethermint/pull/1790) Raise error when get invalid consensus params - (deps) [#1782](https://github.com/evmos/ethermint/pull/1782) Bump Cosmos-SDK to v0.47.3 and ibc-go to v7.1.0. +- (ante) [#358](https://github.com/crypto-org-chain/ethermint/pull/358) enforce user setting the From address in MsgEthereumTx ### Bug Fixes diff --git a/app/ante/ante_test.go b/app/ante/ante_test.go index 6f6f59e970..cd2740f2bd 100644 --- a/app/ante/ante_test.go +++ b/app/ante/ante_test.go @@ -95,7 +95,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -116,7 +116,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -137,7 +137,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -159,7 +159,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -181,7 +181,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -203,7 +203,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -224,7 +224,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -234,7 +234,7 @@ func (suite AnteTestSuite) TestAnteHandler() { "fail - CheckTx (cosmos tx is not valid)", func() sdk.Tx { signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) // bigger than MaxGasWanted @@ -246,7 +246,7 @@ func (suite AnteTestSuite) TestAnteHandler() { "fail - CheckTx (memo too long)", func() sdk.Tx { signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) txBuilder.SetMemo(strings.Repeat("*", 257)) @@ -257,7 +257,7 @@ func (suite AnteTestSuite) TestAnteHandler() { "fail - CheckTx (ExtensionOptionsEthereumTx not set)", func() sdk.Tx { signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false, true) return txBuilder.GetTx() @@ -271,7 +271,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress()) suite.Require().NoError(err) signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, true) return tx @@ -283,7 +283,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress()) suite.Require().NoError(err) signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) txBuilder.SetMemo("memo for cosmos tx not allowed") @@ -296,7 +296,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress()) suite.Require().NoError(err) signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) txBuilder.SetTimeoutHeight(10) @@ -309,7 +309,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress()) suite.Require().NoError(err) signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) @@ -329,7 +329,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nonce, err := suite.app.AccountKeeper.GetSequence(suite.ctx, acc.GetAddress()) suite.Require().NoError(err) signedTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) @@ -589,10 +589,12 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - msg.From = addr.Hex() + msg.From = addr.Bytes() tx := suite.CreateTestTx(msg, privKey, 1, false) msg = tx.GetMsgs()[0].(*evmtypes.MsgEthereumTx) - msg.From = addr.Hex() + msg.From = addr.Bytes() + // arbitrary modify + msg.From[0] = msg.From[0] + 1 return tx }, true, false, false, }, @@ -906,7 +908,7 @@ func (suite AnteTestSuite) TestAnteHandler() { nil, nil, ) - ethTx.From = addr.Hex() + ethTx.From = addr.Bytes() msg := authz.NewMsgExec( sdk.AccAddress(privKey.PubKey().Address()), @@ -976,7 +978,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -998,7 +1000,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -1020,7 +1022,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -1043,7 +1045,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -1066,7 +1068,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -1089,7 +1091,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -1112,7 +1114,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -1135,7 +1137,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) // bigger than MaxGasWanted @@ -1160,7 +1162,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) txBuilder.SetMemo(strings.Repeat("*", 257)) @@ -1183,7 +1185,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() { nil, &types.AccessList{}, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -1242,7 +1244,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithParams() { nil, &types.AccessList{}, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -1264,7 +1266,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithParams() { nil, &types.AccessList{}, ) - signedContractTx.From = addr.Hex() + signedContractTx.From = addr.Bytes() tx := suite.CreateTestTx(signedContractTx, privKey, 1, false) return tx @@ -1287,7 +1289,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithParams() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx @@ -1310,7 +1312,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithParams() { nil, &types.AccessList{}, ) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() tx := suite.CreateTestTx(signedTx, privKey, 1, false) return tx diff --git a/app/ante/authz_test.go b/app/ante/authz_test.go index 462ed7d326..1696299415 100644 --- a/app/ante/authz_test.go +++ b/app/ante/authz_test.go @@ -226,6 +226,8 @@ func (suite *AnteTestSuite) TestRejectDeliverMsgsInAuthz() { _, testAddresses, err := generatePrivKeyAddressPairs(10) suite.Require().NoError(err) + fromAddr := []byte{0, 0} + testcases := []struct { name string msgs []sdk.Msg @@ -237,7 +239,7 @@ func (suite *AnteTestSuite) TestRejectDeliverMsgsInAuthz() { msgs: []sdk.Msg{ newGenericMsgGrant( testAddresses, - sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{}), + sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{From: fromAddr}), ), }, expectedCode: sdkerrors.ErrUnauthorized.ABCICode(), @@ -257,7 +259,7 @@ func (suite *AnteTestSuite) TestRejectDeliverMsgsInAuthz() { msgs: []sdk.Msg{ newGenericMsgGrant( testAddresses, - sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{}), + sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{From: fromAddr}), ), }, expectedCode: sdkerrors.ErrUnauthorized.ABCICode(), @@ -270,7 +272,7 @@ func (suite *AnteTestSuite) TestRejectDeliverMsgsInAuthz() { testAddresses[1], []sdk.Msg{ createMsgSend(testAddresses), - &evmtypes.MsgEthereumTx{}, + &evmtypes.MsgEthereumTx{From: fromAddr}, }, ), }, @@ -283,7 +285,7 @@ func (suite *AnteTestSuite) TestRejectDeliverMsgsInAuthz() { testAddresses[1], 2, []sdk.Msg{ - &evmtypes.MsgEthereumTx{}, + &evmtypes.MsgEthereumTx{From: fromAddr}, }, ), }, diff --git a/app/ante/eth.go b/app/ante/eth.go index 0d9cbd93f5..a67133336a 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -30,7 +30,6 @@ import ( evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" ) @@ -195,7 +194,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula return ctx, errorsmod.Wrapf(err, "failed to verify the fees") } - err = egcd.evmKeeper.DeductTxCostsFromUserBalance(ctx, fees, common.HexToAddress(msgEthTx.From)) + err = egcd.evmKeeper.DeductTxCostsFromUserBalance(ctx, fees, common.BytesToAddress(msgEthTx.From)) if err != nil { return ctx, errorsmod.Wrapf(err, "failed to deduct transaction costs from user balance") } @@ -263,14 +262,13 @@ func NewCanTransferDecorator(evmKeeper EVMKeeper, baseFee *big.Int, evmParams *e // AnteHandle creates an EVM from the message and calls the BlockContext CanTransfer function to // see if the address can execute the transaction. func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - signer := ethtypes.MakeSigner(ctd.ethCfg, big.NewInt(ctx.BlockHeight())) for _, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) if !ok { return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - coreMsg, err := msgEthTx.AsMessage(signer, ctd.baseFee) + coreMsg, err := msgEthTx.AsMessage(ctd.baseFee) if err != nil { return ctx, errorsmod.Wrapf( err, diff --git a/app/ante/eth_test.go b/app/ante/eth_test.go index f7a5ad80fe..529be3ef74 100644 --- a/app/ante/eth_test.go +++ b/app/ante/eth_test.go @@ -24,7 +24,7 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() { addr := tests.GenerateAddress() tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - tx.From = addr.Hex() + tx.From = addr.Bytes() var vmdb *statedb.StateDB @@ -111,7 +111,7 @@ func (suite AnteTestSuite) TestEthNonceVerificationDecorator() { addr := tests.GenerateAddress() tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - tx.From = addr.Hex() + tx.From = addr.Bytes() testCases := []struct { name string @@ -172,7 +172,7 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() { txGasLimit := uint64(1000) tx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), txGasLimit, big.NewInt(1), nil, nil, nil, nil) - tx.From = addr.Hex() + tx.From = addr.Bytes() suite.Require().Equal(int64(1000000000), baseFee.Int64()) @@ -180,7 +180,7 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() { tx2GasLimit := uint64(1000000) tx2 := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), tx2GasLimit, gasPrice, nil, nil, nil, ðtypes.AccessList{{Address: addr, StorageKeys: nil}}) - tx2.From = addr.Hex() + tx2.From = addr.Bytes() tx2Priority := int64(1) tx3GasLimit := ethermint.BlockGasLimit(suite.ctx) + uint64(1) @@ -191,7 +191,7 @@ func (suite AnteTestSuite) TestEthGasConsumeDecorator() { new(big.Int).Add(baseFee, big.NewInt(evmtypes.DefaultPriorityReduction.Int64()*2)), // gasFeeCap evmtypes.DefaultPriorityReduction.BigInt(), // gasTipCap nil, ðtypes.AccessList{{Address: addr, StorageKeys: nil}}) - dynamicFeeTx.From = addr.Hex() + dynamicFeeTx.From = addr.Bytes() dynamicFeeTxPriority := int64(1) var vmdb *statedb.StateDB @@ -353,7 +353,7 @@ func (suite AnteTestSuite) TestCanTransferDecorator() { ðtypes.AccessList{}, ) - tx.From = addr.Hex() + tx.From = addr.Bytes() err := tx.Sign(suite.ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) @@ -412,18 +412,18 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() { addr, privKey := tests.NewAddrKey() contract := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 0, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - contract.From = addr.Hex() + contract.From = addr.Bytes() err := contract.Sign(suite.ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) to := tests.GenerateAddress() tx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 0, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - tx.From = addr.Hex() + tx.From = addr.Bytes() err = tx.Sign(suite.ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) tx2 := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - tx2.From = addr.Hex() + tx2.From = addr.Bytes() err = tx2.Sign(suite.ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 34adc07690..47e8cb62ae 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -79,7 +79,7 @@ func newEthAnteHandler(ctx sdk.Context, options HandlerOptions, extra ...sdk.Ant NewEthMempoolFeeDecorator(evmDenom, baseFee), // Check eth effective gas price against minimal-gas-prices NewEthMinGasPriceDecorator(options.FeeMarketKeeper, baseFee), // Check eth effective gas price against the global MinGasPrice NewEthValidateBasicDecorator(&evmParams, baseFee), - NewEthSigVerificationDecorator(ethCfg), + NewEthSigVerificationDecorator(chainID), NewEthAccountVerificationDecorator(options.AccountKeeper, options.EvmKeeper, evmDenom), NewCanTransferDecorator(options.EvmKeeper, baseFee, &evmParams, ethCfg), NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted, ethCfg, evmDenom, baseFee), diff --git a/app/ante/setup.go b/app/ante/setup.go index 0085b747c8..19169d424f 100644 --- a/app/ante/setup.go +++ b/app/ante/setup.go @@ -163,11 +163,6 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - // Validate `From` field - if msgEthTx.From != "" { - return ctx, errorsmod.Wrapf(errortypes.ErrInvalidRequest, "invalid From %s, expect empty string", msgEthTx.From) - } - txGasLimit += msgEthTx.GetGas() txData, err := evmtypes.UnpackTxData(msgEthTx.Data) diff --git a/app/ante/setup_test.go b/app/ante/setup_test.go index f828b4367f..db17b13c59 100644 --- a/app/ante/setup_test.go +++ b/app/ante/setup_test.go @@ -47,12 +47,12 @@ func (suite AnteTestSuite) TestValidateBasicDecorator() { addr, privKey := tests.NewAddrKey() signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) unprotectedTx := evmtypes.NewTxContract(nil, 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - unprotectedTx.From = addr.Hex() + unprotectedTx.From = addr.Bytes() err = unprotectedTx.Sign(ethtypes.HomesteadSigner{}, tests.NewSigner(privKey)) suite.Require().NoError(err) tmTx, err := unprotectedTx.BuildTx(suite.clientCtx.TxConfig.NewTxBuilder(), evmtypes.DefaultEVMDenom) diff --git a/app/ante/signverify_test.go b/app/ante/signverify_test.go index 9874ed6646..8c29ac8a6f 100644 --- a/app/ante/signverify_test.go +++ b/app/ante/signverify_test.go @@ -14,12 +14,12 @@ func (suite AnteTestSuite) TestEthSigVerificationDecorator() { addr, privKey := tests.NewAddrKey() signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) unprotectedTx := evmtypes.NewTxContract(nil, 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) - unprotectedTx.From = addr.Hex() + unprotectedTx.From = addr.Bytes() err = unprotectedTx.Sign(ethtypes.HomesteadSigner{}, tests.NewSigner(privKey)) suite.Require().NoError(err) @@ -43,13 +43,7 @@ func (suite AnteTestSuite) TestEthSigVerificationDecorator() { for _, tc := range testCases { suite.Run(tc.name, func() { suite.SetupTest() - - evmParams := suite.app.EvmKeeper.GetParams(suite.ctx) - chainID := suite.app.EvmKeeper.ChainID() - chainCfg := evmParams.GetChainConfig() - ethCfg := chainCfg.EthereumConfig(chainID) - - dec := ante.NewEthSigVerificationDecorator(ethCfg) + dec := ante.NewEthSigVerificationDecorator(suite.app.EvmKeeper.ChainID()) _, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, NextFn) if tc.expPass { diff --git a/app/ante/sigs_test.go b/app/ante/sigs_test.go index 30f050458c..3a1ff19649 100644 --- a/app/ante/sigs_test.go +++ b/app/ante/sigs_test.go @@ -22,7 +22,7 @@ func (suite AnteTestSuite) TestSignatures() { suite.app.EvmKeeper.SetAccount(suite.ctx, addr, *acc) suite.app.EvmKeeper.SetBalance(suite.ctx, addr, balance) msgEthereumTx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 100000, big.NewInt(1), nil, nil, nil, nil) - msgEthereumTx.From = addr.Hex() + msgEthereumTx.From = addr.Bytes() // CreateTestTx will sign the msgEthereumTx but not sign the cosmos tx since we have signCosmosTx as false tx := suite.CreateTestTx(msgEthereumTx, privKey, 1, false) diff --git a/app/ante/sigverify.go b/app/ante/sigverify.go index c66b3c0217..6e49d83207 100644 --- a/app/ante/sigverify.go +++ b/app/ante/sigverify.go @@ -21,19 +21,17 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" evmtypes "github.com/evmos/ethermint/x/evm/types" ) // EthSigVerificationDecorator validates an ethereum signatures type EthSigVerificationDecorator struct { - ethCfg *params.ChainConfig + chainID *big.Int } // NewEthSigVerificationDecorator creates a new EthSigVerificationDecorator -func NewEthSigVerificationDecorator(ethCfg *params.ChainConfig) EthSigVerificationDecorator { - return EthSigVerificationDecorator{ethCfg} +func NewEthSigVerificationDecorator(chainID *big.Int) EthSigVerificationDecorator { + return EthSigVerificationDecorator{chainID} } // AnteHandle validates checks that the registered chain id is the same as the one on the message, and @@ -42,27 +40,15 @@ func NewEthSigVerificationDecorator(ethCfg *params.ChainConfig) EthSigVerificati // Failure in RecheckTx will prevent tx to be included into block, especially when CheckTx succeed, in which case user // won't see the error message. func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - blockNum := big.NewInt(ctx.BlockHeight()) - signer := ethtypes.MakeSigner(esvd.ethCfg, blockNum) - for _, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) if !ok { return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - ethTx := msgEthTx.AsTransaction() - sender, err := signer.Sender(ethTx) - if err != nil { - return ctx, errorsmod.Wrapf( - errortypes.ErrorInvalidSigner, - "couldn't retrieve sender address from the ethereum transaction: %s", - err.Error(), - ) + if err := msgEthTx.VerifySender(esvd.chainID); err != nil { + return ctx, errorsmod.Wrapf(errortypes.ErrorInvalidSigner, "signature verification failed: %s", err.Error()) } - - // set up the sender to the transaction field if not already - msgEthTx.From = sender.Hex() } return next(ctx, tx, simulate) diff --git a/app/ante/utils_test.go b/app/ante/utils_test.go index c5ddd77d73..f575cf41d2 100644 --- a/app/ante/utils_test.go +++ b/app/ante/utils_test.go @@ -195,7 +195,7 @@ func (s *AnteTestSuite) BuildTestEthTx( input, accesses, ) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() return msgEthereumTx } @@ -230,7 +230,6 @@ func (suite *AnteTestSuite) CreateTestTxBuilder( err = msg.Sign(suite.ethSigner, tests.NewSigner(priv)) suite.Require().NoError(err) - msg.From = "" err = builder.SetMsgs(msg) suite.Require().NoError(err) diff --git a/encoding/config_test.go b/encoding/config_test.go index 5a90f18438..ddda5cb4fb 100644 --- a/encoding/config_test.go +++ b/encoding/config_test.go @@ -19,7 +19,7 @@ func TestTxEncoding(t *testing.T) { signer := tests.NewSigner(key) msg := evmtypes.NewTxContract(big.NewInt(1), 1, big.NewInt(10), 100000, nil, big.NewInt(1), big.NewInt(1), []byte{}, nil) - msg.From = addr.Hex() + msg.From = addr.Bytes() ethSigner := ethtypes.LatestSignerForChainID(big.NewInt(1)) err := msg.Sign(ethSigner, signer) diff --git a/indexer/kv_indexer_test.go b/indexer/kv_indexer_test.go index 0efd0c32bc..8fe5bc30cf 100644 --- a/indexer/kv_indexer_test.go +++ b/indexer/kv_indexer_test.go @@ -32,7 +32,7 @@ func TestKVIndexer(t *testing.T) { tx := types.NewTx( nil, 0, &to, big.NewInt(1000), 21000, nil, nil, nil, nil, nil, ) - tx.From = from.Hex() + tx.From = from.Bytes() require.NoError(t, tx.Sign(ethSigner, signer)) txHash := tx.AsTransaction().Hash() diff --git a/proto/ethermint/evm/v1/tx.proto b/proto/ethermint/evm/v1/tx.proto index dbfb0dd2bb..26ff9689e0 100644 --- a/proto/ethermint/evm/v1/tx.proto +++ b/proto/ethermint/evm/v1/tx.proto @@ -32,10 +32,11 @@ message MsgEthereumTx { double size = 2 [(gogoproto.jsontag) = "-"]; // hash of the transaction in hex format string hash = 3 [(gogoproto.moretags) = "rlp:\"-\""]; - // from is the ethereum signer address in hex format. This address value is checked + string deprecated_from = 4 [deprecated = true]; + // from is the bytes of ethereum signer address. This address value is checked // against the address derived from the signature (V, R, S) using the // secp256k1 elliptic curve - string from = 4; + bytes from = 5; } // LegacyTx is the transaction data of regular Ethereum transactions. diff --git a/rpc/backend/backend_suite_test.go b/rpc/backend/backend_suite_test.go index a14b6254e0..812f049712 100644 --- a/rpc/backend/backend_suite_test.go +++ b/rpc/backend/backend_suite_test.go @@ -31,9 +31,10 @@ import ( type BackendTestSuite struct { suite.Suite - backend *Backend - acc sdk.AccAddress - signer keyring.Signer + backend *Backend + acc sdk.AccAddress + signer keyring.Signer + signerAddress sdk.AccAddress } func TestBackendTestSuite(t *testing.T) { @@ -67,6 +68,7 @@ func (suite *BackendTestSuite) SetupTest() { priv, err := ethsecp256k1.GenerateKey() suite.signer = tests.NewSigner(priv) suite.Require().NoError(err) + suite.signerAddress = sdk.AccAddress(priv.PubKey().Address().Bytes()) encodingConfig := encoding.MakeConfig(app.ModuleBasics) clientCtx := client.Context{}.WithChainID(ChainID). @@ -104,12 +106,12 @@ func (suite *BackendTestSuite) buildEthereumTx() (*evmtypes.MsgEthereumTx, []byt nil, nil, ) - - // A valid msg should have empty `From` - msgEthereumTx.From = "" + msgEthereumTx.From = suite.signerAddress + err := msgEthereumTx.Sign(ethtypes.LatestSignerForChainID(suite.backend.chainID), suite.signer) + suite.Require().NoError(err) txBuilder := suite.backend.clientCtx.TxConfig.NewTxBuilder() - err := txBuilder.SetMsgs(msgEthereumTx) + err = txBuilder.SetMsgs(msgEthereumTx) suite.Require().NoError(err) bz, err := suite.backend.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) @@ -178,7 +180,7 @@ func (suite *BackendTestSuite) signAndEncodeEthTx(msgEthereumTx *evmtypes.MsgEth RegisterParamsWithoutHeader(queryClient, 1) ethSigner := ethtypes.LatestSigner(suite.backend.ChainConfig()) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() err := msgEthereumTx.Sign(ethSigner, signer) suite.Require().NoError(err) diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index 6871bbd7f0..3b346cbeed 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -131,7 +131,7 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { } ethereumTx := &evmtypes.MsgEthereumTx{} - if err := ethereumTx.FromEthereumTx(tx); err != nil { + if err := ethereumTx.FromSignedEthereumTx(tx, b.chainID); err != nil { b.logger.Error("transaction converting failed", "error", err.Error()) return common.Hash{}, err } diff --git a/rpc/backend/call_tx_test.go b/rpc/backend/call_tx_test.go index a3705284ad..f4349fc541 100644 --- a/rpc/backend/call_tx_test.go +++ b/rpc/backend/call_tx_test.go @@ -300,6 +300,8 @@ func (suite *BackendTestSuite) TestSendRawTransaction() { "fail - unprotected transactions", func() { suite.backend.allowUnprotectedTxs = false + queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) + RegisterParamsWithoutHeaderError(queryClient, 1) }, rlpEncodedBz, common.Hash{}, diff --git a/rpc/backend/tracing_test.go b/rpc/backend/tracing_test.go index 613c681687..af72cda02e 100644 --- a/rpc/backend/tracing_test.go +++ b/rpc/backend/tracing_test.go @@ -37,12 +37,12 @@ func (suite *BackendTestSuite) TestTraceTransaction() { txEncoder := suite.backend.clientCtx.TxConfig.TxEncoder() - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() msgEthereumTx.Sign(ethSigner, suite.signer) tx, _ := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") txBz, _ := txEncoder(tx) - msgEthereumTx2.From = from.String() + msgEthereumTx2.From = from.Bytes() msgEthereumTx2.Sign(ethSigner, suite.signer) tx2, _ := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") txBz2, _ := txEncoder(tx2) diff --git a/rpc/backend/tx_info.go b/rpc/backend/tx_info.go index b47f59bff2..8207bcd291 100644 --- a/rpc/backend/tx_info.go +++ b/rpc/backend/tx_info.go @@ -194,7 +194,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ return nil, err } - from, err := ethMsg.GetSender(chainID.ToInt()) + from, err := ethMsg.GetSenderLegacy(chainID.ToInt()) if err != nil { return nil, err } diff --git a/rpc/backend/utils.go b/rpc/backend/utils.go index 9512623be2..d13369f09e 100644 --- a/rpc/backend/utils.go +++ b/rpc/backend/utils.go @@ -104,7 +104,7 @@ func (b *Backend) getAccountNonce(accAddr common.Address, pending bool, height i break } - sender, err := ethMsg.GetSender(b.chainID) + sender, err := ethMsg.GetSenderLegacy(b.chainID) if err != nil { continue } diff --git a/store/cachekv/internal/btree.go b/store/cachekv/internal/btree.go index 0de7a1376d..644bcf1baf 100644 --- a/store/cachekv/internal/btree.go +++ b/store/cachekv/internal/btree.go @@ -27,19 +27,28 @@ type BTree struct { // NewBTree creates a wrapper around `btree.BTreeG`. func NewBTree() BTree { - return BTree{ - tree: btree.NewBTreeGOptions(byKeys, btree.Options{ - Degree: bTreeDegree, - NoLocks: false, - }), - } + return BTree{} } -func (bt BTree) Set(key, value []byte, dirty bool) { +func (bt *BTree) init() { + bt.tree = btree.NewBTreeGOptions(byKeys, btree.Options{ + Degree: bTreeDegree, + NoLocks: false, + }) +} + +func (bt *BTree) Set(key, value []byte, dirty bool) { + if bt.tree == nil { + bt.init() + } bt.tree.Set(item{key: key, value: value, dirty: dirty}) } func (bt BTree) Get(key []byte) ([]byte, bool) { + if bt.tree == nil { + return nil, false + } + i, found := bt.tree.Get(newItem(key)) if !found { return nil, false @@ -48,6 +57,9 @@ func (bt BTree) Get(key []byte) ([]byte, bool) { } func (bt BTree) Delete(key []byte) { + if bt.tree == nil { + return + } bt.tree.Delete(newItem(key)) } @@ -67,6 +79,10 @@ func (bt BTree) ReverseIterator(start, end []byte) (types.Iterator, error) { // ScanDirtyItems iterate over the dirty entries. func (bt BTree) ScanDirtyItems(fn func(key, value []byte)) { + if bt.tree == nil { + return + } + bt.tree.Scan(func(item item) bool { if item.dirty { fn(item.key, item.value) @@ -78,6 +94,10 @@ func (bt BTree) ScanDirtyItems(fn func(key, value []byte)) { // Copy the tree. This is a copy-on-write operation and is very fast because // it only performs a shadowed copy. func (bt BTree) Copy() BTree { + if bt.tree == nil { + return BTree{} + } + return BTree{ tree: bt.tree.Copy(), } diff --git a/store/cachekv/internal/memiterator.go b/store/cachekv/internal/memiterator.go index 76f5b158f0..d1b98bd5b6 100644 --- a/store/cachekv/internal/memiterator.go +++ b/store/cachekv/internal/memiterator.go @@ -23,6 +23,10 @@ type memIterator struct { } func newMemIterator(start, end []byte, items BTree, ascending bool) *memIterator { + if items.tree == nil { + return &memIterator{start: start, end: end, ascending: ascending, valid: false} + } + iter := items.tree.Iter() var valid bool if ascending { diff --git a/store/cachemulti/store.go b/store/cachemulti/store.go index bcf3fb0222..41923c5e1f 100644 --- a/store/cachemulti/store.go +++ b/store/cachemulti/store.go @@ -68,7 +68,7 @@ func NewStore( } func newCacheMultiStoreFromCMS(cms Store) Store { - stores := make(map[types.StoreKey]types.KVStore) + stores := make(map[types.StoreKey]types.KVStore, len(cms.stores)) for k, v := range cms.stores { stores[k] = v } diff --git a/x/evm/client/cli/tx.go b/x/evm/client/cli/tx.go index 8f33d36c1e..eb34fc5d4d 100644 --- a/x/evm/client/cli/tx.go +++ b/x/evm/client/cli/tx.go @@ -28,6 +28,7 @@ import ( "github.com/spf13/cobra" rpctypes "github.com/evmos/ethermint/rpc/types" + ethermint "github.com/evmos/ethermint/types" "github.com/evmos/ethermint/x/evm/types" ) @@ -51,22 +52,27 @@ func NewRawTxCmd() *cobra.Command { Short: "Build cosmos transaction from raw ethereum transaction", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + data, err := hexutil.Decode(args[0]) if err != nil { return errors.Wrap(err, "failed to decode ethereum tx hex bytes") } - msg := &types.MsgEthereumTx{} - if err := msg.UnmarshalBinary(data); err != nil { + eip155ChainID, err := ethermint.ParseChainID(clientCtx.ChainID) + if err != nil { return err } - if err := msg.ValidateBasic(); err != nil { + msg := &types.MsgEthereumTx{} + if err := msg.UnmarshalBinary(data, eip155ChainID); err != nil { return err } - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { + if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/evm/handler_test.go b/x/evm/handler_test.go index 219e921645..b2f40ffcf1 100644 --- a/x/evm/handler_test.go +++ b/x/evm/handler_test.go @@ -176,7 +176,7 @@ func (suite *EvmTestSuite) SetupTest() { } func (suite *EvmTestSuite) SignTx(tx *types.MsgEthereumTx) { - tx.From = suite.from.String() + tx.From = suite.from.Bytes() err := tx.Sign(suite.ethSigner, suite.signer) suite.Require().NoError(err) } @@ -605,7 +605,7 @@ func (suite *EvmTestSuite) TestERC20TransferReverted() { suite.Require().NoError(err) fees, err := keeper.VerifyFee(txData, "aphoton", baseFee, true, true, suite.ctx.IsCheckTx()) suite.Require().NoError(err) - err = k.DeductTxCostsFromUserBalance(suite.ctx, fees, common.HexToAddress(tx.From)) + err = k.DeductTxCostsFromUserBalance(suite.ctx, fees, tx.GetSender()) suite.Require().NoError(err) res, err := k.EthereumTx(sdk.WrapSDKContext(suite.ctx), tx) diff --git a/x/evm/keeper/benchmark_test.go b/x/evm/keeper/benchmark_test.go index 9264629bcf..8a00885c19 100644 --- a/x/evm/keeper/benchmark_test.go +++ b/x/evm/keeper/benchmark_test.go @@ -54,7 +54,7 @@ func DoBenchmark(b *testing.B, txBuilder TxBuilder) { suite, contractAddr := SetupContract(b) msg := txBuilder(suite, contractAddr) - msg.From = suite.address.Hex() + msg.From = suite.address.Bytes() err := msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer) require.NoError(b, err) @@ -121,7 +121,7 @@ func BenchmarkMessageCall(b *testing.B) { nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address) msg := types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 25000000, big.NewInt(1), nil, nil, input, nil) - msg.From = suite.address.Hex() + msg.From = suite.address.Bytes() err = msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer) require.NoError(b, err) diff --git a/x/evm/keeper/integration_test.go b/x/evm/keeper/integration_test.go index 73aa363f89..31fd4dad39 100644 --- a/x/evm/keeper/integration_test.go +++ b/x/evm/keeper/integration_test.go @@ -239,7 +239,7 @@ func buildEthTx( data, accesses, ) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() return msgEthereumTx } @@ -256,8 +256,6 @@ func prepareEthTx(priv *ethsecp256k1.PrivKey, msgEthereumTx *evmtypes.MsgEthereu err = msgEthereumTx.Sign(s.ethSigner, tests.NewSigner(priv)) s.Require().NoError(err) - // A valid msg should have empty `From` - msgEthereumTx.From = "" err = txBuilder.SetMsgs(msgEthereumTx) s.Require().NoError(err) diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index b7297d8005..908b1e8241 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -305,7 +305,7 @@ func (suite *KeeperTestSuite) DeployTestContract(t require.TestingT, owner commo ) } - erc20DeployTx.From = suite.address.Hex() + erc20DeployTx.From = suite.address.Bytes() err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) require.NoError(t, err) rsp, err := suite.app.EvmKeeper.EthereumTx(ctx, erc20DeployTx) @@ -359,7 +359,7 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd ) } - ercTransferTx.From = suite.address.Hex() + ercTransferTx.From = suite.address.Bytes() err = ercTransferTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) require.NoError(t, err) rsp, err := suite.app.EvmKeeper.EthereumTx(ctx, ercTransferTx) @@ -415,7 +415,7 @@ func (suite *KeeperTestSuite) DeployTestMessageCall(t require.TestingT) common.A ) } - erc20DeployTx.From = suite.address.Hex() + erc20DeployTx.From = suite.address.Bytes() err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer) require.NoError(t, err) rsp, err := suite.app.EvmKeeper.EthereumTx(ctx, erc20DeployTx) diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 5c58bb8363..4f001442b2 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -42,7 +42,6 @@ var _ types.MsgServer = &Keeper{} func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - sender := msg.From tx := msg.AsTransaction() txIndex := k.GetTxIndexTransient(ctx) @@ -105,7 +104,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t } if to := tx.To(); to != nil { - attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyRecipient, to.Hex())) + attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyRecipient, types.HexAddress(to.Bytes()))) } if response.Failed() { @@ -121,8 +120,8 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, sender), - sdk.NewAttribute(types.AttributeKeyTxType, fmt.Sprintf("%d", tx.Type())), + sdk.NewAttribute(sdk.AttributeKeySender, types.HexAddress(msg.From)), + sdk.NewAttribute(types.AttributeKeyTxType, strconv.Itoa(int(tx.Type()))), ), }) diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index 9d851291b6..36d14ecf5a 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -177,9 +177,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, msgEth *types.MsgEthereumTx) 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 := msgEth.AsMessage(signer, cfg.BaseFee) + msg, err := msgEth.AsMessage(cfg.BaseFee) if err != nil { return nil, errorsmod.Wrap(err, "failed to return ethereum transaction as core message") } diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 68e93d1ce5..e2a10293de 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -73,7 +73,7 @@ func newSignedEthTx( } var msg evmtypes.MsgEthereumTx - if err := msg.FromEthereumTx(ethTx); err != nil { + if err := msg.FromSignedEthereumTx(ethTx, ethSigner.ChainID()); err != nil { return nil, err } return &msg, nil @@ -128,7 +128,7 @@ func newEthMsgTx( msg := &evmtypes.MsgEthereumTx{} msg.FromEthereumTx(ethTx) - msg.From = address.Hex() + msg.From = address.Bytes() return msg, baseFee, msg.Sign(ethSigner, krSigner) } @@ -144,14 +144,12 @@ func newNativeMessage( data []byte, accessList ethtypes.AccessList, ) (core.Message, error) { - msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight)) - msg, baseFee, err := newEthMsgTx(nonce, blockHeight, address, cfg, krSigner, ethSigner, txType, data, accessList) if err != nil { return nil, err } - m, err := msg.AsMessage(msgSigner, baseFee) + m, err := msg.AsMessage(baseFee) if err != nil { return nil, err } diff --git a/x/evm/keeper/state_transition_test.go b/x/evm/keeper/state_transition_test.go index 3f45146718..cf5de6c247 100644 --- a/x/evm/keeper/state_transition_test.go +++ b/x/evm/keeper/state_transition_test.go @@ -668,8 +668,7 @@ func (suite *KeeperTestSuite) createContractGethMsg(nonce uint64, signer ethtype return nil, err } - msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(suite.ctx.BlockHeight())) - return ethMsg.AsMessage(msgSigner, nil) + return ethMsg.AsMessage(nil) } func (suite *KeeperTestSuite) createContractMsgTx(nonce uint64, signer ethtypes.Signer, cfg *params.ChainConfig, gasPrice *big.Int) (*types.MsgEthereumTx, error) { @@ -683,7 +682,7 @@ func (suite *KeeperTestSuite) createContractMsgTx(nonce uint64, signer ethtypes. ethTx := ethtypes.NewTx(contractCreateTx) ethMsg := &types.MsgEthereumTx{} ethMsg.FromEthereumTx(ethTx) - ethMsg.From = suite.address.Hex() + ethMsg.From = suite.address.Bytes() return ethMsg, ethMsg.Sign(signer, suite.signer) } diff --git a/x/evm/keeper/statedb.go b/x/evm/keeper/statedb.go index b0dbac54e4..d414bd193d 100644 --- a/x/evm/keeper/statedb.go +++ b/x/evm/keeper/statedb.go @@ -16,7 +16,6 @@ package keeper import ( - "fmt" "math/big" errorsmod "cosmossdk.io/errors" @@ -126,11 +125,10 @@ func (k *Keeper) SetAccount(ctx sdk.Context, addr common.Address, account stated k.accountKeeper.SetAccount(ctx, acct) - k.Logger(ctx).Debug( - "account updated", - "ethereum-address", addr.Hex(), + k.Logger(ctx).Debug("account updated", + "ethereum-address", addr, "nonce", account.Nonce, - "codeHash", codeHash.Hex(), + "codeHash", codeHash, ) return nil } @@ -145,10 +143,10 @@ func (k *Keeper) SetState(ctx sdk.Context, addr common.Address, key common.Hash, } else { store.Set(key.Bytes(), value) } - k.Logger(ctx).Debug( - fmt.Sprintf("state %s", action), - "ethereum-address", addr.Hex(), - "key", key.Hex(), + k.Logger(ctx).Debug("state", + "action", action, + "ethereum-address", addr, + "key", key, ) } @@ -164,9 +162,9 @@ func (k *Keeper) SetCode(ctx sdk.Context, codeHash, code []byte) { } else { store.Set(codeHash, code) } - k.Logger(ctx).Debug( - fmt.Sprintf("code %s", action), - "code-hash", common.BytesToHash(codeHash).Hex(), + k.Logger(ctx).Debug("code", + "action", action, + "code-hash", codeHash, ) } @@ -198,10 +196,9 @@ func (k *Keeper) DeleteAccount(ctx sdk.Context, addr common.Address) error { // remove auth account k.accountKeeper.RemoveAccount(ctx, acct) - k.Logger(ctx).Debug( - "account suicided", - "ethereum-address", addr.Hex(), - "cosmos-address", cosmosAddr.String(), + k.Logger(ctx).Debug("account suicided", + "ethereum-address", addr, + "cosmos-address", cosmosAddr, ) return nil diff --git a/x/evm/keeper/statedb_test.go b/x/evm/keeper/statedb_test.go index 24390a0d26..f8bc1bff2e 100644 --- a/x/evm/keeper/statedb_test.go +++ b/x/evm/keeper/statedb_test.go @@ -626,27 +626,27 @@ func (suite *KeeperTestSuite) CreateTestTx(msg *types.MsgEthereumTx, priv crypto func (suite *KeeperTestSuite) TestAddLog() { addr, privKey := tests.NewAddrKey() msg := types.NewTx(big.NewInt(1), 0, &suite.address, big.NewInt(1), 100000, big.NewInt(1), nil, nil, []byte("test"), nil) - msg.From = addr.Hex() + msg.From = addr.Bytes() tx := suite.CreateTestTx(msg, privKey) msg, _ = tx.GetMsgs()[0].(*types.MsgEthereumTx) txHash := msg.AsTransaction().Hash() msg2 := types.NewTx(big.NewInt(1), 1, &suite.address, big.NewInt(1), 100000, big.NewInt(1), nil, nil, []byte("test"), nil) - msg2.From = addr.Hex() + msg2.From = addr.Bytes() tx2 := suite.CreateTestTx(msg2, privKey) msg2, _ = tx2.GetMsgs()[0].(*types.MsgEthereumTx) msg3 := types.NewTx(big.NewInt(1), 0, &suite.address, big.NewInt(1), 100000, nil, big.NewInt(1), big.NewInt(1), []byte("test"), nil) - msg3.From = addr.Hex() + msg3.From = addr.Bytes() tx3 := suite.CreateTestTx(msg3, privKey) msg3, _ = tx3.GetMsgs()[0].(*types.MsgEthereumTx) txHash3 := msg3.AsTransaction().Hash() msg4 := types.NewTx(big.NewInt(1), 1, &suite.address, big.NewInt(1), 100000, nil, big.NewInt(1), big.NewInt(1), []byte("test"), nil) - msg4.From = addr.Hex() + msg4.From = addr.Bytes() tx4 := suite.CreateTestTx(msg4, privKey) msg4, _ = tx4.GetMsgs()[0].(*types.MsgEthereumTx) diff --git a/x/evm/keeper/utils_test.go b/x/evm/keeper/utils_test.go index 5de7a342d9..d86870b848 100644 --- a/x/evm/keeper/utils_test.go +++ b/x/evm/keeper/utils_test.go @@ -233,7 +233,7 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() { } tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &to, amount, tc.gasLimit, gasPrice, gasFeeCap, gasTipCap, nil, tc.accessList) - tx.From = tc.from + tx.From = common.HexToAddress(tc.from).Bytes() txData, _ := evmtypes.UnpackTxData(tx.Data) @@ -471,7 +471,7 @@ func (suite *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { suite.Require().NoError(err, "Unexpected error while committing to vmdb: %d", err) tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &suite.address, amount, tc.gasLimit, gasPrice, gasFeeCap, gasTipCap, nil, tc.accessList) - tx.From = tc.from + tx.From = common.HexToAddress(tc.from).Bytes() txData, _ := evmtypes.UnpackTxData(tx.Data) @@ -507,7 +507,7 @@ func (suite *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { suite.Require().Nil(fees, "invalid test %d passed. fees value must be nil - '%s'", i, tc.name) } - err = suite.app.EvmKeeper.DeductTxCostsFromUserBalance(suite.ctx, fees, common.HexToAddress(tx.From)) + err = suite.app.EvmKeeper.DeductTxCostsFromUserBalance(suite.ctx, fees, common.BytesToAddress(tx.From)) if tc.expectPassDeduct { suite.Require().NoError(err, "valid test %d failed - '%s'", i, tc.name) } else { diff --git a/x/evm/simulation/operations.go b/x/evm/simulation/operations.go index e8106c57b7..41538a16c5 100644 --- a/x/evm/simulation/operations.go +++ b/x/evm/simulation/operations.go @@ -232,7 +232,7 @@ func CreateRandomValidEthTx(ctx *simulateContext, } ethTx = types.NewTx(ethChainID, nonce, to, amount, gasLimit, gasPrice, gasFeeCap, gasTipCap, *data, nil) - ethTx.From = from.String() + ethTx.From = from.Bytes() return ethTx, nil } diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index 3d29b595d2..6ccf97bf58 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -16,6 +16,7 @@ package types import ( + "bytes" "errors" "fmt" "math/big" @@ -32,8 +33,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/signing" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - "github.com/evmos/ethermint/types" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" @@ -172,6 +171,21 @@ func (msg *MsgEthereumTx) FromEthereumTx(tx *ethtypes.Transaction) error { return nil } +// FromSignedEthereumTx populates the message fields from the given signed ethereum transaction, and set From field. +func (msg *MsgEthereumTx) FromSignedEthereumTx(tx *ethtypes.Transaction, chainID *big.Int) error { + if err := msg.FromEthereumTx(tx); err != nil { + return err + } + + from, err := msg.recoverSender(chainID) + if err != nil { + return err + } + + msg.From = from.Bytes() + return nil +} + // Route returns the route value of an MsgEthereumTx. func (msg MsgEthereumTx) Route() string { return RouterKey } @@ -181,10 +195,12 @@ func (msg MsgEthereumTx) Type() string { return TypeMsgEthereumTx } // ValidateBasic implements the sdk.Msg interface. It performs basic validation // checks of a Transaction. If returns an error if validation fails. func (msg MsgEthereumTx) ValidateBasic() error { - if msg.From != "" { - if err := types.ValidateAddress(msg.From); err != nil { - return errorsmod.Wrap(err, "invalid from address") - } + if len(msg.DeprecatedFrom) != 0 { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "deprecated From field is not empty") + } + + if len(msg.From) == 0 { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "sender address is missing") } // Validate Size_ field, should be kept empty @@ -222,25 +238,35 @@ func (msg *MsgEthereumTx) GetMsgs() []sdk.Msg { // GetSigners returns the expected signers for an Ethereum transaction message. // For such a message, there should exist only a single 'signer'. -// -// NOTE: This method panics if 'Sign' hasn't been called first. func (msg *MsgEthereumTx) GetSigners() []sdk.AccAddress { - if len(msg.From) > 0 { - return []sdk.AccAddress{common.HexToAddress(msg.From).Bytes()} + if len(msg.From) == 0 { + return nil } + return []sdk.AccAddress{msg.GetFrom()} +} - data, err := UnpackTxData(msg.Data) - if err != nil { - panic(err) - } +// GetSender convert the From field to common.Address +// From should always be set, which is validated in ValidateBasic +func (msg *MsgEthereumTx) GetSender() common.Address { + return common.BytesToAddress(msg.From) +} - sender, err := msg.GetSender(data.GetChainID()) +// GetSenderLegacy fallbacks to old behavior if From is empty, should be used by json-rpc +func (msg *MsgEthereumTx) GetSenderLegacy(chainID *big.Int) (common.Address, error) { + if len(msg.From) > 0 { + return msg.GetSender(), nil + } + sender, err := msg.recoverSender(chainID) if err != nil { - panic(err) + return common.Address{}, err } + msg.From = sender.Bytes() + return sender, nil +} - signer := sdk.AccAddress(sender.Bytes()) - return []sdk.AccAddress{signer} +// recoverSender recovers the sender address from the transaction signature. +func (msg *MsgEthereumTx) recoverSender(chainID *big.Int) (common.Address, error) { + return ethtypes.LatestSignerForChainID(chainID).Sender(msg.AsTransaction()) } // GetSignBytes returns the Amino bytes of an Ethereum transaction message used @@ -311,11 +337,7 @@ func (msg MsgEthereumTx) GetEffectiveFee(baseFee *big.Int) *big.Int { // GetFrom loads the ethereum sender address from the sigcache and returns an // sdk.AccAddress from its bytes func (msg *MsgEthereumTx) GetFrom() sdk.AccAddress { - if msg.From == "" { - return nil - } - - return common.HexToAddress(msg.From).Bytes() + return sdk.AccAddress(msg.From) } // AsTransaction creates an Ethereum Transaction type from the msg fields @@ -329,7 +351,7 @@ 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) { +func (msg MsgEthereumTx) AsMessage(baseFee *big.Int) (core.Message, error) { txData, err := UnpackTxData(msg.Data) if err != nil { return nil, err @@ -339,22 +361,8 @@ func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (co if baseFee != nil { gasPrice = math.BigMin(gasPrice.Add(gasTipCap, baseFee), gasFeeCap) } - 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, err = signer.Sender(msg.AsTransaction()) - if err != nil { - return nil, err - } - } ethMsg := ethtypes.NewMessage( - from, + msg.GetSender(), txData.GetTo(), txData.GetNonce(), txData.GetValue(), @@ -368,16 +376,17 @@ func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (co return ethMsg, nil } -// GetSender extracts the sender address from the signature values using the latest signer for the given chainID. -func (msg *MsgEthereumTx) GetSender(chainID *big.Int) (common.Address, error) { - signer := ethtypes.LatestSignerForChainID(chainID) - from, err := signer.Sender(msg.AsTransaction()) +// VerifySender verify the sender address against the signature values using the latest signer for the given chainID. +func (msg *MsgEthereumTx) VerifySender(chainID *big.Int) error { + from, err := msg.recoverSender(chainID) if err != nil { - return common.Address{}, err + return err } - msg.From = from.Hex() - return from, nil + if !bytes.Equal(msg.From, from.Bytes()) { + return fmt.Errorf("sender verification failed. got %s, expected %s", from.String(), HexAddress(msg.From)) + } + return nil } // UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces @@ -386,12 +395,12 @@ func (msg MsgEthereumTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error } // UnmarshalBinary decodes the canonical encoding of transactions. -func (msg *MsgEthereumTx) UnmarshalBinary(b []byte) error { +func (msg *MsgEthereumTx) UnmarshalBinary(b []byte, chainID *big.Int) error { tx := ðtypes.Transaction{} if err := tx.UnmarshalBinary(b); err != nil { return err } - return msg.FromEthereumTx(tx) + return msg.FromSignedEthereumTx(tx, chainID) } // BuildTx builds the canonical cosmos tx from ethereum msg @@ -418,9 +427,6 @@ func (msg *MsgEthereumTx) BuildTx(b client.TxBuilder, evmDenom string) (signing. builder.SetExtensionOptions(option) - // A valid msg should have empty `From` - msg.From = "" - err = builder.SetMsgs(msg) if err != nil { return nil, err diff --git a/x/evm/types/msg_test.go b/x/evm/types/msg_test.go index b997290553..f6dd866dc3 100644 --- a/x/evm/types/msg_test.go +++ b/x/evm/types/msg_test.go @@ -64,7 +64,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Constructor() { suite.Require().Equal(msg.Type(), types.TypeMsgEthereumTx) // suite.Require().NotNil(msg.To()) suite.Require().Equal(msg.GetMsgs(), []sdk.Msg{msg}) - suite.Require().Panics(func() { msg.GetSigners() }) + suite.Require().Empty(msg.GetSigners()) suite.Require().Panics(func() { msg.GetSignBytes() }) msg = types.NewTxContract(nil, 0, nil, 100000, nil, nil, nil, []byte("test"), nil) @@ -115,6 +115,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { zeroInt := big.NewInt(0) minusOneInt := big.NewInt(-1) exp_2_255 := new(big.Int).Exp(big.NewInt(2), big.NewInt(255), nil) + validFrom := common.BigToAddress(big.NewInt(1)).Bytes() testCases := []struct { msg string @@ -124,7 +125,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasPrice *big.Int gasFeeCap *big.Int gasTipCap *big.Int - from string + from []byte accessList *ethtypes.AccessList chainID *big.Int expectPass bool @@ -132,6 +133,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "pass with recipient - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: hundredInt, @@ -142,6 +144,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "pass with recipient - AccessList Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -154,6 +157,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "pass with recipient - DynamicFee Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -166,6 +170,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "pass contract - Legacy Tx", to: "", + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: hundredInt, @@ -176,6 +181,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "invalid recipient", to: invalidFromAddress, + from: validFrom, amount: minusOneInt, gasLimit: 1000, gasPrice: hundredInt, @@ -184,6 +190,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil amount - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: nil, gasLimit: 1000, gasPrice: hundredInt, @@ -194,6 +201,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "negative amount - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: minusOneInt, gasLimit: 1000, gasPrice: hundredInt, @@ -204,6 +212,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "zero gas limit - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 0, gasPrice: hundredInt, @@ -214,6 +223,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil gas price - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: nil, @@ -224,6 +234,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "negative gas price - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: minusOneInt, @@ -234,6 +245,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "zero gas price - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -249,12 +261,13 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasPrice: zeroInt, gasFeeCap: nil, gasTipCap: nil, - from: invalidFromAddress, + from: nil, expectPass: false, }, { msg: "out of bound gas fee - Legacy Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: exp_2_255, @@ -265,6 +278,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil amount - AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: nil, gasLimit: 1000, gasPrice: hundredInt, @@ -277,6 +291,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "negative amount - AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: minusOneInt, gasLimit: 1000, gasPrice: hundredInt, @@ -289,6 +304,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "zero gas limit - AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 0, gasPrice: zeroInt, @@ -301,6 +317,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil gas price - AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: nil, @@ -313,6 +330,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "negative gas price - AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: minusOneInt, @@ -325,6 +343,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "zero gas price - AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -342,7 +361,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasPrice: zeroInt, gasFeeCap: nil, gasTipCap: nil, - from: invalidFromAddress, + from: nil, accessList: ðtypes.AccessList{}, chainID: hundredInt, expectPass: false, @@ -350,6 +369,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "chain ID not set on AccessListTx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -362,6 +382,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil tx.Data - AccessList Tx", to: suite.to.Hex(), + from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -375,7 +396,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { for _, tc := range testCases { suite.Run(tc.msg, func() { - to := common.HexToAddress(tc.from) + to := common.HexToAddress(tc.to) tx := types.NewTx(tc.chainID, 1, &to, tc.amount, tc.gasLimit, tc.gasPrice, tc.gasFeeCap, tc.gasTipCap, nil, tc.accessList) tx.From = tc.from @@ -467,42 +488,42 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { "pass - EIP2930 signer", types.NewTx(suite.chainID, 0, &suite.to, nil, 100000, nil, nil, nil, []byte("test"), ðtypes.AccessList{}), ethtypes.NewEIP2930Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { "pass - EIP155 signer", types.NewTx(suite.chainID, 0, &suite.to, nil, 100000, nil, nil, nil, []byte("test"), nil), ethtypes.NewEIP155Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { "pass - Homestead signer", types.NewTx(suite.chainID, 0, &suite.to, nil, 100000, nil, nil, nil, []byte("test"), nil), ethtypes.HomesteadSigner{}, - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { "pass - Frontier signer", types.NewTx(suite.chainID, 0, &suite.to, nil, 100000, nil, nil, nil, []byte("test"), nil), ethtypes.FrontierSigner{}, - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { "no from address ", types.NewTx(suite.chainID, 0, &suite.to, nil, 100000, nil, nil, nil, []byte("test"), ðtypes.AccessList{}), ethtypes.NewEIP2930Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = "" }, + func(tx *types.MsgEthereumTx) { tx.From = nil }, false, }, { "from address ≠ signer address", types.NewTx(suite.chainID, 0, &suite.to, nil, 100000, nil, nil, nil, []byte("test"), ðtypes.AccessList{}), ethtypes.NewEIP2930Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = suite.to.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.to.Bytes() }, false, }, } @@ -514,9 +535,8 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { if tc.expectPass { suite.Require().NoError(err, "valid test %d failed: %s", i, tc.msg) - sender, err := tc.tx.GetSender(suite.chainID) suite.Require().NoError(err, tc.msg) - suite.Require().Equal(tc.tx.From, sender.Hex(), tc.msg) + suite.Require().NoError(tc.tx.VerifySender(suite.chainID)) } else { suite.Require().Error(err, "invalid test %d passed: %s", i, tc.msg) } @@ -762,7 +782,7 @@ func (suite *MsgsTestSuite) TestTransactionCoding() { suite.T().Fatalf("could not sign transaction: %v", err) } // RLP - parsedTx, err := encodeDecodeBinary(tx) + parsedTx, err := encodeDecodeBinary(tx, signer.ChainID()) if err != nil { suite.T().Fatal(err) } @@ -770,13 +790,13 @@ func (suite *MsgsTestSuite) TestTransactionCoding() { } } -func encodeDecodeBinary(tx *ethtypes.Transaction) (*types.MsgEthereumTx, error) { +func encodeDecodeBinary(tx *ethtypes.Transaction, chainID *big.Int) (*types.MsgEthereumTx, error) { data, err := tx.MarshalBinary() if err != nil { return nil, fmt.Errorf("rlp encoding failed: %v", err) } parsedTx := &types.MsgEthereumTx{} - if err := parsedTx.UnmarshalBinary(data); err != nil { + if err := parsedTx.UnmarshalBinary(data, chainID); err != nil { return nil, fmt.Errorf("rlp decoding failed: %v", err) } return parsedTx, nil diff --git a/x/evm/types/tx.pb.go b/x/evm/types/tx.pb.go index 285f143227..35053e0372 100644 --- a/x/evm/types/tx.pb.go +++ b/x/evm/types/tx.pb.go @@ -41,11 +41,12 @@ type MsgEthereumTx struct { // size is the encoded storage size of the transaction (DEPRECATED) Size_ float64 `protobuf:"fixed64,2,opt,name=size,proto3" json:"-"` // hash of the transaction in hex format - Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty" rlp:"-"` - // from is the ethereum signer address in hex format. This address value is checked + Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty" rlp:"-"` + DeprecatedFrom string `protobuf:"bytes,4,opt,name=deprecated_from,json=deprecatedFrom,proto3" json:"deprecated_from,omitempty"` // Deprecated: Do not use. + // from is the bytes of ethereum signer address. This address value is checked // against the address derived from the signature (V, R, S) using the // secp256k1 elliptic curve - From string `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"` + From []byte `protobuf:"bytes,5,opt,name=from,proto3" json:"from,omitempty"` } func (m *MsgEthereumTx) Reset() { *m = MsgEthereumTx{} } @@ -456,70 +457,71 @@ func init() { func init() { proto.RegisterFile("ethermint/evm/v1/tx.proto", fileDescriptor_f75ac0a12d075f21) } var fileDescriptor_f75ac0a12d075f21 = []byte{ - // 994 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0xda, 0xeb, 0x5f, 0xcf, 0xfe, 0xe6, 0x5b, 0x8d, 0x52, 0x75, 0x6d, 0x11, 0xaf, 0xb1, - 0x04, 0xb8, 0x95, 0xbc, 0xab, 0x06, 0xd4, 0x43, 0x4e, 0x8d, 0x9b, 0xb4, 0xb4, 0x4a, 0x44, 0xb5, - 0xb8, 0x17, 0x8a, 0x64, 0x4d, 0xd6, 0x93, 0xf5, 0xaa, 0xde, 0x9d, 0xd5, 0xce, 0x78, 0x65, 0x23, - 0x71, 0xe9, 0x89, 0x1b, 0x20, 0xfe, 0x01, 0xce, 0x9c, 0x90, 0xe8, 0x1f, 0x80, 0xc4, 0xa5, 0xe2, - 0x54, 0xc1, 0x05, 0x71, 0x30, 0xc8, 0x41, 0x42, 0xca, 0x0d, 0xfe, 0x02, 0x34, 0x33, 0xeb, 0x38, - 0xae, 0x49, 0x0b, 0xa5, 0x88, 0xd3, 0xce, 0x9b, 0xf7, 0xe6, 0xf3, 0xde, 0xbc, 0xcf, 0x67, 0x66, - 0x16, 0xaa, 0x84, 0x0f, 0x48, 0x1c, 0xf8, 0x21, 0xb7, 0x49, 0x12, 0xd8, 0xc9, 0x55, 0x9b, 0x8f, - 0xad, 0x28, 0xa6, 0x9c, 0xa2, 0x0b, 0xa7, 0x2e, 0x8b, 0x24, 0x81, 0x95, 0x5c, 0xad, 0x5d, 0x72, - 0x29, 0x0b, 0x28, 0xb3, 0x03, 0xe6, 0x89, 0xc8, 0x80, 0x79, 0x2a, 0xb4, 0x56, 0x55, 0x8e, 0x9e, - 0xb4, 0x6c, 0x65, 0xa4, 0xae, 0xda, 0x4a, 0x02, 0x01, 0xa6, 0x7c, 0x1b, 0x1e, 0xf5, 0xa8, 0x5a, - 0x23, 0x46, 0xe9, 0xec, 0x2b, 0x1e, 0xa5, 0xde, 0x90, 0xd8, 0x38, 0xf2, 0x6d, 0x1c, 0x86, 0x94, - 0x63, 0xee, 0xd3, 0x70, 0x8e, 0x57, 0x4d, 0xbd, 0xd2, 0x3a, 0x1c, 0x1d, 0xd9, 0x38, 0x9c, 0x28, - 0x57, 0xf3, 0x63, 0x0d, 0xfe, 0x77, 0xc0, 0xbc, 0x3d, 0x91, 0x90, 0x8c, 0x82, 0xee, 0x18, 0xb5, - 0x40, 0xef, 0x63, 0x8e, 0x0d, 0xad, 0xa1, 0xb5, 0xca, 0x5b, 0x1b, 0x96, 0x5a, 0x6b, 0xcd, 0xd7, - 0x5a, 0x3b, 0xe1, 0xc4, 0x91, 0x11, 0xa8, 0x0a, 0x3a, 0xf3, 0x3f, 0x20, 0x46, 0xa6, 0xa1, 0xb5, - 0xb4, 0x4e, 0xee, 0x64, 0x6a, 0x6a, 0x6d, 0x47, 0x4e, 0x21, 0x13, 0xf4, 0x01, 0x66, 0x03, 0x23, - 0xdb, 0xd0, 0x5a, 0xa5, 0x4e, 0xf9, 0xf7, 0xa9, 0x59, 0x88, 0x87, 0xd1, 0x76, 0xb3, 0xdd, 0x74, - 0xa4, 0x03, 0x21, 0xd0, 0x8f, 0x62, 0x1a, 0x18, 0xba, 0x08, 0x70, 0xe4, 0x78, 0x5b, 0xff, 0xe8, - 0x73, 0x73, 0xad, 0xf9, 0x55, 0x06, 0x8a, 0xfb, 0xc4, 0xc3, 0xee, 0xa4, 0x3b, 0x46, 0x1b, 0x90, - 0x0b, 0x69, 0xe8, 0x12, 0x59, 0x8d, 0xee, 0x28, 0x03, 0xdd, 0x82, 0x92, 0x87, 0x45, 0xe7, 0x7c, - 0x57, 0x65, 0x2f, 0x75, 0xae, 0xfc, 0x38, 0x35, 0x5f, 0xf7, 0x7c, 0x3e, 0x18, 0x1d, 0x5a, 0x2e, - 0x0d, 0xd2, 0x7e, 0xa6, 0x9f, 0x36, 0xeb, 0x3f, 0xb0, 0xf9, 0x24, 0x22, 0xcc, 0xba, 0x1d, 0x72, - 0xa7, 0xe8, 0x61, 0x76, 0x57, 0xac, 0x45, 0x75, 0xc8, 0x7a, 0x98, 0xc9, 0x2a, 0xf5, 0x4e, 0x65, - 0x36, 0x35, 0x8b, 0xb7, 0x30, 0xdb, 0xf7, 0x03, 0x9f, 0x3b, 0xc2, 0x81, 0xd6, 0x21, 0xc3, 0x69, - 0x5a, 0x63, 0x86, 0x53, 0x74, 0x07, 0x72, 0x09, 0x1e, 0x8e, 0x88, 0x91, 0x93, 0x49, 0xdf, 0xfa, - 0xeb, 0x49, 0x67, 0x53, 0x33, 0xbf, 0x13, 0xd0, 0x51, 0xc8, 0x1d, 0x05, 0x21, 0x3a, 0x20, 0xfb, - 0x9c, 0x6f, 0x68, 0xad, 0x4a, 0xda, 0xd1, 0x0a, 0x68, 0x89, 0x51, 0x90, 0x13, 0x5a, 0x22, 0xac, - 0xd8, 0x28, 0x2a, 0x2b, 0x16, 0x16, 0x33, 0x4a, 0xca, 0x62, 0xdb, 0xeb, 0xa2, 0x57, 0xdf, 0x3e, - 0x6a, 0xe7, 0xbb, 0xe3, 0x5d, 0xcc, 0x71, 0xf3, 0xb7, 0x2c, 0x54, 0x76, 0x5c, 0x97, 0x30, 0xb6, - 0xef, 0x33, 0xde, 0x1d, 0xa3, 0xfb, 0x50, 0x74, 0x07, 0xd8, 0x0f, 0x7b, 0x7e, 0x5f, 0x36, 0xaf, - 0xd4, 0xb9, 0xfe, 0xb7, 0xaa, 0x2d, 0xdc, 0x10, 0xab, 0x6f, 0xef, 0x9e, 0x4c, 0xcd, 0x82, 0xab, - 0x86, 0x4e, 0x3a, 0xe8, 0x2f, 0x68, 0xc9, 0x9c, 0x4b, 0x4b, 0xf6, 0x9f, 0xd3, 0xa2, 0x3f, 0x9b, - 0x96, 0xdc, 0x2a, 0x2d, 0xf9, 0x97, 0x47, 0x4b, 0xe1, 0x0c, 0x2d, 0xf7, 0xa1, 0x88, 0x65, 0x6f, - 0x09, 0x33, 0x8a, 0x8d, 0x6c, 0xab, 0xbc, 0xb5, 0x69, 0x3d, 0x7d, 0xd0, 0x2d, 0xd5, 0xfd, 0xee, - 0x28, 0x1a, 0x92, 0x4e, 0xe3, 0xf1, 0xd4, 0x5c, 0x3b, 0x99, 0x9a, 0x80, 0x4f, 0x29, 0xf9, 0xe2, - 0x27, 0x13, 0x16, 0x04, 0x39, 0xa7, 0x80, 0x8a, 0xf3, 0xd2, 0x12, 0xe7, 0xb0, 0xc4, 0x79, 0xf9, - 0x3c, 0xce, 0xbf, 0xd6, 0xa1, 0xb2, 0x3b, 0x09, 0x71, 0xe0, 0xbb, 0x37, 0x09, 0xf9, 0x6f, 0x38, - 0xbf, 0x03, 0x65, 0xc1, 0x39, 0xf7, 0xa3, 0x9e, 0x8b, 0xa3, 0x17, 0x60, 0x5d, 0x48, 0xa6, 0xeb, - 0x47, 0x37, 0x70, 0x34, 0xc7, 0x3a, 0x22, 0x44, 0x62, 0xe9, 0x2f, 0x84, 0x75, 0x93, 0x10, 0x81, - 0x95, 0x4a, 0x28, 0xf7, 0x6c, 0x09, 0xe5, 0x57, 0x25, 0x54, 0x78, 0x79, 0x12, 0x2a, 0x9e, 0x23, - 0xa1, 0xd2, 0xbf, 0x22, 0x21, 0x58, 0x92, 0x50, 0x79, 0x49, 0x42, 0x95, 0xf3, 0x24, 0xd4, 0x84, - 0xda, 0xde, 0x98, 0x93, 0x90, 0xf9, 0x34, 0x7c, 0x27, 0x92, 0x6f, 0xc6, 0xe2, 0x29, 0x48, 0x2f, - 0xe4, 0x6f, 0x34, 0xb8, 0xb8, 0xf4, 0x44, 0x38, 0x84, 0x45, 0x34, 0x64, 0x72, 0xa3, 0xf2, 0x96, - 0xd7, 0xd4, 0x25, 0x2e, 0x2f, 0xf6, 0xcb, 0xa0, 0x0f, 0xa9, 0xc7, 0x8c, 0x8c, 0xdc, 0xe4, 0xc5, - 0xd5, 0x4d, 0xee, 0x53, 0xcf, 0x91, 0x21, 0xe8, 0x02, 0x64, 0x63, 0xc2, 0xa5, 0x66, 0x2a, 0x8e, - 0x18, 0xa2, 0x2a, 0x14, 0x93, 0xa0, 0x47, 0xe2, 0x98, 0xc6, 0xe9, 0xad, 0x5b, 0x48, 0x82, 0x3d, - 0x61, 0x0a, 0x97, 0x10, 0xc7, 0x88, 0x91, 0xbe, 0x62, 0xd5, 0x29, 0x78, 0x98, 0xdd, 0x63, 0xa4, - 0x8f, 0x36, 0x01, 0x0e, 0x87, 0xd4, 0x7d, 0xd0, 0x93, 0xc5, 0xa8, 0xfb, 0xb4, 0x24, 0x67, 0xde, - 0xc6, 0x6c, 0x90, 0xee, 0xe2, 0x53, 0x0d, 0xfe, 0x7f, 0xc0, 0xbc, 0x7b, 0x51, 0x1f, 0x73, 0x72, - 0x17, 0xc7, 0x38, 0x60, 0xe8, 0x1a, 0x94, 0xf0, 0x88, 0x0f, 0x68, 0xec, 0xf3, 0x49, 0x7a, 0x60, - 0x8c, 0xef, 0x1e, 0xb5, 0x37, 0xd2, 0xc7, 0x78, 0xa7, 0xdf, 0x8f, 0x09, 0x63, 0xef, 0xf2, 0xd8, - 0x0f, 0x3d, 0x67, 0x11, 0x8a, 0xae, 0x41, 0x3e, 0x92, 0x08, 0xf2, 0x2c, 0x94, 0xb7, 0x8c, 0xd5, - 0x5d, 0xaa, 0x0c, 0x1d, 0x5d, 0xb0, 0xe8, 0xa4, 0xd1, 0xdb, 0xeb, 0x0f, 0x7f, 0xfd, 0xf2, 0xca, - 0x02, 0xa7, 0x59, 0x85, 0x4b, 0x4f, 0x95, 0x34, 0x6f, 0xed, 0xd6, 0x4c, 0x83, 0xec, 0x01, 0xf3, - 0xd0, 0x87, 0x00, 0x67, 0xde, 0x66, 0x73, 0x35, 0xd1, 0x12, 0x33, 0xb5, 0x37, 0x9e, 0x13, 0x30, - 0xc7, 0x6f, 0xbe, 0xf6, 0xf0, 0xfb, 0x5f, 0x3e, 0xcb, 0x98, 0xcd, 0x4d, 0x7b, 0xf5, 0x5f, 0x23, - 0x8d, 0xee, 0xf1, 0x31, 0x7a, 0x1f, 0x2a, 0x4b, 0x1d, 0x7b, 0xf5, 0x4f, 0xf1, 0xcf, 0x86, 0xd4, - 0x2e, 0x3f, 0x37, 0x64, 0x5e, 0x44, 0xe7, 0xfa, 0xe3, 0x59, 0x5d, 0x7b, 0x32, 0xab, 0x6b, 0x3f, - 0xcf, 0xea, 0xda, 0x27, 0xc7, 0xf5, 0xb5, 0x27, 0xc7, 0xf5, 0xb5, 0x1f, 0x8e, 0xeb, 0x6b, 0xef, - 0x9d, 0x3d, 0x7b, 0x24, 0x11, 0x47, 0x6f, 0x51, 0xe6, 0x58, 0x16, 0x2a, 0xcf, 0xdf, 0x61, 0x5e, - 0xfe, 0x96, 0xbc, 0xf9, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xdd, 0x24, 0x44, 0x93, 0x09, - 0x00, 0x00, + // 1019 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xcf, 0x8f, 0xdb, 0xc4, + 0x17, 0x8f, 0x13, 0xe7, 0x87, 0x27, 0xf9, 0x6e, 0xab, 0xd1, 0x56, 0x75, 0xa2, 0xef, 0xc6, 0x21, + 0x12, 0x90, 0x16, 0xc5, 0x56, 0x17, 0xd4, 0xc3, 0x9e, 0xba, 0xee, 0xee, 0x96, 0x56, 0xbb, 0xa2, + 0x32, 0xe9, 0x85, 0x22, 0x45, 0xb3, 0xf6, 0xac, 0x63, 0x35, 0xf6, 0x58, 0x9e, 0x89, 0x95, 0x20, + 0x71, 0xe9, 0x89, 0x23, 0x88, 0x7f, 0x80, 0x33, 0x27, 0x24, 0x7a, 0xe4, 0x80, 0xc4, 0xa5, 0xe2, + 0x54, 0xc1, 0x05, 0x71, 0x08, 0x28, 0x8b, 0x84, 0xb4, 0x37, 0xf8, 0x0b, 0xd0, 0xcc, 0x38, 0x9b, + 0x4d, 0xc3, 0xb6, 0x50, 0x8a, 0x38, 0x65, 0x9e, 0xdf, 0x9b, 0xcf, 0xbc, 0xf7, 0x3e, 0x9f, 0x99, + 0x17, 0x50, 0xc7, 0x6c, 0x80, 0x93, 0x30, 0x88, 0x98, 0x85, 0xd3, 0xd0, 0x4a, 0xaf, 0x59, 0x6c, + 0x6c, 0xc6, 0x09, 0x61, 0x04, 0x5e, 0x3c, 0x75, 0x99, 0x38, 0x0d, 0xcd, 0xf4, 0x5a, 0xe3, 0xb2, + 0x4b, 0x68, 0x48, 0xa8, 0x15, 0x52, 0x9f, 0x47, 0x86, 0xd4, 0x97, 0xa1, 0x8d, 0xba, 0x74, 0xf4, + 0x85, 0x65, 0x49, 0x23, 0x73, 0x35, 0x56, 0x0e, 0xe0, 0x60, 0xd2, 0xb7, 0xee, 0x13, 0x9f, 0xc8, + 0x3d, 0x7c, 0x95, 0x7d, 0xfd, 0xbf, 0x4f, 0x88, 0x3f, 0xc4, 0x16, 0x8a, 0x03, 0x0b, 0x45, 0x11, + 0x61, 0x88, 0x05, 0x24, 0x9a, 0xe3, 0xd5, 0x33, 0xaf, 0xb0, 0x0e, 0x47, 0x47, 0x16, 0x8a, 0x26, + 0xd2, 0xd5, 0xfe, 0x4a, 0x01, 0xff, 0x3b, 0xa0, 0xfe, 0x2e, 0x3f, 0x10, 0x8f, 0xc2, 0xde, 0x18, + 0x76, 0x80, 0xea, 0x21, 0x86, 0x74, 0xa5, 0xa5, 0x74, 0xaa, 0x9b, 0xeb, 0xa6, 0xdc, 0x6b, 0xce, + 0xf7, 0x9a, 0xdb, 0xd1, 0xc4, 0x11, 0x11, 0xb0, 0x0e, 0x54, 0x1a, 0x7c, 0x80, 0xf5, 0x7c, 0x4b, + 0xe9, 0x28, 0x76, 0xf1, 0x64, 0x6a, 0x28, 0x5d, 0x47, 0x7c, 0x82, 0x06, 0x50, 0x07, 0x88, 0x0e, + 0xf4, 0x42, 0x4b, 0xe9, 0x68, 0x76, 0xf5, 0xf7, 0xa9, 0x51, 0x4e, 0x86, 0xf1, 0x56, 0xbb, 0xdb, + 0x76, 0x84, 0x03, 0xbe, 0x01, 0x2e, 0x78, 0x38, 0x4e, 0xb0, 0x8b, 0x18, 0xf6, 0xfa, 0x47, 0x09, + 0x09, 0x75, 0x55, 0xc4, 0xe6, 0x75, 0xc5, 0x59, 0x5b, 0xb8, 0xf6, 0x12, 0x12, 0x42, 0x08, 0x54, + 0x11, 0x51, 0x6c, 0x29, 0x9d, 0x9a, 0x23, 0xd6, 0x5b, 0xea, 0x47, 0x9f, 0x19, 0xb9, 0xf6, 0x97, + 0x79, 0x50, 0xd9, 0xc7, 0x3e, 0x72, 0x27, 0xbd, 0x31, 0x5c, 0x07, 0xc5, 0x88, 0x44, 0x2e, 0x16, + 0xa9, 0xab, 0x8e, 0x34, 0xe0, 0x2d, 0xa0, 0xf9, 0x88, 0xb7, 0x39, 0x70, 0x65, 0xaa, 0x9a, 0x7d, + 0xf5, 0xc7, 0xa9, 0xf1, 0x9a, 0x1f, 0xb0, 0xc1, 0xe8, 0xd0, 0x74, 0x49, 0x98, 0x35, 0x3f, 0xfb, + 0xe9, 0x52, 0xef, 0x81, 0xc5, 0x26, 0x31, 0xa6, 0xe6, 0xed, 0x88, 0x39, 0x15, 0x1f, 0xd1, 0xbb, + 0x7c, 0x2f, 0x6c, 0x82, 0x82, 0x8f, 0xa8, 0x28, 0x49, 0xb5, 0x6b, 0xb3, 0xa9, 0x51, 0xb9, 0x85, + 0xe8, 0x7e, 0x10, 0x06, 0xcc, 0xe1, 0x0e, 0xb8, 0x06, 0xf2, 0x8c, 0xc8, 0x2a, 0x9c, 0x3c, 0x23, + 0xf0, 0x0e, 0x28, 0xa6, 0x68, 0x38, 0xc2, 0x22, 0x6d, 0xcd, 0x7e, 0xeb, 0xaf, 0x1f, 0x3a, 0x9b, + 0x1a, 0xa5, 0xed, 0x90, 0x8c, 0x22, 0xe6, 0x48, 0x08, 0xde, 0x01, 0x41, 0x4a, 0x49, 0x76, 0x40, + 0xb4, 0xbf, 0x06, 0x94, 0x54, 0x2f, 0x8b, 0x0f, 0x4a, 0xca, 0xad, 0x44, 0xaf, 0x48, 0x2b, 0xe1, + 0x16, 0xd5, 0x35, 0x69, 0xd1, 0xad, 0x35, 0xde, 0xab, 0x6f, 0x1f, 0x75, 0x4b, 0xbd, 0xf1, 0x0e, + 0x62, 0xa8, 0xfd, 0x5b, 0x01, 0xd4, 0xb6, 0x5d, 0x17, 0x53, 0xba, 0x1f, 0x50, 0xd6, 0x1b, 0xc3, + 0xfb, 0xa0, 0xe2, 0x0e, 0x50, 0x10, 0xf5, 0x03, 0x4f, 0x34, 0x4f, 0xb3, 0x6f, 0xfc, 0xad, 0x6c, + 0xcb, 0x37, 0xf9, 0xee, 0xdb, 0x3b, 0x27, 0x53, 0xa3, 0xec, 0xca, 0xa5, 0x93, 0x2d, 0xbc, 0x05, + 0x2d, 0xf9, 0x73, 0x69, 0x29, 0xfc, 0x73, 0x5a, 0xd4, 0x67, 0xd3, 0x52, 0x5c, 0xa5, 0xa5, 0xf4, + 0xf2, 0x68, 0x29, 0x9f, 0xa1, 0xe5, 0x3e, 0xa8, 0x20, 0xd1, 0x5b, 0x4c, 0xf5, 0x4a, 0xab, 0xd0, + 0xa9, 0x6e, 0x6e, 0x98, 0x4f, 0xbf, 0x0a, 0xa6, 0xec, 0x7e, 0x6f, 0x14, 0x0f, 0xb1, 0xdd, 0x7a, + 0x3c, 0x35, 0x72, 0x27, 0x53, 0x03, 0xa0, 0x53, 0x4a, 0x3e, 0xff, 0xc9, 0x00, 0x0b, 0x82, 0x9c, + 0x53, 0x40, 0xc9, 0xb9, 0xb6, 0xc4, 0x39, 0x58, 0xe2, 0xbc, 0x7a, 0x1e, 0xe7, 0x5f, 0xab, 0xa0, + 0xb6, 0x33, 0x89, 0x50, 0x18, 0xb8, 0x7b, 0x18, 0xff, 0x37, 0x9c, 0xdf, 0x01, 0x55, 0xce, 0x39, + 0x0b, 0xe2, 0xbe, 0x8b, 0xe2, 0x17, 0x60, 0x9d, 0x4b, 0xa6, 0x17, 0xc4, 0x37, 0x51, 0x3c, 0xc7, + 0x3a, 0xc2, 0x58, 0x60, 0xa9, 0x2f, 0x84, 0xb5, 0x87, 0x31, 0xc7, 0xca, 0x24, 0x54, 0x7c, 0xb6, + 0x84, 0x4a, 0xab, 0x12, 0x2a, 0xbf, 0x3c, 0x09, 0x55, 0xce, 0x91, 0x90, 0xf6, 0xaf, 0x48, 0x08, + 0x2c, 0x49, 0xa8, 0xba, 0x24, 0xa1, 0xda, 0x79, 0x12, 0x6a, 0x83, 0xc6, 0xee, 0x98, 0xe1, 0x88, + 0x06, 0x24, 0x7a, 0x27, 0x16, 0x03, 0x66, 0x31, 0x37, 0xb2, 0x07, 0xf9, 0x1b, 0x05, 0x5c, 0x5a, + 0x9a, 0x27, 0x0e, 0xa6, 0x31, 0x89, 0xa8, 0x28, 0x54, 0x8c, 0x04, 0xa1, 0xb5, 0x6c, 0x0a, 0x5c, + 0x01, 0xea, 0x90, 0xf8, 0x54, 0xcf, 0x8b, 0x22, 0x2f, 0xad, 0x16, 0xb9, 0x4f, 0x7c, 0x47, 0x84, + 0xc0, 0x8b, 0xa0, 0x90, 0x60, 0x26, 0x34, 0x53, 0x73, 0xf8, 0x12, 0xd6, 0x41, 0x25, 0x0d, 0xfb, + 0x38, 0x49, 0x48, 0x92, 0xbd, 0xba, 0xe5, 0x34, 0xdc, 0xe5, 0x26, 0x77, 0x71, 0x71, 0x8c, 0x28, + 0xf6, 0x24, 0xab, 0x4e, 0xd9, 0x47, 0xf4, 0x1e, 0xc5, 0x1e, 0xdc, 0x00, 0xe0, 0x70, 0x48, 0xdc, + 0x07, 0x7d, 0x91, 0x8c, 0x7c, 0x4f, 0x35, 0xf1, 0xe5, 0x6d, 0x44, 0x07, 0x59, 0x15, 0x9f, 0x28, + 0xe0, 0xc2, 0x01, 0xf5, 0xef, 0xc5, 0x1e, 0x62, 0xf8, 0x2e, 0x4a, 0x50, 0x48, 0xe1, 0x75, 0xa0, + 0xa1, 0x11, 0x1b, 0x90, 0x24, 0x60, 0x93, 0xec, 0xc2, 0xe8, 0xdf, 0x3d, 0xea, 0xae, 0x67, 0x93, + 0x7b, 0xdb, 0xf3, 0x12, 0x4c, 0xe9, 0xbb, 0x2c, 0x09, 0x22, 0xdf, 0x59, 0x84, 0xc2, 0xeb, 0xa0, + 0x14, 0x0b, 0x04, 0x71, 0x17, 0xaa, 0x9b, 0xfa, 0x6a, 0x95, 0xf2, 0x04, 0x5b, 0xe5, 0x2c, 0x3a, + 0x59, 0xf4, 0xd6, 0xda, 0xc3, 0x5f, 0xbf, 0xb8, 0xba, 0xc0, 0x69, 0xd7, 0xc1, 0xe5, 0xa7, 0x52, + 0x9a, 0xb7, 0x76, 0x73, 0xa6, 0x80, 0xc2, 0x01, 0xf5, 0xe1, 0x87, 0x00, 0x9c, 0x19, 0xe4, 0xc6, + 0xea, 0x41, 0x4b, 0xcc, 0x34, 0x5e, 0x7f, 0x4e, 0xc0, 0x1c, 0xbf, 0xfd, 0xea, 0xc3, 0xef, 0x7f, + 0xf9, 0x34, 0x6f, 0xb4, 0x37, 0xac, 0xd5, 0x3f, 0x26, 0x59, 0x74, 0x9f, 0x8d, 0xe1, 0xfb, 0xa0, + 0xb6, 0xd4, 0xb1, 0x57, 0xfe, 0x14, 0xff, 0x6c, 0x48, 0xe3, 0xca, 0x73, 0x43, 0xe6, 0x49, 0xd8, + 0x37, 0x1e, 0xcf, 0x9a, 0xca, 0x93, 0x59, 0x53, 0xf9, 0x79, 0xd6, 0x54, 0x3e, 0x3e, 0x6e, 0xe6, + 0x9e, 0x1c, 0x37, 0x73, 0x3f, 0x1c, 0x37, 0x73, 0xef, 0x9d, 0xbd, 0x7b, 0x38, 0xe5, 0x57, 0x6f, + 0x91, 0xe6, 0x58, 0x24, 0x2a, 0xee, 0xdf, 0x61, 0x49, 0xfc, 0x87, 0x79, 0xf3, 0x8f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x5f, 0x60, 0x8e, 0xd7, 0xc0, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -669,6 +671,13 @@ func (m *MsgEthereumTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.From) i = encodeVarintTx(dAtA, i, uint64(len(m.From))) i-- + dAtA[i] = 0x2a + } + if len(m.DeprecatedFrom) > 0 { + i -= len(m.DeprecatedFrom) + copy(dAtA[i:], m.DeprecatedFrom) + i = encodeVarintTx(dAtA, i, uint64(len(m.DeprecatedFrom))) + i-- dAtA[i] = 0x22 } if len(m.Hash) > 0 { @@ -1223,6 +1232,10 @@ func (m *MsgEthereumTx) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.DeprecatedFrom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } l = len(m.From) if l > 0 { n += 1 + l + sovTx(uint64(l)) @@ -1566,7 +1579,7 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedFrom", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1594,7 +1607,41 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.From = string(dAtA[iNdEx:postIndex]) + m.DeprecatedFrom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = append(m.From[:0], dAtA[iNdEx:postIndex]...) + if m.From == nil { + m.From = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/evm/types/tx_args.go b/x/evm/types/tx_args.go index f445e23a08..e286b8637b 100644 --- a/x/evm/types/tx_args.go +++ b/x/evm/types/tx_args.go @@ -73,7 +73,8 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx { var ( chainID, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas sdkmath.Int gas, nonce uint64 - from, to string + to string + from []byte ) // Set sender address or use zero address if none specified. @@ -156,7 +157,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx { } if args.From != nil { - from = args.From.Hex() + from = args.From.Bytes() } msg := MsgEthereumTx{ diff --git a/x/evm/types/utils.go b/x/evm/types/utils.go index 91c6c63bcb..3b74fdcda6 100644 --- a/x/evm/types/utils.go +++ b/x/evm/types/utils.go @@ -16,6 +16,7 @@ package types import ( + "encoding/hex" "fmt" "math/big" @@ -181,3 +182,11 @@ func BinSearch(lo, hi uint64, executable func(uint64) (bool, *MsgEthereumTxRespo func EffectiveGasPrice(baseFee *big.Int, feeCap *big.Int, tipCap *big.Int) *big.Int { return math.BigMin(new(big.Int).Add(tipCap, baseFee), feeCap) } + +// HexAddress encode ethereum address without checksum, faster to run for state machine +func HexAddress(a []byte) string { + var buf [common.AddressLength*2 + 2]byte + copy(buf[:2], "0x") + hex.Encode(buf[2:], a) + return string(buf[:]) +} diff --git a/x/feemarket/keeper/integration_test.go b/x/feemarket/keeper/integration_test.go index 66545defae..5996e416d9 100644 --- a/x/feemarket/keeper/integration_test.go +++ b/x/feemarket/keeper/integration_test.go @@ -554,7 +554,7 @@ func buildEthTx( data, accesses, ) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() return msgEthereumTx } @@ -571,7 +571,6 @@ func prepareEthTx(priv *ethsecp256k1.PrivKey, msgEthereumTx *evmtypes.MsgEthereu err = msgEthereumTx.Sign(s.ethSigner, tests.NewSigner(priv)) s.Require().NoError(err) - msgEthereumTx.From = "" err = txBuilder.SetMsgs(msgEthereumTx) s.Require().NoError(err)