diff --git a/app/ante/ante_test.go b/app/ante/ante_test.go index bca6bfa7e4..ee5195324e 100644 --- a/app/ante/ante_test.go +++ b/app/ante/ante_test.go @@ -315,10 +315,10 @@ func (suite *AnteTestSuite) TestAnteHandler() { txBuilder := suite.CreateTestTxBuilder(signedTx, privKey, 1, false) - txData, err := evmtypes.UnpackTxData(signedTx.Data) - suite.Require().NoError(err) + txData := signedTx.AsTransaction() + suite.Require().NotNil(txData) - expFee := txData.Fee() + expFee := signedTx.GetFee() invalidFee := new(big.Int).Add(expFee, big.NewInt(1)) invalidFeeAmount := sdk.Coins{sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewIntFromBigInt(invalidFee))} txBuilder.SetFeeAmount(invalidFeeAmount) diff --git a/app/ante/eth.go b/app/ante/eth.go index 2622733461..8d86c3404e 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -47,16 +47,13 @@ func VerifyEthAccount( return nil } - for i, msg := range tx.GetMsgs() { + for _, msg := range tx.GetMsgs() { msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) if !ok { return errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - txData, err := evmtypes.UnpackTxData(msgEthTx.Data) - if err != nil { - return errorsmod.Wrapf(err, "failed to unpack tx data any for tx %d", i) - } + ethTx := msgEthTx.AsTransaction() // sender address should be in the tx cache from the previous AnteHandle call from := msgEthTx.GetFrom() @@ -76,8 +73,8 @@ func VerifyEthAccount( "the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash) } - balance := evmKeeper.GetBalance(ctx, sdk.AccAddress(fromAddr.Bytes()), evmDenom) - if err := keeper.CheckSenderBalance(sdkmath.NewIntFromBigInt(balance), txData); err != nil { + balance := evmKeeper.GetBalance(ctx, from, evmDenom) + if err := keeper.CheckSenderBalance(sdkmath.NewIntFromBigIntMut(balance), ethTx); err != nil { return errorsmod.Wrap(err, "failed to check sender balance") } } @@ -119,26 +116,22 @@ func CheckEthGasConsume( return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - txData, err := evmtypes.UnpackTxData(msgEthTx.Data) - if err != nil { - return ctx, errorsmod.Wrap(err, "failed to unpack tx data") - } - - priority := evmtypes.GetTxPriority(txData, baseFee) + priority := evmtypes.GetTxPriority(msgEthTx, baseFee) if priority < minPriority { minPriority = priority } + gasLimit := msgEthTx.GetGas() if ctx.IsCheckTx() && maxGasWanted != 0 { // We can't trust the tx gas limit, because we'll refund the unused gas. - if txData.GetGas() > maxGasWanted { + if gasLimit > maxGasWanted { gasWanted += maxGasWanted } else { - gasWanted += txData.GetGas() + gasWanted += gasLimit } } else { - gasWanted += txData.GetGas() + gasWanted += gasLimit } // user balance is already checked during CheckTx so there's no need to @@ -147,7 +140,7 @@ func CheckEthGasConsume( continue } - fees, err := keeper.VerifyFee(txData, evmDenom, baseFee, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai, ctx.IsCheckTx()) + fees, err := keeper.VerifyFee(msgEthTx, evmDenom, baseFee, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai, ctx.IsCheckTx()) if err != nil { return ctx, errorsmod.Wrapf(err, "failed to verify the fees") } @@ -212,14 +205,7 @@ func CheckEthCanTransfer( return errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - coreMsg, err := msgEthTx.AsMessage(baseFee) - if err != nil { - return errorsmod.Wrapf( - err, - "failed to create an ethereum core.Message", - ) - } - + tx := msgEthTx.AsTransaction() if rules.IsLondon { if baseFee == nil { return errorsmod.Wrap( @@ -227,23 +213,24 @@ func CheckEthCanTransfer( "base fee is supported but evm block context value is nil", ) } - if coreMsg.GasFeeCap.Cmp(baseFee) < 0 { + if tx.GasFeeCap().Cmp(baseFee) < 0 { return errorsmod.Wrapf( errortypes.ErrInsufficientFee, "max fee per gas less than block base fee (%s < %s)", - coreMsg.GasFeeCap, baseFee, + tx.GasFeeCap(), baseFee, ) } } + from := common.BytesToAddress(msgEthTx.From) // check that caller has enough balance to cover asset transfer for **topmost** call // NOTE: here the gas consumed is from the context with the infinite gas meter - if coreMsg.Value.Sign() > 0 && !canTransfer(ctx, evmKeeper, evmParams.EvmDenom, coreMsg.From, coreMsg.Value) { + if tx.Value().Sign() > 0 && !canTransfer(ctx, evmKeeper, evmParams.EvmDenom, from, tx.Value()) { return errorsmod.Wrapf( errortypes.ErrInsufficientFunds, "failed to transfer %s from address %s using the EVM block context transfer function", - coreMsg.Value, - coreMsg.From, + tx.Value(), + from, ) } } @@ -269,10 +256,7 @@ func CheckEthSenderNonce( return errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil)) } - txData, err := evmtypes.UnpackTxData(msgEthTx.Data) - if err != nil { - return errorsmod.Wrap(err, "failed to unpack tx data") - } + tx := msgEthTx.AsTransaction() // increase sequence of sender acc := ak.GetAccount(ctx, msgEthTx.GetFrom()) @@ -286,10 +270,10 @@ func CheckEthSenderNonce( // we merged the nonce verification to nonce increment, so when tx includes multiple messages // with same sender, they'll be accepted. - if txData.GetNonce() != nonce { + if tx.Nonce() != nonce { return errorsmod.Wrapf( errortypes.ErrInvalidSequence, - "invalid nonce; got %d, expected %d", txData.GetNonce(), nonce, + "invalid nonce; got %d, expected %d", tx.Nonce(), nonce, ) } diff --git a/app/ante/eth_test.go b/app/ante/eth_test.go index ac329be5de..93a3da1eea 100644 --- a/app/ante/eth_test.go +++ b/app/ante/eth_test.go @@ -489,11 +489,11 @@ func (suite *AnteTestSuite) TestEthIncrementSenderSequenceDecorator() { suite.Require().NoError(err) msg := tc.tx.(*evmtypes.MsgEthereumTx) - txData, err := evmtypes.UnpackTxData(msg.Data) - suite.Require().NoError(err) + txData := msg.AsTransaction() + suite.Require().NotNil(txData) nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, addr) - suite.Require().Equal(txData.GetNonce()+1, nonce) + suite.Require().Equal(txData.Nonce()+1, nonce) } else { suite.Require().Error(err) } diff --git a/app/ante/fees.go b/app/ante/fees.go index 3c249b0a49..d5946683df 100644 --- a/app/ante/fees.go +++ b/app/ante/fees.go @@ -23,7 +23,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" - ethtypes "github.com/ethereum/go-ethereum/core/types" evmtypes "github.com/evmos/ethermint/x/evm/types" feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" ) @@ -114,8 +113,6 @@ func CheckEthMinGasPrice(tx sdk.Tx, minGasPrice sdkmath.LegacyDec, baseFee *big. ) } - feeAmt := ethMsg.GetFee() - // For dynamic transactions, GetFee() uses the GasFeeCap value, which // is the maximum gas price that the signer can pay. In practice, the // signer can pay less, if the block's BaseFee is lower. So, in this case, @@ -124,15 +121,7 @@ func CheckEthMinGasPrice(tx sdk.Tx, minGasPrice sdkmath.LegacyDec, baseFee *big. // increase the GasTipCap (priority fee) until EffectivePrice > MinGasPrices. // Transactions with MinGasPrices * gasUsed < tx fees < EffectiveFee are rejected // by the feemarket AnteHandle - - txData, err := evmtypes.UnpackTxData(ethMsg.Data) - if err != nil { - return errorsmod.Wrapf(err, "failed to unpack tx data %s", ethMsg.Hash) - } - - if txData.TxType() != ethtypes.LegacyTxType { - feeAmt = ethMsg.GetEffectiveFee(baseFee) - } + feeAmt := ethMsg.GetEffectiveFee(baseFee) gasLimit := sdkmath.LegacyNewDecFromBigInt(new(big.Int).SetUint64(ethMsg.GetGas())) diff --git a/app/ante/setup.go b/app/ante/setup.go index d8d6c822d9..eb61eb96c2 100644 --- a/app/ante/setup.go +++ b/app/ante/setup.go @@ -107,30 +107,25 @@ func ValidateEthBasic(ctx sdk.Context, tx sdk.Tx, evmParams *evmtypes.Params, ba txGasLimit += msgEthTx.GetGas() - txData, err := evmtypes.UnpackTxData(msgEthTx.Data) - if err != nil { - return errorsmod.Wrap(err, "failed to unpack MsgEthereumTx Data") - } - + tx := msgEthTx.AsTransaction() // return error if contract creation or call are disabled through governance - if !enableCreate && txData.GetTo() == nil { + if !enableCreate && tx.To() == nil { return errorsmod.Wrap(evmtypes.ErrCreateDisabled, "failed to create new contract") - } else if !enableCall && txData.GetTo() != nil { + } else if !enableCall && tx.To() != nil { return errorsmod.Wrap(evmtypes.ErrCallDisabled, "failed to call contract") } - if baseFee == nil && txData.TxType() == ethtypes.DynamicFeeTxType { + if baseFee == nil && tx.Type() == ethtypes.DynamicFeeTxType { return errorsmod.Wrap(ethtypes.ErrTxTypeNotSupported, "dynamic fee tx not supported") } - ethTx := ethtypes.NewTx(txData.AsEthereumData()) - if !allowUnprotectedTxs && !ethTx.Protected() { + if !allowUnprotectedTxs && !tx.Protected() { return errorsmod.Wrapf( errortypes.ErrNotSupported, "rejected unprotected Ethereum transaction. Please EIP155 sign your transaction to protect it against replay-attacks") } - txFee = txFee.Add(sdk.Coin{Denom: evmDenom, Amount: sdkmath.NewIntFromBigInt(txData.Fee())}) + txFee = txFee.Add(sdk.Coin{Denom: evmDenom, Amount: sdkmath.NewIntFromBigInt(msgEthTx.GetFee())}) } if !authInfo.Fee.Amount.Equal(txFee) { diff --git a/app/ante/sigs_test.go b/app/ante/sigs_test.go index 8b0deab64c..16506815ac 100644 --- a/app/ante/sigs_test.go +++ b/app/ante/sigs_test.go @@ -32,10 +32,10 @@ func (suite *AnteTestSuite) TestSignatures() { // signatures of cosmos tx should be empty suite.Require().Equal(len(sigs), 0) - txData, err := evmtypes.UnpackTxData(msgEthereumTx.Data) - suite.Require().NoError(err) + txData := msgEthereumTx.AsTransaction() + suite.Require().NotNil(txData) - msgV, msgR, msgS := txData.GetRawSignatureValues() + msgV, msgR, msgS := txData.RawSignatureValues() ethTx := msgEthereumTx.AsTransaction() ethV, ethR, ethS := ethTx.RawSignatureValues() diff --git a/app/ante/utils_test.go b/app/ante/utils_test.go index 99a917124f..4cfae9ed6c 100644 --- a/app/ante/utils_test.go +++ b/app/ante/utils_test.go @@ -231,10 +231,10 @@ func (suite *AnteTestSuite) CreateTestTxBuilder( err = builder.SetMsgs(msg) suite.Require().NoError(err) - txData, err := evmtypes.UnpackTxData(msg.Data) - suite.Require().NoError(err) + txData := msg.AsTransaction() + suite.Require().NotNil(txData) - fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewIntFromBigInt(txData.Fee()))) + fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewIntFromBigInt(msg.GetFee()))) builder.SetFeeAmount(fees) builder.SetGasLimit(msg.GetGas()) @@ -250,7 +250,7 @@ func (suite *AnteTestSuite) CreateTestTxBuilder( SignMode: defaultSignMode, Signature: nil, }, - Sequence: txData.GetNonce(), + Sequence: txData.Nonce(), } sigsV2 := []signing.SignatureV2{sigV2} @@ -263,12 +263,12 @@ func (suite *AnteTestSuite) CreateTestTxBuilder( signerData := authsigning.SignerData{ ChainID: suite.ctx.ChainID(), AccountNumber: accNum, - Sequence: txData.GetNonce(), + Sequence: txData.Nonce(), } sigV2, err = tx.SignWithPrivKey( suite.ctx, defaultSignMode, signerData, - txBuilder, priv, suite.clientCtx.TxConfig, txData.GetNonce(), + txBuilder, priv, suite.clientCtx.TxConfig, txData.Nonce(), ) suite.Require().NoError(err) diff --git a/app/signer.go b/app/signer.go index 854e3b388b..c55b1a84a3 100644 --- a/app/signer.go +++ b/app/signer.go @@ -28,14 +28,10 @@ func (s EthSignerExtractionAdapter) GetSigners(tx sdk.Tx) ([]mempool.SignerData, if len(opts) > 0 && opts[0].GetTypeUrl() == "/ethermint.evm.v1.ExtensionOptionsEthereumTx" { for _, msg := range tx.GetMsgs() { if ethMsg, ok := msg.(*evmtypes.MsgEthereumTx); ok { - txData, err := evmtypes.UnpackTxData(ethMsg.Data) - if err != nil { - return nil, err - } return []mempool.SignerData{ mempool.NewSignerData( - sdk.AccAddress(ethMsg.From), - txData.GetNonce(), + ethMsg.GetFrom(), + ethMsg.AsTransaction().Nonce(), ), }, nil } diff --git a/go.mod b/go.mod index 747b5473ea..4953131888 100644 --- a/go.mod +++ b/go.mod @@ -253,7 +253,8 @@ replace ( // use cosmos keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/cockroachdb/pebble => github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 - github.com/ethereum/go-ethereum => github.com/crypto-org-chain/go-ethereum v1.10.20-0.20231207063621-43cf32d91c3e + // release/v1.11.x + github.com/ethereum/go-ethereum => github.com/crypto-org-chain/go-ethereum v1.10.20-0.20240425065928-ebb09502e7a7 // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0 diff --git a/go.sum b/go.sum index 79d3644a3c..5098e35925 100644 --- a/go.sum +++ b/go.sum @@ -421,8 +421,8 @@ github.com/crypto-org-chain/cosmos-sdk/x/tx v0.0.0-20240415105151-0108877a3201 h github.com/crypto-org-chain/cosmos-sdk/x/tx v0.0.0-20240415105151-0108877a3201/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= github.com/crypto-org-chain/go-block-stm v0.0.0-20240408011717-9f11af197bde h1:sQIHTJfVt5VTrF7po9eZiFkZiPjlHbFvnXtGCOoBjNM= github.com/crypto-org-chain/go-block-stm v0.0.0-20240408011717-9f11af197bde/go.mod h1:iwQTX9xMX8NV9k3o2BiWXA0SswpsZrDk5q3gA7nWYiE= -github.com/crypto-org-chain/go-ethereum v1.10.20-0.20231207063621-43cf32d91c3e h1:vnyepPQ/m25+19xcTuBUdRxmltZ/EjVWNqEjhg7Ummk= -github.com/crypto-org-chain/go-ethereum v1.10.20-0.20231207063621-43cf32d91c3e/go.mod h1:+a8pUj1tOyJ2RinsNQD4326YS+leSoKGiG/uVVb0x6Y= +github.com/crypto-org-chain/go-ethereum v1.10.20-0.20240425065928-ebb09502e7a7 h1:V43F3JFcqG4MUThf9W/DytnPblpR6CcaLBw2Wx6zTgE= +github.com/crypto-org-chain/go-ethereum v1.10.20-0.20240425065928-ebb09502e7a7/go.mod h1:+a8pUj1tOyJ2RinsNQD4326YS+leSoKGiG/uVVb0x6Y= github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/gomod2nix.toml b/gomod2nix.toml index 762baeeff5..cce5e66341 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -248,8 +248,8 @@ schema = 3 version = "v1.6.1" hash = "sha256-zOpoaepCfPLmU9iQji/Ait+SVEHI9eF3rwtW0h/8lho=" [mod."github.com/ethereum/go-ethereum"] - version = "v1.10.20-0.20231207063621-43cf32d91c3e" - hash = "sha256-lDIqRLUrXYCb9mmFBY/+WW+ee69+IkxOgqjHVyo4ij0=" + version = "v1.10.20-0.20240425065928-ebb09502e7a7" + hash = "sha256-lE4G5FaRb3MVi9FFVn+WlwsSTOB4SbjmVboKyQ5yB0A=" replaced = "github.com/crypto-org-chain/go-ethereum" [mod."github.com/fatih/color"] version = "v1.16.0" diff --git a/indexer/kv_indexer.go b/indexer/kv_indexer.go index cb0c5bab64..7849418021 100644 --- a/indexer/kv_indexer.go +++ b/indexer/kv_indexer.go @@ -62,7 +62,7 @@ func NewKVIndexer(db dbm.DB, logger log.Logger, clientCtx client.Context) *KVInd // - Iterates over all the messages of the Tx // - Builds and stores a indexer.TxResult based on parsed events for every message func (kv *KVIndexer) IndexBlock(block *tmtypes.Block, txResults []*abci.ExecTxResult) error { - height := block.Header.Height + height := block.Height batch := kv.db.NewBatch() defer batch.Close() @@ -94,7 +94,7 @@ func (kv *KVIndexer) IndexBlock(block *tmtypes.Block, txResults []*abci.ExecTxRe var cumulativeGasUsed uint64 for msgIndex, msg := range tx.GetMsgs() { ethMsg := msg.(*evmtypes.MsgEthereumTx) - txHash := common.HexToHash(ethMsg.Hash) + var txHash common.Hash txResult := ethermint.TxResult{ Height: height, @@ -107,6 +107,7 @@ func (kv *KVIndexer) IndexBlock(block *tmtypes.Block, txResults []*abci.ExecTxRe // some old versions don't emit any events, so workaround here directly. txResult.GasUsed = ethMsg.GetGas() txResult.Failed = true + txHash = ethMsg.Hash() } else { parsedTx := txs.GetTxByMsgIndex(msgIndex) if parsedTx == nil { @@ -118,6 +119,7 @@ func (kv *KVIndexer) IndexBlock(block *tmtypes.Block, txResults []*abci.ExecTxRe } txResult.GasUsed = parsedTx.GasUsed txResult.Failed = parsedTx.Failed + txHash = parsedTx.Hash } cumulativeGasUsed += txResult.GasUsed diff --git a/indexer/kv_indexer_test.go b/indexer/kv_indexer_test.go index 30443b70fa..ac0971ca06 100644 --- a/indexer/kv_indexer_test.go +++ b/indexer/kv_indexer_test.go @@ -88,6 +88,7 @@ func TestKVIndexer(t *testing.T) { {Key: "txIndex", Value: "0"}, }}, {Type: types.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ + {Key: "ethereumTxHash", Value: txHash.Hex()}, {Key: "amount", Value: "1000"}, {Key: "txGasUsed", Value: "21000"}, {Key: "txHash", Value: "14A84ED06282645EFBF080E0B7ED80D8D8D6A36337668A12B5F229F81CDD3F57"}, diff --git a/proto/ethermint/evm/v1/tx.proto b/proto/ethermint/evm/v1/tx.proto index fbc2434f69..cea3279399 100644 --- a/proto/ethermint/evm/v1/tx.proto +++ b/proto/ethermint/evm/v1/tx.proto @@ -35,12 +35,14 @@ message MsgEthereumTx { // size is the encoded storage size of the transaction (DEPRECATED) double size = 2 [(gogoproto.jsontag) = "-"]; // hash of the transaction in hex format - string hash = 3 [(gogoproto.moretags) = "rlp:\"-\""]; + string deprecated_hash = 3 [(gogoproto.moretags) = "rlp:\"-\""]; 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 bytes from = 5; + // raw is the raw bytes of the ethereum transaction + bytes raw = 6 [(gogoproto.customtype) = "EthereumTx", (gogoproto.nullable) = false]; } // 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 7694574684..a7419524ad 100644 --- a/rpc/backend/backend_suite_test.go +++ b/rpc/backend/backend_suite_test.go @@ -109,13 +109,16 @@ func (suite *BackendTestSuite) buildEthereumTx() (*evmtypes.MsgEthereumTx, []byt err := msgEthereumTx.Sign(ethtypes.LatestSignerForChainID(suite.backend.chainID), suite.signer) suite.Require().NoError(err) - txBuilder := suite.backend.clientCtx.TxConfig.NewTxBuilder() - err = txBuilder.SetMsgs(msgEthereumTx) + tx, err := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") + suite.Require().NoError(err) + + bz, err := suite.backend.clientCtx.TxConfig.TxEncoder()(tx) suite.Require().NoError(err) - bz, err := suite.backend.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) + sdkTx, err := suite.backend.clientCtx.TxConfig.TxDecoder()(bz) suite.Require().NoError(err) - return msgEthereumTx, bz + + return sdkTx.GetMsgs()[0].(*evmtypes.MsgEthereumTx), bz } // buildFormattedBlock returns a formatted block for testing @@ -149,7 +152,7 @@ func (suite *BackendTestSuite) buildFormattedBlock( suite.Require().NoError(err) ethRPCTxs = []interface{}{rpcTx} } else { - ethRPCTxs = []interface{}{common.HexToHash(tx.Hash)} + ethRPCTxs = []interface{}{tx.Hash()} } } @@ -186,8 +189,7 @@ func (suite *BackendTestSuite) signAndEncodeEthTx(msgEthereumTx *evmtypes.MsgEth tx, err := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") suite.Require().NoError(err) - txEncoder := suite.backend.clientCtx.TxConfig.TxEncoder() - txBz, err := txEncoder(tx) + txBz, err := suite.backend.clientCtx.TxConfig.TxEncoder()(tx) suite.Require().NoError(err) return txBz diff --git a/rpc/backend/blocks.go b/rpc/backend/blocks.go index 87cf7d5226..fe946ebfc1 100644 --- a/rpc/backend/blocks.go +++ b/rpc/backend/blocks.go @@ -288,7 +288,6 @@ func (b *Backend) EthMsgsFromTendermintBlock( continue } - ethMsg.Hash = ethMsg.AsTransaction().Hash().Hex() result = append(result, ethMsg) } } @@ -392,8 +391,7 @@ func (b *Backend) RPCBlockFromTendermintBlock( msgs := b.EthMsgsFromTendermintBlock(resBlock, blockRes) for txIndex, ethMsg := range msgs { if !fullTx { - hash := common.HexToHash(ethMsg.Hash) - ethRPCTxs = append(ethRPCTxs, hash) + ethRPCTxs = append(ethRPCTxs, ethMsg.Hash()) continue } diff --git a/rpc/backend/blocks_test.go b/rpc/backend/blocks_test.go index 1d74a24658..431a10629c 100644 --- a/rpc/backend/blocks_test.go +++ b/rpc/backend/blocks_test.go @@ -1094,7 +1094,7 @@ func (suite *BackendTestSuite) TestGetEthBlockFromTendermint() { suite.Require().NoError(err) ethRPCTxs = []interface{}{rpcTx} } else { - ethRPCTxs = []interface{}{common.HexToHash(msgEthereumTx.Hash)} + ethRPCTxs = []interface{}{msgEthereumTx.Hash()} } } @@ -1503,7 +1503,11 @@ func (suite *BackendTestSuite) TestEthBlockByNumber() { suite.Require().Equal(tc.expEthBlock.Uncles(), ethBlock.Uncles()) suite.Require().Equal(tc.expEthBlock.ReceiptHash(), ethBlock.ReceiptHash()) for i, tx := range tc.expEthBlock.Transactions() { - suite.Require().Equal(tx.Data(), ethBlock.Transactions()[i].Data()) + bz, err := tx.MarshalBinary() + suite.Require().NoError(err) + expBz, err := ethBlock.Transactions()[i].MarshalBinary() + suite.Require().NoError(err) + suite.Require().Equal(bz, expBz) } } else { diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index 1c62e905b2..f9be170c78 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -118,7 +118,7 @@ func (b *Backend) Resend(args evmtypes.TransactionArgs, gasPrice *hexutil.Big, g // SendRawTransaction send a raw Ethereum transaction. func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { // RLP decode raw transaction bytes - tx := ðtypes.Transaction{} + var tx ethtypes.Transaction if err := tx.UnmarshalBinary(data); err != nil { b.logger.Error("transaction decoding failed", "error", err.Error()) return common.Hash{}, err @@ -130,8 +130,8 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") } - ethereumTx := &evmtypes.MsgEthereumTx{} - if err := ethereumTx.FromSignedEthereumTx(tx, ethtypes.LatestSignerForChainID(b.chainID)); err != nil { + var ethereumTx evmtypes.MsgEthereumTx + if err := ethereumTx.FromSignedEthereumTx(&tx, ethtypes.LatestSignerForChainID(b.chainID)); err != nil { b.logger.Error("transaction converting failed", "error", err.Error()) return common.Hash{}, err } @@ -142,7 +142,7 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { } // Query params to use the EVM denomination - res, err := b.queryClient.QueryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}) + res, err := b.queryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}) if err != nil { b.logger.Error("failed to query evm params", "error", err.Error()) return common.Hash{}, err @@ -161,7 +161,7 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { return common.Hash{}, err } - txHash := ethereumTx.AsTransaction().Hash() + txHash := ethereumTx.Hash() syncCtx := b.clientCtx.WithBroadcastMode(flags.BroadcastSync) rsp, err := syncCtx.BroadcastTx(txBytes) diff --git a/rpc/backend/call_tx_test.go b/rpc/backend/call_tx_test.go index dcca7109de..dc2865791d 100644 --- a/rpc/backend/call_tx_test.go +++ b/rpc/backend/call_tx_test.go @@ -328,7 +328,7 @@ func (suite *BackendTestSuite) TestSendRawTransaction() { RegisterBroadcastTxError(client, txBytes) }, rlpEncodedBz, - common.HexToHash(ethTx.Hash), + ethTx.Hash(), false, }, { @@ -341,7 +341,7 @@ func (suite *BackendTestSuite) TestSendRawTransaction() { RegisterBroadcastTx(client, txBytes) }, rlpEncodedBz, - common.HexToHash(ethTx.Hash), + ethTx.Hash(), true, }, } diff --git a/rpc/backend/tracing_test.go b/rpc/backend/tracing_test.go index 83d8bc1060..78f2284aaa 100644 --- a/rpc/backend/tracing_test.go +++ b/rpc/backend/tracing_test.go @@ -5,12 +5,12 @@ import ( "fmt" "math/big" - dbm "github.com/cosmos/cosmos-db" - abci "github.com/cometbft/cometbft/abci/types" tmlog "cosmossdk.io/log" + abci "github.com/cometbft/cometbft/abci/types" tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/cometbft/cometbft/types" tmtypes "github.com/cometbft/cometbft/types" + dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/cosmos-sdk/crypto" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -41,17 +41,32 @@ func (suite *BackendTestSuite) TestTraceTransaction() { ethSigner := ethtypes.LatestSigner(suite.backend.ChainConfig()) txEncoder := suite.backend.clientCtx.TxConfig.TxEncoder() + txDecoder := suite.backend.clientCtx.TxConfig.TxDecoder() msgEthereumTx.From = from.Bytes() msgEthereumTx.Sign(ethSigner, suite.signer) - tx, _ := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") - txBz, _ := txEncoder(tx) + tx, err := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") + suite.Require().NoError(err) + txBz, err := txEncoder(tx) + suite.Require().NoError(err) msgEthereumTx2.From = from.Bytes() msgEthereumTx2.Sign(ethSigner, suite.signer) - tx2, _ := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") + tx2, _ := msgEthereumTx2.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton") txBz2, _ := txEncoder(tx2) + { + tx, err := txDecoder(txBz) + suite.Require().NoError(err) + msgEthereumTx = tx.GetMsgs()[0].(*evmtypes.MsgEthereumTx) + } + + { + tx, err := txDecoder(txBz) + suite.Require().NoError(err) + msgEthereumTx2 = tx.GetMsgs()[0].(*evmtypes.MsgEthereumTx) + } + testCases := []struct { name string registerMock func() diff --git a/rpc/backend/tx_info.go b/rpc/backend/tx_info.go index f45f7d362c..13ee8638e7 100644 --- a/rpc/backend/tx_info.go +++ b/rpc/backend/tx_info.go @@ -35,8 +35,6 @@ import ( // GetTransactionByHash returns the Ethereum format transaction identified by Ethereum transaction hash func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransaction, error) { res, err := b.GetTxByEthHash(txHash) - hexTx := txHash.Hex() - if err != nil { return b.getTransactionByHashPending(txHash) } @@ -67,7 +65,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac // Fallback to find tx index by iterating all valid eth transactions msgs := b.EthMsgsFromTendermintBlock(block, blockRes) for i := range msgs { - if msgs[i].Hash == hexTx { + if msgs[i].Hash() == txHash { res.EthTxIndex = int32(i) break } @@ -96,11 +94,10 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac // getTransactionByHashPending find pending tx from mempool func (b *Backend) getTransactionByHashPending(txHash common.Hash) (*rpctypes.RPCTransaction, error) { - hexTx := txHash.Hex() // try to find tx in mempool txs, err := b.PendingTransactions() if err != nil { - b.logger.Debug("tx not found", "hash", hexTx, "error", err.Error()) + b.logger.Debug("tx not found", "hash", txHash, "error", err.Error()) return nil, nil } @@ -111,7 +108,7 @@ func (b *Backend) getTransactionByHashPending(txHash common.Hash) (*rpctypes.RPC continue } - if msg.Hash == hexTx { + if msg.Hash() == txHash { // use zero block values since it's not included in a block yet rpctx, err := rpctypes.NewTransactionFromMsg( msg, @@ -128,7 +125,7 @@ func (b *Backend) getTransactionByHashPending(txHash common.Hash) (*rpctypes.RPC } } - b.logger.Debug("tx not found", "hash", hexTx) + b.logger.Debug("tx not found", "hash", txHash) return nil, nil } @@ -145,12 +142,11 @@ func (b *Backend) GetGasUsed(res *ethermint.TxResult, gas uint64) uint64 { // GetTransactionReceipt returns the transaction receipt identified by hash. func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { - hexTx := hash.Hex() - b.logger.Debug("eth_getTransactionReceipt", "hash", hexTx) + b.logger.Debug("eth_getTransactionReceipt", "hash", hash) res, err := b.GetTxByEthHash(hash) if err != nil { - b.logger.Debug("tx not found", "hash", hexTx, "error", err.Error()) + b.logger.Debug("tx not found", "hash", hash, "error", err.Error()) return nil, nil } resBlock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(res.Height)) @@ -165,9 +161,9 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ } ethMsg := tx.GetMsgs()[res.MsgIndex].(*evmtypes.MsgEthereumTx) - txData, err := evmtypes.UnpackTxData(ethMsg.Data) - if err != nil { - b.logger.Error("failed to unpack tx data", "error", err.Error()) + txData := ethMsg.AsTransaction() + if txData == nil { + b.logger.Error("failed to unpack tx data") return nil, err } @@ -201,14 +197,14 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ // parse tx logs from events logs, err := evmtypes.DecodeMsgLogsFromEvents(blockRes.TxsResults[res.TxIndex].Data, int(res.MsgIndex), uint64(blockRes.Height)) if err != nil { - b.logger.Debug("failed to parse logs", "hash", hexTx, "error", err.Error()) + b.logger.Debug("failed to parse logs", "hash", hash, "error", err.Error()) } if res.EthTxIndex == -1 { // Fallback to find tx index by iterating all valid eth transactions msgs := b.EthMsgsFromTendermintBlock(resBlock, blockRes) for i := range msgs { - if msgs[i].Hash == hexTx { + if msgs[i].Hash() == hash { res.EthTxIndex = int32(i) break } @@ -230,7 +226,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ // They are stored in the chain database. "transactionHash": hash, "contractAddress": nil, - "gasUsed": hexutil.Uint64(b.GetGasUsed(res, txData.GetGas())), + "gasUsed": hexutil.Uint64(b.GetGasUsed(res, txData.Gas())), // Inclusion information: These fields provide information about the inclusion of the // transaction corresponding to this receipt. @@ -240,7 +236,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ // sender and receiver (contract or EOA) addreses "from": from, - "to": txData.GetTo(), + "to": txData.To(), "type": hexutil.Uint(ethMsg.AsTransaction().Type()), } @@ -249,17 +245,17 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ } // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation - if txData.GetTo() == nil { - receipt["contractAddress"] = crypto.CreateAddress(from, txData.GetNonce()) + if txData.To() == nil { + receipt["contractAddress"] = crypto.CreateAddress(from, txData.Nonce()) } - if dynamicTx, ok := txData.(*evmtypes.DynamicFeeTx); ok { + if txData.Type() == ethtypes.DynamicFeeTxType { baseFee, err := b.BaseFee(blockRes) if err != nil { // tolerate the error for pruned node. b.logger.Error("fetch basefee failed, node is pruned?", "height", res.Height, "error", err) } else { - receipt["effectiveGasPrice"] = hexutil.Big(*dynamicTx.EffectiveGasPrice(baseFee)) + receipt["effectiveGasPrice"] = hexutil.Big(*ethMsg.GetEffectiveGasPrice(baseFee)) } } diff --git a/rpc/backend/tx_info_test.go b/rpc/backend/tx_info_test.go index d9812592b6..fd0471303f 100644 --- a/rpc/backend/tx_info_test.go +++ b/rpc/backend/tx_info_test.go @@ -22,9 +22,8 @@ import ( func (suite *BackendTestSuite) TestGetTransactionByHash() { msgEthereumTx, _ := suite.buildEthereumTx() - txHash := msgEthereumTx.AsTransaction().Hash() - txBz := suite.signAndEncodeEthTx(msgEthereumTx) + txHash := msgEthereumTx.Hash() block := &types.Block{Header: types.Header{Height: 1, ChainID: "test"}, Data: types.Data{Txs: []types.Tx{txBz}}} responseDeliver := []*abci.ExecTxResult{ { @@ -110,7 +109,7 @@ func (suite *BackendTestSuite) TestGetTransactionByHash() { err := suite.backend.indexer.IndexBlock(block, responseDeliver) suite.Require().NoError(err) - rpcTx, err := suite.backend.GetTransactionByHash(common.HexToHash(tc.tx.Hash)) + rpcTx, err := suite.backend.GetTransactionByHash(tc.tx.Hash()) if tc.expPass { suite.Require().NoError(err) @@ -170,7 +169,7 @@ func (suite *BackendTestSuite) TestGetTransactionsByHashPending() { suite.SetupTest() // reset tc.registerMock() - rpcTx, err := suite.backend.getTransactionByHashPending(common.HexToHash(tc.tx.Hash)) + rpcTx, err := suite.backend.getTransactionByHashPending(tc.tx.Hash()) if tc.expPass { suite.Require().NoError(err) @@ -198,7 +197,7 @@ func (suite *BackendTestSuite) TestGetTxByEthHash() { func() { suite.backend.indexer = nil client := suite.backend.clientCtx.Client.(*mocks.Client) - query := fmt.Sprintf("%s.%s='%s'", evmtypes.TypeMsgEthereumTx, evmtypes.AttributeKeyEthereumTxHash, common.HexToHash(msgEthereumTx.Hash).Hex()) + query := fmt.Sprintf("%s.%s='%s'", evmtypes.TypeMsgEthereumTx, evmtypes.AttributeKeyEthereumTxHash, msgEthereumTx.Hash().Hex()) RegisterTxSearch(client, query, bz) }, msgEthereumTx, @@ -212,7 +211,7 @@ func (suite *BackendTestSuite) TestGetTxByEthHash() { suite.SetupTest() // reset tc.registerMock() - rpcTx, err := suite.backend.GetTxByEthHash(common.HexToHash(tc.tx.Hash)) + rpcTx, err := suite.backend.GetTxByEthHash(tc.tx.Hash()) if tc.expPass { suite.Require().NoError(err) @@ -283,7 +282,7 @@ func (suite *BackendTestSuite) TestGetTransactionByBlockAndIndex() { Code: 0, Events: []abci.Event{ {Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: common.HexToHash(msgEthTx.Hash).Hex()}, + {Key: "ethereumTxHash", Value: msgEthTx.Hash().Hex()}, {Key: "txIndex", Value: "0"}, {Key: "amount", Value: "1000"}, {Key: "txGasUsed", Value: "21000"}, @@ -532,9 +531,8 @@ func (suite *BackendTestSuite) TestQueryTendermintTxIndexer() { func (suite *BackendTestSuite) TestGetTransactionReceipt() { msgEthereumTx, _ := suite.buildEthereumTx() - txHash := msgEthereumTx.AsTransaction().Hash() - txBz := suite.signAndEncodeEthTx(msgEthereumTx) + txHash := msgEthereumTx.Hash() testCases := []struct { name string @@ -588,7 +586,7 @@ func (suite *BackendTestSuite) TestGetTransactionReceipt() { err := suite.backend.indexer.IndexBlock(tc.block, tc.blockResult) suite.Require().NoError(err) - txReceipt, err := suite.backend.GetTransactionReceipt(common.HexToHash(tc.tx.Hash)) + txReceipt, err := suite.backend.GetTransactionReceipt(tc.tx.Hash()) if tc.expPass { suite.Require().NoError(err) suite.Require().Equal(txReceipt, tc.expTxReceipt) diff --git a/rpc/types/utils.go b/rpc/types/utils.go index d3dac54e5f..fb7b0facfc 100644 --- a/rpc/types/utils.go +++ b/rpc/types/utils.go @@ -56,7 +56,6 @@ func RawTxToEthTx(clientCtx client.Context, txBz tmtypes.Tx) ([]*evmtypes.MsgEth if !ok { return nil, fmt.Errorf("invalid message type %T, expected %T", msg, &evmtypes.MsgEthereumTx{}) } - ethTx.Hash = ethTx.AsTransaction().Hash().Hex() ethTxs[i] = ethTx } return ethTxs, nil diff --git a/testutil/base_test_suite.go b/testutil/base_test_suite.go index a0ac2a70f3..4136d45268 100644 --- a/testutil/base_test_suite.go +++ b/testutil/base_test_suite.go @@ -22,7 +22,6 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/mock" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -206,31 +205,17 @@ func (suite *BaseTestSuiteWithAccount) BuildEthTx( func (suite *BaseTestSuiteWithAccount) PrepareEthTx(msgEthereumTx *types.MsgEthereumTx, privKey *ethsecp256k1.PrivKey) []byte { ethSigner := ethtypes.LatestSignerForChainID(suite.App.EvmKeeper.ChainID()) - encodingConfig := suite.App.EncodingConfig() - option, err := codectypes.NewAnyWithValue(&types.ExtensionOptionsEthereumTx{}) + err := msgEthereumTx.Sign(ethSigner, tests.NewSigner(privKey)) suite.Require().NoError(err) - txBuilder := encodingConfig.TxConfig.NewTxBuilder() - builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder) - suite.Require().True(ok) - builder.SetExtensionOptions(option) - - err = msgEthereumTx.Sign(ethSigner, tests.NewSigner(privKey)) - suite.Require().NoError(err) - - err = txBuilder.SetMsgs(msgEthereumTx) - suite.Require().NoError(err) + txConfig := suite.App.TxConfig() + evmDenom := suite.App.EvmKeeper.GetParams(suite.Ctx).EvmDenom - txData, err := types.UnpackTxData(msgEthereumTx.Data) + tx, err := msgEthereumTx.BuildTx(txConfig.NewTxBuilder(), evmDenom) suite.Require().NoError(err) - evmDenom := suite.App.EvmKeeper.GetParams(suite.Ctx).EvmDenom - fees := sdk.Coins{{Denom: evmDenom, Amount: sdkmath.NewIntFromBigInt(txData.Fee())}} - builder.SetFeeAmount(fees) - builder.SetGasLimit(msgEthereumTx.GetGas()) - // bz are bytes to be broadcasted over the network - bz, err := encodingConfig.TxConfig.TxEncoder()(txBuilder.GetTx()) + bz, err := txConfig.TxEncoder()(tx) suite.Require().NoError(err) return bz diff --git a/testutil/tx/eth.go b/testutil/tx/eth.go index 070ed91f51..0827eb1e49 100644 --- a/testutil/tx/eth.go +++ b/testutil/tx/eth.go @@ -26,7 +26,7 @@ func CreateContractMsgTx( } ethTx := ethtypes.NewTx(contractCreateTx) ethMsg := &types.MsgEthereumTx{} - ethMsg.FromEthereumTx(ethTx) //nolint: errcheck + ethMsg.FromEthereumTx(ethTx) ethMsg.From = from.Bytes() return ethMsg, ethMsg.Sign(signer, keyringSigner) diff --git a/x/evm/handler_test.go b/x/evm/handler_test.go index 6de98d43df..d361c106e1 100644 --- a/x/evm/handler_test.go +++ b/x/evm/handler_test.go @@ -391,7 +391,7 @@ func (suite *HandlerTestSuite) deployERC20Contract() common.Address { nonce := k.GetNonce(suite.Ctx, suite.Address) ctorArgs, err := types.ERC20Contract.ABI.Pack("", suite.Address, big.NewInt(10000000000)) suite.Require().NoError(err) - msg := core.Message{ + msg := &core.Message{ From: suite.Address, To: nil, Nonce: nonce, @@ -478,9 +478,7 @@ func (suite *HandlerTestSuite) TestERC20TransferReverted() { ethCfg := evmParams.GetChainConfig().EthereumConfig(nil) baseFee := suite.App.EvmKeeper.GetBaseFee(suite.Ctx, ethCfg) - txData, err := types.UnpackTxData(tx.Data) - suite.Require().NoError(err) - fees, err := keeper.VerifyFee(txData, "aphoton", baseFee, true, true, true, suite.Ctx.IsCheckTx()) + fees, err := keeper.VerifyFee(tx, "aphoton", baseFee, true, true, true, suite.Ctx.IsCheckTx()) suite.Require().NoError(err) err = k.DeductTxCostsFromUserBalance(suite.Ctx, fees, tx.GetSender()) suite.Require().NoError(err) @@ -572,13 +570,13 @@ func (suite *HandlerTestSuite) TestContractDeploymentRevert() { // DummyHook implements EvmHooks interface type DummyHook struct{} -func (dh *DummyHook) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error { +func (dh *DummyHook) PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error { return nil } // FailureHook implements EvmHooks interface type FailureHook struct{} -func (dh *FailureHook) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error { +func (dh *FailureHook) PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error { return errors.New("mock error") } diff --git a/x/evm/keeper/benchmark_test.go b/x/evm/keeper/benchmark_test.go index 4f78d69df8..8b57ccbd46 100644 --- a/x/evm/keeper/benchmark_test.go +++ b/x/evm/keeper/benchmark_test.go @@ -109,11 +109,7 @@ func doBenchmark(b *testing.B, txBuilder TxBuilder) { for i := 0; i < b.N; i++ { ctx, _ := suite.Ctx.CacheContext() - // deduct fee first - txData, err := types.UnpackTxData(msg.Data) - require.NoError(b, err) - - fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdkmath.NewIntFromBigInt(txData.Fee()))} + fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdkmath.NewIntFromBigInt(msg.GetFee()))} err = evmkeeper.DeductFees(suite.App.BankKeeper, suite.Ctx, suite.App.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) require.NoError(b, err) @@ -176,11 +172,7 @@ func BenchmarkMessageCall(b *testing.B) { for i := 0; i < b.N; i++ { ctx, _ := suite.Ctx.CacheContext() - // deduct fee first - txData, err := types.UnpackTxData(msg.Data) - require.NoError(b, err) - - fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdkmath.NewIntFromBigInt(txData.Fee()))} + fees := sdk.Coins{sdk.NewCoin(suite.EvmDenom(), sdkmath.NewIntFromBigInt(msg.GetFee()))} err = evmkeeper.DeductFees(suite.App.BankKeeper, suite.Ctx, suite.App.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees) require.NoError(b, err) diff --git a/x/evm/keeper/config.go b/x/evm/keeper/config.go index 0f0e589ff7..4a19709975 100644 --- a/x/evm/keeper/config.go +++ b/x/evm/keeper/config.go @@ -21,7 +21,6 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" rpctypes "github.com/evmos/ethermint/rpc/types" @@ -143,7 +142,7 @@ func (k *Keeper) TxConfig(ctx sdk.Context, txHash common.Hash) statedb.TxConfig // VMConfig creates an EVM configuration from the debug setting and the extra EIPs enabled on the // module parameters. The config generated uses the default JumpTable from the EVM. -func (k Keeper) VMConfig(ctx sdk.Context, _ core.Message, cfg *EVMConfig) vm.Config { +func (k Keeper) VMConfig(ctx sdk.Context, cfg *EVMConfig) vm.Config { noBaseFee := true if types.IsLondon(cfg.ChainConfig, ctx.BlockHeight()) { noBaseFee = cfg.FeeMarketParams.NoBaseFee diff --git a/x/evm/keeper/gas.go b/x/evm/keeper/gas.go index 5874f77002..b184702937 100644 --- a/x/evm/keeper/gas.go +++ b/x/evm/keeper/gas.go @@ -31,7 +31,7 @@ import ( ) // GetEthIntrinsicGas returns the intrinsic gas cost for the transaction -func (k *Keeper) GetEthIntrinsicGas(msg core.Message, rules params.Rules, isContractCreation bool) (uint64, error) { +func (k *Keeper) GetEthIntrinsicGas(msg *core.Message, rules params.Rules, isContractCreation bool) (uint64, error) { return core.IntrinsicGas(msg.Data, msg.AccessList, isContractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) } @@ -39,7 +39,7 @@ func (k *Keeper) GetEthIntrinsicGas(msg core.Message, rules params.Rules, isCont // consumed in the transaction. Additionally, the function sets the total gas consumed to the value // returned by the EVM execution, thus ignoring the previous intrinsic gas consumed during in the // AnteHandler. -func (k *Keeper) RefundGas(ctx sdk.Context, msg core.Message, leftoverGas uint64, denom string) error { +func (k *Keeper) RefundGas(ctx sdk.Context, msg *core.Message, leftoverGas uint64, denom string) error { // Return EVM tokens for remaining gas, exchanged at the original rate. remaining := new(big.Int).Mul(new(big.Int).SetUint64(leftoverGas), msg.GasPrice) diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index 8fb28c58cd..30bed2e3b8 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -349,7 +349,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type // Create a helper to check if a gas allowance results in an executable transaction executable := func(gas uint64) (vmError bool, rsp *types.MsgEthereumTxResponse, err error) { // update the message with the new gas value - msg = core.Message{ + msg = &core.Message{ From: msg.From, To: msg.To, Nonce: msg.Nonce, @@ -459,7 +459,7 @@ func execTrace[T traceRequest]( return nil, status.Error(codes.Internal, err.Error()) } - result, _, err := k.prepareTrace(ctx, cfg, *msg, req.GetTraceConfig(), false) + result, _, err := k.prepareTrace(ctx, cfg, msg, req.GetTraceConfig(), false) if err != nil { // error will be returned with detail status from traceTx return nil, err @@ -492,7 +492,7 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ } cfg.TxConfig.TxHash = ethTx.Hash() cfg.TxConfig.TxIndex = uint(i) - rsp, err := k.ApplyMessageWithConfig(ctx, *msg, cfg, true) + rsp, err := k.ApplyMessageWithConfig(ctx, msg, cfg, true) if err != nil { continue } @@ -563,7 +563,7 @@ func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest) if err != nil { result.Error = status.Error(codes.Internal, err.Error()).Error() } else { - traceResult, logIndex, err := k.prepareTrace(ctx, cfg, *msg, req.TraceConfig, true) + traceResult, logIndex, err := k.prepareTrace(ctx, cfg, msg, req.TraceConfig, true) if err != nil { result.Error = err.Error() } else { @@ -607,7 +607,7 @@ func (k Keeper) TraceCall(c context.Context, req *types.QueryTraceCallRequest) ( if err != nil { return nil, err } - return &msg, nil + return msg, nil }, ) if err != nil { @@ -623,7 +623,7 @@ func (k Keeper) TraceCall(c context.Context, req *types.QueryTraceCallRequest) ( func (k *Keeper) prepareTrace( ctx sdk.Context, cfg *EVMConfig, - msg core.Message, + msg *core.Message, traceConfig *types.TraceConfig, commitMessage bool, ) (*interface{}, uint, error) { diff --git a/x/evm/keeper/hooks.go b/x/evm/keeper/hooks.go index fc33d778fe..e7b79dcde6 100644 --- a/x/evm/keeper/hooks.go +++ b/x/evm/keeper/hooks.go @@ -34,7 +34,7 @@ func NewMultiEvmHooks(hooks ...types.EvmHooks) MultiEvmHooks { } // PostTxProcessing delegate the call to underlying hooks -func (mh MultiEvmHooks) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error { +func (mh MultiEvmHooks) PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error { for i := range mh { if err := mh[i].PostTxProcessing(ctx, msg, receipt); err != nil { return errorsmod.Wrapf(err, "EVM hook %T failed", mh[i]) diff --git a/x/evm/keeper/hooks_test.go b/x/evm/keeper/hooks_test.go index 13c72a54c6..e3b14b7728 100644 --- a/x/evm/keeper/hooks_test.go +++ b/x/evm/keeper/hooks_test.go @@ -30,7 +30,7 @@ type LogRecordHook struct { Logs []*ethtypes.Log } -func (dh *LogRecordHook) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error { +func (dh *LogRecordHook) PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error { dh.Logs = receipt.Logs return nil } @@ -38,7 +38,7 @@ func (dh *LogRecordHook) PostTxProcessing(ctx sdk.Context, msg core.Message, rec // FailureHook always fail type FailureHook struct{} -func (dh FailureHook) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error { +func (dh FailureHook) PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error { return errors.New("post tx processing failed") } @@ -92,7 +92,7 @@ func (suite *HookTestSuite) TestEvmHooks() { TxHash: txHash, Logs: logs, } - result := k.PostTxProcessing(suite.Ctx, core.Message{}, receipt) + result := k.PostTxProcessing(suite.Ctx, &core.Message{}, receipt) tc.expFunc(hook, result) } diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 14fee66b9c..56acb834f5 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -191,7 +191,7 @@ func (k *Keeper) SetHooks(eh types.EvmHooks) *Keeper { } // PostTxProcessing delegate the call to the hooks. If no hook has been registered, this function returns with a `nil` error -func (k *Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error { +func (k *Keeper) PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error { if k.hooks == nil { return nil } @@ -199,7 +199,7 @@ func (k *Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *et } // Tracer return a default vm.Tracer based on current keeper state -func (k Keeper) Tracer(msg core.Message, rules params.Rules) vm.EVMLogger { +func (k Keeper) Tracer(msg *core.Message, rules params.Rules) vm.EVMLogger { return types.NewTracer(k.tracer, msg, rules) } diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index 9f6d75db46..0c7189f1e0 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -48,7 +48,7 @@ import ( // for more information. func (k *Keeper) NewEVM( ctx sdk.Context, - msg core.Message, + msg *core.Message, cfg *EVMConfig, stateDB vm.StateDB, ) *vm.EVM { @@ -67,11 +67,11 @@ func (k *Keeper) NewEVM( if cfg.BlockOverrides != nil { cfg.BlockOverrides.Apply(&blockCtx) } - txCtx := core.NewEVMTxContext(&msg) + txCtx := core.NewEVMTxContext(msg) if cfg.Tracer == nil { cfg.Tracer = k.Tracer(msg, cfg.Rules) } - vmConfig := k.VMConfig(ctx, msg, cfg) + vmConfig := k.VMConfig(ctx, cfg) contracts := make(map[common.Address]vm.PrecompiledContract) active := make([]common.Address, 0) for addr, c := range vm.DefaultPrecompiles(cfg.Rules) { @@ -172,11 +172,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, msgEth *types.MsgEthereumTx) return nil, errorsmod.Wrap(err, "failed to load evm config") } - msg, err := msgEth.AsMessage(cfg.BaseFee) - if err != nil { - return nil, errorsmod.Wrap(err, "failed to return ethereum transaction as core message") - } - + msg := msgEth.AsMessage(cfg.BaseFee) // snapshot to contain the tx processing and post processing in same scope var commit func() tmpCtx := ctx @@ -251,7 +247,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, msgEth *types.MsgEthereumTx) } // ApplyMessage calls ApplyMessageWithConfig with an empty TxConfig. -func (k *Keeper) ApplyMessage(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool) (*types.MsgEthereumTxResponse, error) { +func (k *Keeper) ApplyMessage(ctx sdk.Context, msg *core.Message, tracer vm.EVMLogger, commit bool) (*types.MsgEthereumTxResponse, error) { cfg, err := k.EVMConfig(ctx, k.eip155ChainID, common.Hash{}) if err != nil { return nil, errorsmod.Wrap(err, "failed to load evm config") @@ -310,7 +306,7 @@ func (k *Keeper) ApplyMessage(ctx sdk.Context, msg core.Message, tracer vm.EVMLo // 2. sender nonce is incremented by 1 before execution func (k *Keeper) ApplyMessageWithConfig( ctx sdk.Context, - msg core.Message, + msg *core.Message, cfg *EVMConfig, commit bool, ) (*types.MsgEthereumTxResponse, error) { diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 8296f05c93..f8e3a4e6d2 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -177,18 +177,13 @@ func newNativeMessage( txType byte, data []byte, accessList ethtypes.AccessList, -) (core.Message, error) { +) (*core.Message, error) { msg, baseFee, err := newEthMsgTx(nonce, address, krSigner, ethSigner, txType, data, accessList) if err != nil { - return core.Message{}, err - } - - m, err := msg.AsMessage(baseFee) - if err != nil { - return core.Message{}, err + return nil, err } - return m, nil + return msg.AsMessage(baseFee), nil } func BenchmarkApplyTransaction(b *testing.B) { diff --git a/x/evm/keeper/state_transition_test.go b/x/evm/keeper/state_transition_test.go index 3883d4a298..bdc95a1f87 100644 --- a/x/evm/keeper/state_transition_test.go +++ b/x/evm/keeper/state_transition_test.go @@ -418,7 +418,7 @@ func (suite *StateTransitionTestSuite) TestGasToRefund() { func (suite *StateTransitionTestSuite) TestRefundGas() { var ( - m core.Message + m *core.Message err error ) @@ -594,7 +594,7 @@ func (suite *StateTransitionTestSuite) TestEVMConfig() { } func (suite *StateTransitionTestSuite) TestContractDeployment() { - contractAddress := suite.EVMTestSuiteWithAccountAndQueryClient.DeployTestContract( + contractAddress := suite.DeployTestContract( suite.T(), suite.Address, big.NewInt(10000000000000), @@ -606,7 +606,7 @@ func (suite *StateTransitionTestSuite) TestContractDeployment() { func (suite *StateTransitionTestSuite) TestApplyMessage() { expectedGasUsed := params.TxGas - var msg core.Message + var msg *core.Message _, err := suite.App.EvmKeeper.EVMConfig(suite.Ctx, big.NewInt(9000), common.Hash{}) suite.Require().NoError(err) @@ -640,7 +640,7 @@ func (suite *StateTransitionTestSuite) TestApplyMessage() { func (suite *StateTransitionTestSuite) TestApplyMessageWithConfig() { var ( - msg core.Message + msg *core.Message err error expectedGasUsed uint64 config *keeper.EVMConfig @@ -732,12 +732,12 @@ func (suite *StateTransitionTestSuite) TestApplyMessageWithConfig() { } } -func (suite *StateTransitionTestSuite) createContractGethMsg(nonce uint64, signer ethtypes.Signer, gasPrice *big.Int) (core.Message, error) { +func (suite *StateTransitionTestSuite) createContractGethMsg(nonce uint64, signer ethtypes.Signer, gasPrice *big.Int) (*core.Message, error) { ethMsg, err := utiltx.CreateContractMsgTx(nonce, signer, gasPrice, suite.Address, suite.Signer) if err != nil { - return core.Message{}, err + return nil, err } - return ethMsg.AsMessage(nil) + return ethMsg.AsMessage(nil), nil } func (suite *StateTransitionTestSuite) TestGetProposerAddress() { diff --git a/x/evm/keeper/utils.go b/x/evm/keeper/utils.go index 9720232bf0..d2b1257692 100644 --- a/x/evm/keeper/utils.go +++ b/x/evm/keeper/utils.go @@ -94,21 +94,18 @@ func (k *Keeper) DeductTxCostsFromUserBalance( // gas limit is not reached, the gas limit is higher than the intrinsic gas and that the // base fee is higher than the gas fee cap. func VerifyFee( - txData types.TxData, + msg *types.MsgEthereumTx, denom string, baseFee *big.Int, homestead, istanbul, shanghai, isCheckTx bool, ) (sdk.Coins, error) { - isContractCreation := txData.GetTo() == nil + tx := msg.AsTransaction() + isContractCreation := tx.To() == nil - gasLimit := txData.GetGas() + gasLimit := tx.Gas() - var accessList ethtypes.AccessList - if txData.GetAccessList() != nil { - accessList = txData.GetAccessList() - } - - intrinsicGas, err := core.IntrinsicGas(txData.GetData(), accessList, isContractCreation, homestead, istanbul, shanghai) + accessList := tx.AccessList() + intrinsicGas, err := core.IntrinsicGas(tx.Data(), accessList, isContractCreation, homestead, istanbul, shanghai) if err != nil { return nil, errorsmod.Wrapf( err, @@ -125,14 +122,14 @@ func VerifyFee( ) } - if baseFee != nil && txData.GetGasFeeCap().Cmp(baseFee) < 0 { + if baseFee != nil && tx.GasFeeCap().Cmp(baseFee) < 0 { return nil, errorsmod.Wrapf(errortypes.ErrInsufficientFee, "the tx gasfeecap is lower than the tx baseFee: %s (gasfeecap), %s (basefee) ", - txData.GetGasFeeCap(), + tx.GasFeeCap(), baseFee) } - feeAmt := txData.EffectiveFee(baseFee) + feeAmt := msg.GetEffectiveFee(baseFee) if feeAmt.Sign() == 0 { // zero fee, no need to deduct return sdk.Coins{}, nil @@ -145,9 +142,9 @@ func VerifyFee( // sender has enough funds to pay for the fees and value of the transaction. func CheckSenderBalance( balance sdkmath.Int, - txData types.TxData, + tx *ethtypes.Transaction, ) error { - cost := txData.Cost() + cost := tx.Cost() if cost.Sign() < 0 { return errorsmod.Wrapf( @@ -159,7 +156,7 @@ func CheckSenderBalance( if balance.IsNegative() || balance.BigInt().Cmp(cost) < 0 { return errorsmod.Wrapf( errortypes.ErrInsufficientFunds, - "sender balance < tx cost (%s < %s)", balance, txData.Cost(), + "sender balance < tx cost (%s < %s)", balance, tx.Cost(), ) } return nil diff --git a/x/evm/keeper/utils_test.go b/x/evm/keeper/utils_test.go index f5d7127ea0..d2199f6bfa 100644 --- a/x/evm/keeper/utils_test.go +++ b/x/evm/keeper/utils_test.go @@ -261,11 +261,10 @@ func (suite *UtilsTestSuite) TestCheckSenderBalance() { } tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &to, amount, tc.gasLimit, gasPrice, gasFeeCap, gasTipCap, nil, tc.accessList) tx.From = common.HexToAddress(tc.from).Bytes() - txData, _ := evmtypes.UnpackTxData(tx.Data) balance := suite.App.EvmKeeper.GetEVMDenomBalance(suite.Ctx, suite.Address) err = keeper.CheckSenderBalance( sdkmath.NewIntFromBigInt(balance), - txData, + tx.AsTransaction(), ) if tc.expectPass { suite.Require().NoError(err, "valid test %d failed", i) @@ -497,14 +496,12 @@ func (suite *UtilsTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { tx := evmtypes.NewTx(zeroInt.BigInt(), 1, &suite.Address, amount, tc.gasLimit, gasPrice, gasFeeCap, gasTipCap, nil, tc.accessList) tx.From = common.HexToAddress(tc.from).Bytes() - txData, _ := evmtypes.UnpackTxData(tx.Data) - evmParams := suite.App.EvmKeeper.GetParams(suite.Ctx) ethCfg := evmParams.GetChainConfig().EthereumConfig(nil) baseFee := suite.App.EvmKeeper.GetBaseFee(suite.Ctx, ethCfg) - priority := evmtypes.GetTxPriority(txData, baseFee) + priority := evmtypes.GetTxPriority(tx, baseFee) - fees, err := keeper.VerifyFee(txData, evmtypes.DefaultEVMDenom, baseFee, false, false, false, suite.Ctx.IsCheckTx()) + fees, err := keeper.VerifyFee(tx, evmtypes.DefaultEVMDenom, baseFee, false, false, false, suite.Ctx.IsCheckTx()) if tc.expectPassVerify { suite.Require().NoError(err, "valid test %d failed - '%s'", i, tc.name) if tc.enableFeemarket { @@ -512,7 +509,7 @@ func (suite *UtilsTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { suite.Require().Equal( fees, sdk.NewCoins( - sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewIntFromBigInt(txData.EffectiveFee(baseFee))), + sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewIntFromBigInt(tx.GetEffectiveFee(baseFee))), ), "valid test %d failed, fee value is wrong - '%s'", i, tc.name, ) diff --git a/x/evm/simulation/operations.go b/x/evm/simulation/operations.go index b28abd9957..89ed26009a 100644 --- a/x/evm/simulation/operations.go +++ b/x/evm/simulation/operations.go @@ -298,12 +298,7 @@ func GetSignedTx( return nil, err } - txData, err := types.UnpackTxData(msg.Data) - if err != nil { - return nil, err - } - - fees := sdk.NewCoins(sdk.NewCoin(ctx.keeper.GetParams(ctx.context).EvmDenom, sdkmath.NewIntFromBigInt(txData.Fee()))) + fees := sdk.NewCoins(sdk.NewCoin(ctx.keeper.GetParams(ctx.context).EvmDenom, sdkmath.NewIntFromBigInt(msg.GetFee()))) builder.SetFeeAmount(fees) builder.SetGasLimit(msg.GetGas()) diff --git a/x/evm/types/eth.go b/x/evm/types/eth.go new file mode 100644 index 0000000000..e1fb2655bf --- /dev/null +++ b/x/evm/types/eth.go @@ -0,0 +1,84 @@ +package types + +import ( + "encoding/json" + + errorsmod "cosmossdk.io/errors" + "github.com/ethereum/go-ethereum/common/hexutil" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/evmos/ethermint/types" +) + +type EthereumTx struct { + *ethtypes.Transaction +} + +func NewEthereumTx(txData ethtypes.TxData) EthereumTx { + return EthereumTx{ethtypes.NewTx(txData)} +} + +func (tx EthereumTx) Size() int { + if tx.Transaction == nil { + return 0 + } + return int(tx.Transaction.Size()) +} + +func (tx EthereumTx) MarshalTo(dst []byte) (int, error) { + if tx.Transaction == nil { + return 0, nil + } + bz, err := tx.MarshalBinary() + if err != nil { + return 0, err + } + copy(dst, bz) + return len(bz), nil +} + +func (tx *EthereumTx) Unmarshal(dst []byte) error { + if len(dst) == 0 { + tx.Transaction = nil + return nil + } + if tx.Transaction == nil { + tx.Transaction = new(ethtypes.Transaction) + } + return tx.UnmarshalBinary(dst) +} + +func (tx *EthereumTx) UnmarshalJSON(bz []byte) error { + var data hexutil.Bytes + if err := json.Unmarshal(bz, &data); err != nil { + return err + } + return tx.Unmarshal(data) +} + +func (tx EthereumTx) MarshalJSON() ([]byte, error) { + bz, err := tx.MarshalBinary() + if err != nil { + return nil, err + } + return json.Marshal(hexutil.Bytes(bz)) +} + +func (tx EthereumTx) Validate() error { + // prevent txs with 0 gas to fill up the mempool + if tx.Gas() == 0 { + return errorsmod.Wrap(ErrInvalidGasLimit, "gas limit must not be zero") + } + if !types.IsValidInt256(tx.GasPrice()) { + return errorsmod.Wrap(ErrInvalidGasPrice, "out of bound") + } + if !types.IsValidInt256(tx.GasFeeCap()) { + return errorsmod.Wrap(ErrInvalidGasPrice, "out of bound") + } + if !types.IsValidInt256(tx.GasTipCap()) { + return errorsmod.Wrap(ErrInvalidGasPrice, "out of bound") + } + if !types.IsValidInt256(tx.Cost()) { + return errorsmod.Wrap(ErrInvalidGasFee, "out of bound") + } + return nil +} diff --git a/x/evm/types/interfaces.go b/x/evm/types/interfaces.go index 4ee211f5d5..3d30a27f6c 100644 --- a/x/evm/types/interfaces.go +++ b/x/evm/types/interfaces.go @@ -72,7 +72,7 @@ type FeeMarketKeeper interface { // EvmHooks event hooks for evm tx processing type EvmHooks interface { // Must be called after tx is processed successfully, if return an error, the whole transaction is reverted. - PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error + PostTxProcessing(ctx sdk.Context, msg *core.Message, receipt *ethtypes.Receipt) error } type ( diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index fd8d1d947c..c2089b18f9 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -36,7 +36,7 @@ import ( authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" ) @@ -56,6 +56,10 @@ const ( TypeMsgEthereumTx = "ethereum_tx" ) +func NewTxWithData(txData ethtypes.TxData) *MsgEthereumTx { + return &MsgEthereumTx{Raw: NewEthereumTx(txData)} +} + // NewTx returns a reference to a new Ethereum transaction message. func NewTx( chainID *big.Int, nonce uint64, to *common.Address, amount *big.Int, @@ -82,100 +86,57 @@ func newMsgEthereumTx( chainID *big.Int, nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, input []byte, accesses *ethtypes.AccessList, ) *MsgEthereumTx { - var ( - cid, amt, gp *sdkmath.Int - toAddr string - txData TxData - ) - - if to != nil { - toAddr = to.Hex() - } - - if amount != nil { - amountInt := sdkmath.NewIntFromBigInt(amount) - amt = &amountInt - } - - if chainID != nil { - chainIDInt := sdkmath.NewIntFromBigInt(chainID) - cid = &chainIDInt - } - - if gasPrice != nil { - gasPriceInt := sdkmath.NewIntFromBigInt(gasPrice) - gp = &gasPriceInt - } + var txData ethtypes.TxData switch { case gasFeeCap != nil: - gtc := sdkmath.NewIntFromBigInt(gasTipCap) - gfc := sdkmath.NewIntFromBigInt(gasFeeCap) - txData = &DynamicFeeTx{ - ChainID: cid, - Nonce: nonce, - To: toAddr, - Amount: amt, - GasLimit: gasLimit, - GasTipCap: >c, - GasFeeCap: &gfc, - Data: input, - Accesses: NewAccessList(accesses), + var accessList ethtypes.AccessList + if accesses != nil { + accessList = *accesses + } + txData = ðtypes.DynamicFeeTx{ + ChainID: chainID, + Nonce: nonce, + To: to, + Value: amount, + Gas: gasLimit, + GasTipCap: gasTipCap, + GasFeeCap: gasFeeCap, + Data: input, + AccessList: accessList, } case accesses != nil: - txData = &AccessListTx{ - ChainID: cid, - Nonce: nonce, - To: toAddr, - Amount: amt, - GasLimit: gasLimit, - GasPrice: gp, - Data: input, - Accesses: NewAccessList(accesses), + txData = ðtypes.AccessListTx{ + ChainID: chainID, + Nonce: nonce, + To: to, + Value: amount, + Gas: gasLimit, + GasPrice: gasPrice, + Data: input, + AccessList: *accesses, } default: - txData = &LegacyTx{ + txData = ðtypes.LegacyTx{ Nonce: nonce, - To: toAddr, - Amount: amt, - GasLimit: gasLimit, - GasPrice: gp, + To: to, + Value: amount, + Gas: gasLimit, + GasPrice: gasPrice, Data: input, } } - dataAny, err := PackTxData(txData) - if err != nil { - panic(err) - } - - msg := MsgEthereumTx{Data: dataAny} - msg.Hash = msg.AsTransaction().Hash().Hex() - return &msg + return NewTxWithData(txData) } -// FromEthereumTx populates the message fields from the given ethereum transaction -func (msg *MsgEthereumTx) FromEthereumTx(tx *ethtypes.Transaction) error { - txData, err := NewTxDataFromTx(tx) - if err != nil { - return err - } - - anyTxData, err := PackTxData(txData) - if err != nil { - return err - } - - msg.Data = anyTxData - msg.Hash = tx.Hash().Hex() - return nil +func (msg *MsgEthereumTx) FromEthereumTx(tx *ethtypes.Transaction) { + msg.Raw.Transaction = tx } // FromSignedEthereumTx populates the message fields from the given signed ethereum transaction, and set From field. func (msg *MsgEthereumTx) FromSignedEthereumTx(tx *ethtypes.Transaction, signer ethtypes.Signer) error { - if err := msg.FromEthereumTx(tx); err != nil { - return err - } + msg.Raw.Transaction = tx from, err := ethtypes.Sender(signer, tx) if err != nil { @@ -195,39 +156,33 @@ 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 len(msg.DeprecatedFrom) != 0 { - return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "deprecated From field is not empty") - } - + // From and Raw are only two fields allowed in new transaction format. if len(msg.From) == 0 { return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "sender address is missing") } + if msg.Raw.Transaction == nil { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "raw tx is missing") + } + // Check removed fields not exists + if len(msg.DeprecatedFrom) != 0 { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "deprecated From field is not empty") + } + if len(msg.DeprecatedHash) != 0 { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "deprecated Hash field is not empty") + } // Validate Size_ field, should be kept empty if msg.Size_ != 0 { return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "tx size is deprecated") } - - txData, err := UnpackTxData(msg.Data) - if err != nil { - return errorsmod.Wrap(err, "failed to unpack tx data") - } - - // prevent txs with 0 gas to fill up the mempool - if txData.GetGas() == 0 { - return errorsmod.Wrap(ErrInvalidGasLimit, "gas limit must not be zero") + if msg.Data != nil { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "tx data is deprecated in favor of Raw") } - if err := txData.Validate(); err != nil { + if err := msg.Raw.Validate(); err != nil { return err } - // Validate Hash field after validated txData to avoid panic - txHash := msg.AsTransaction().Hash().Hex() - if msg.Hash != txHash { - return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "invalid tx hash %s, expected: %s", msg.Hash, txHash) - } - return nil } @@ -299,34 +254,36 @@ func (msg *MsgEthereumTx) Sign(ethSigner ethtypes.Signer, keyringSigner keyring. return err } - return msg.FromEthereumTx(tx) + msg.Raw.Transaction = tx + return nil } // GetGas implements the GasTx interface. It returns the GasLimit of the transaction. func (msg MsgEthereumTx) GetGas() uint64 { - txData, err := UnpackTxData(msg.Data) - if err != nil { - return 0 - } - return txData.GetGas() + return msg.AsTransaction().Gas() } // GetFee returns the fee for non dynamic fee tx func (msg MsgEthereumTx) GetFee() *big.Int { - txData, err := UnpackTxData(msg.Data) - if err != nil { - return nil - } - return txData.Fee() + tx := msg.AsTransaction() + price := tx.GasPrice() + return price.Mul(price, new(big.Int).SetUint64(tx.Gas())) } // GetEffectiveFee returns the fee for dynamic fee tx func (msg MsgEthereumTx) GetEffectiveFee(baseFee *big.Int) *big.Int { - txData, err := UnpackTxData(msg.Data) - if err != nil { - return nil + price := msg.GetEffectiveGasPrice(baseFee) + return price.Mul(price, new(big.Int).SetUint64(msg.GetGas())) +} + +// GetEffectiveGasPrice returns the fee for dynamic fee tx +func (msg MsgEthereumTx) GetEffectiveGasPrice(baseFee *big.Int) *big.Int { + tx := msg.AsTransaction() + if baseFee == nil { + return tx.GasPrice() } - return txData.EffectiveFee(baseFee) + // for legacy tx, both gasTipCap and gasFeeCap are gasPrice, the result is equavalent. + return cmath.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap()) } // GetFrom loads the ethereum sender address from the sigcache and returns an @@ -336,41 +293,43 @@ func (msg *MsgEthereumTx) GetFrom() sdk.AccAddress { } // AsTransaction creates an Ethereum Transaction type from the msg fields -func (msg MsgEthereumTx) AsTransaction() *ethtypes.Transaction { +func (msg *MsgEthereumTx) AsTransaction() *ethtypes.Transaction { + tx := msg.Raw.Transaction + if tx != nil { + return tx + } + + // fallback to legacy format txData, err := UnpackTxData(msg.Data) if err != nil { return nil } - - return ethtypes.NewTx(txData.AsEthereumData()) + msg.Raw = NewEthereumTx(txData.AsEthereumData()) + return msg.Raw.Transaction } // AsMessage creates an Ethereum core.Message from the msg fields -func (msg MsgEthereumTx) AsMessage(baseFee *big.Int) (core.Message, error) { - txData, err := UnpackTxData(msg.Data) - if err != nil { - return core.Message{}, err - } +func (msg *MsgEthereumTx) AsMessage(baseFee *big.Int) *core.Message { + tx := msg.AsTransaction() + ethMsg := &core.Message{ + Nonce: tx.Nonce(), + GasLimit: tx.Gas(), + GasPrice: new(big.Int).Set(tx.GasPrice()), + GasFeeCap: new(big.Int).Set(tx.GasFeeCap()), + GasTipCap: new(big.Int).Set(tx.GasTipCap()), + To: tx.To(), + Value: tx.Value(), + Data: tx.Data(), + AccessList: tx.AccessList(), + SkipAccountChecks: false, - gasPrice, gasFeeCap, gasTipCap := txData.GetGasPrice(), txData.GetGasFeeCap(), txData.GetGasTipCap() - if baseFee != nil { - gasPrice = math.BigMin(gasPrice.Add(gasTipCap, baseFee), gasFeeCap) + From: common.BytesToAddress(msg.From), } - ethMsg := core.Message{ - From: msg.GetSender(), - To: txData.GetTo(), - Nonce: txData.GetNonce(), - Value: txData.GetValue(), - GasLimit: txData.GetGas(), - GasPrice: gasPrice, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Data: txData.GetData(), - AccessList: txData.GetAccessList(), - SkipAccountChecks: false, + // If baseFee provided, set gasPrice to effectiveGasPrice. + if baseFee != nil { + ethMsg.GasPrice = cmath.BigMin(ethMsg.GasPrice.Add(ethMsg.GasTipCap, baseFee), ethMsg.GasFeeCap) } - - return ethMsg, nil + return ethMsg } // VerifySender verify the sender address against the signature values using the latest signer for the given chainID. @@ -400,6 +359,10 @@ func (msg *MsgEthereumTx) UnmarshalBinary(b []byte, signer ethtypes.Signer) erro return msg.FromSignedEthereumTx(tx, signer) } +func (msg *MsgEthereumTx) Hash() common.Hash { + return msg.AsTransaction().Hash() +} + // BuildTx builds the canonical cosmos tx from ethereum msg func (msg *MsgEthereumTx) BuildTx(b client.TxBuilder, evmDenom string) (authsigning.Tx, error) { builder, ok := b.(authtx.ExtensionOptionsTxBuilder) @@ -412,26 +375,24 @@ func (msg *MsgEthereumTx) BuildTx(b client.TxBuilder, evmDenom string) (authsign return nil, err } - txData, err := UnpackTxData(msg.Data) - if err != nil { - return nil, err - } fees := make(sdk.Coins, 0) - feeAmt := sdkmath.NewIntFromBigInt(txData.Fee()) + fee := msg.GetFee() + feeAmt := sdkmath.NewIntFromBigInt(fee) if feeAmt.Sign() > 0 { fees = append(fees, sdk.NewCoin(evmDenom, feeAmt)) } builder.SetExtensionOptions(option) - err = builder.SetMsgs(msg) - if err != nil { + if err := builder.SetMsgs(&MsgEthereumTx{ + From: msg.From, + Raw: msg.Raw, + }); err != nil { return nil, err } builder.SetFeeAmount(fees) builder.SetGasLimit(msg.GetGas()) - tx := builder.GetTx() - return tx, nil + return builder.GetTx(), nil } // ValidateBasic does a sanity check of the provided data diff --git a/x/evm/types/msg_test.go b/x/evm/types/msg_test.go index 11076e7264..fbaaa66d49 100644 --- a/x/evm/types/msg_test.go +++ b/x/evm/types/msg_test.go @@ -79,11 +79,6 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_BuildTx() { types.NewTx(nil, 0, &suite.to, nil, 100000, big.NewInt(1), big.NewInt(1), big.NewInt(0), []byte("test"), nil), false, }, - { - "build tx - fail: nil data", - types.NewTx(nil, 0, &suite.to, nil, 100000, big.NewInt(1), big.NewInt(1), big.NewInt(0), []byte("test"), nil), - true, - }, } for _, tc := range testCases { @@ -114,7 +109,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { testCases := []struct { msg string - to string + to *common.Address amount *big.Int gasLimit uint64 gasPrice *big.Int @@ -127,7 +122,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }{ { msg: "pass with recipient - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -138,7 +133,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "pass with recipient - AccessList Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -151,7 +146,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "pass with recipient - DynamicFee Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -164,7 +159,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "pass contract - Legacy Tx", - to: "", + to: nil, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -173,18 +168,9 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasTipCap: nil, expectPass: true, }, - { - msg: "invalid recipient", - to: invalidFromAddress, - from: validFrom, - amount: minusOneInt, - gasLimit: 1000, - gasPrice: hundredInt, - expectPass: false, - }, { msg: "nil amount - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: nil, gasLimit: 1000, @@ -195,7 +181,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "negative amount - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: minusOneInt, gasLimit: 1000, @@ -206,7 +192,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "zero gas limit - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 0, @@ -217,18 +203,18 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "nil gas price - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, gasPrice: nil, gasFeeCap: nil, gasTipCap: nil, - expectPass: false, + expectPass: true, }, { msg: "negative gas price - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -239,7 +225,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "zero gas price - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -250,7 +236,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "invalid from address - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -261,7 +247,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "out of bound gas fee - Legacy Tx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -272,7 +258,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "nil amount - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: nil, gasLimit: 1000, @@ -285,7 +271,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "negative amount - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: minusOneInt, gasLimit: 1000, @@ -298,7 +284,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "zero gas limit - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 0, @@ -311,7 +297,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "nil gas price - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -320,11 +306,11 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasTipCap: nil, accessList: ðtypes.AccessList{}, chainID: hundredInt, - expectPass: false, + expectPass: true, }, { msg: "negative gas price - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -337,7 +323,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "zero gas price - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -350,7 +336,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "invalid from address - AccessListTx", - to: suite.to.Hex(), + to: &suite.to, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -363,7 +349,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { }, { msg: "chain ID not set on AccessListTx", - to: suite.to.Hex(), + to: &suite.to, from: validFrom, amount: hundredInt, gasLimit: 1000, @@ -372,42 +358,36 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasTipCap: nil, accessList: ðtypes.AccessList{}, chainID: nil, - expectPass: false, - }, - { - msg: "nil tx.Data - AccessList Tx", - to: suite.to.Hex(), - from: validFrom, - amount: hundredInt, - gasLimit: 1000, - gasPrice: zeroInt, - gasFeeCap: nil, - gasTipCap: nil, - accessList: ðtypes.AccessList{}, - chainID: hundredInt, - expectPass: false, + expectPass: true, }, } for _, tc := range testCases { suite.Run(tc.msg, func() { - 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 := types.NewTx(tc.chainID, 1, tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.gasFeeCap, tc.gasTipCap, nil, tc.accessList) tx.From = tc.from - // apply nil assignment here to test ValidateBasic function instead of NewTx - if strings.Contains(tc.msg, "nil tx.Data") { - tx.Data = nil + bz, err := tx.Marshal() + if err != nil && !tc.expectPass { + return } + suite.Require().NoError(err) - err := tx.ValidateBasic() - + var tx2 types.MsgEthereumTx + tx2.Unmarshal(bz) + err = tx2.ValidateBasic() if tc.expectPass { suite.Require().NoError(err) } else { suite.Require().Error(err) } + + if tc.expectPass { + bz2, err := tx2.Marshal() + suite.Require().NoError(err) + + suite.Require().Equal(bz, bz2) + } }) } } @@ -433,7 +413,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasicAdvanced() { nil, nil, ) - msg.Hash = "0x00" + msg.DeprecatedHash = "0x00" return msg }, false, @@ -551,53 +531,34 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Getters() { ethtypes.NewEIP2930Signer(suite.chainID), big.NewInt(5000), }, - { - "get fee - fail: nil data", - types.NewTx(suite.chainID, 0, &suite.to, nil, 50, suite.hundredBigInt, nil, nil, nil, ðtypes.AccessList{}), - ethtypes.NewEIP2930Signer(suite.chainID), - nil, - }, { "get effective fee - pass", types.NewTx(suite.chainID, 0, &suite.to, nil, 50, suite.hundredBigInt, nil, nil, nil, ðtypes.AccessList{}), ethtypes.NewEIP2930Signer(suite.chainID), big.NewInt(5000), }, - { - "get effective fee - fail: nil data", - types.NewTx(suite.chainID, 0, &suite.to, nil, 50, suite.hundredBigInt, nil, nil, nil, ðtypes.AccessList{}), - ethtypes.NewEIP2930Signer(suite.chainID), - nil, - }, { "get gas - pass", types.NewTx(suite.chainID, 0, &suite.to, nil, 50, suite.hundredBigInt, nil, nil, nil, ðtypes.AccessList{}), ethtypes.NewEIP2930Signer(suite.chainID), big.NewInt(50), }, - { - "get gas - fail: nil data", - types.NewTx(suite.chainID, 0, &suite.to, nil, 50, suite.hundredBigInt, nil, nil, nil, ðtypes.AccessList{}), - ethtypes.NewEIP2930Signer(suite.chainID), - big.NewInt(0), - }, } var fee, effFee *big.Int for _, tc := range testCases { - if strings.Contains(tc.name, "nil data") { - tc.tx.Data = nil - } - if strings.Contains(tc.name, "get fee") { - fee = tc.tx.GetFee() - suite.Require().Equal(tc.exp, fee) - } else if strings.Contains(tc.name, "get effective fee") { - effFee = tc.tx.GetEffectiveFee(big.NewInt(0)) - suite.Require().Equal(tc.exp, effFee) - } else if strings.Contains(tc.name, "get gas") { - gas := tc.tx.GetGas() - suite.Require().Equal(tc.exp.Uint64(), gas) - } + suite.Run(tc.name, func() { + if strings.Contains(tc.name, "get fee") { + fee = tc.tx.GetFee() + suite.Require().Equal(tc.exp, fee) + } else if strings.Contains(tc.name, "get effective fee") { + effFee = tc.tx.GetEffectiveFee(big.NewInt(0)) + suite.Require().Equal(tc.exp, effFee) + } else if strings.Contains(tc.name, "get gas") { + gas := tc.tx.GetGas() + suite.Require().Equal(tc.exp.Uint64(), gas) + } + }) } } @@ -607,7 +568,7 @@ func (suite *MsgsTestSuite) TestFromEthereumTx() { suite.Require().NoError(err) // 10^80 is more than 256 bits - exp_10_80 := new(big.Int).Mul(big.NewInt(1), new(big.Int).Exp(big.NewInt(10), big.NewInt(80), nil)) + exp_10_80 := new(big.Int).Exp(big.NewInt(10), big.NewInt(80), nil) testCases := []struct { msg string @@ -639,7 +600,7 @@ func (suite *MsgsTestSuite) TestFromEthereumTx() { suite.Require().NoError(err) return tx }}, - {"fail, value bigger than 256bits - AccessListTx", false, func() *ethtypes.Transaction { + {"success, value bigger than 256bits - AccessListTx", true, func() *ethtypes.Transaction { tx := ethtypes.NewTx(ðtypes.AccessListTx{ Nonce: 0, Data: nil, @@ -652,7 +613,7 @@ func (suite *MsgsTestSuite) TestFromEthereumTx() { suite.Require().NoError(err) return tx }}, - {"fail, gas price bigger than 256bits - AccessListTx", false, func() *ethtypes.Transaction { + {"success, gas price bigger than 256bits - AccessListTx", true, func() *ethtypes.Transaction { tx := ethtypes.NewTx(ðtypes.AccessListTx{ Nonce: 0, Data: nil, @@ -665,7 +626,7 @@ func (suite *MsgsTestSuite) TestFromEthereumTx() { suite.Require().NoError(err) return tx }}, - {"fail, value bigger than 256bits - LegacyTx", false, func() *ethtypes.Transaction { + {"success, value bigger than 256bits - LegacyTx", true, func() *ethtypes.Transaction { tx := ethtypes.NewTx(ðtypes.LegacyTx{ Nonce: 0, Data: nil, @@ -678,7 +639,7 @@ func (suite *MsgsTestSuite) TestFromEthereumTx() { suite.Require().NoError(err) return tx }}, - {"fail, gas price bigger than 256bits - LegacyTx", false, func() *ethtypes.Transaction { + {"success, gas price bigger than 256bits - LegacyTx", true, func() *ethtypes.Transaction { tx := ethtypes.NewTx(ðtypes.LegacyTx{ Nonce: 0, Data: nil, @@ -694,17 +655,26 @@ func (suite *MsgsTestSuite) TestFromEthereumTx() { } for _, tc := range testCases { - ethTx := tc.buildTx() - tx := &types.MsgEthereumTx{} - err := tx.FromEthereumTx(ethTx) - if tc.expectPass { + suite.Run(tc.msg, func() { + tx := types.MsgEthereumTx{ + Raw: types.EthereumTx{ + Transaction: tc.buildTx(), + }, + } + + // round-trip encoding + bz, err := tx.Marshal() suite.Require().NoError(err) + var tx2 types.MsgEthereumTx + suite.Require().NoError(tx2.Unmarshal(bz)) - // round-trip test - suite.Require().NoError(assertEqual(tx.AsTransaction(), ethTx)) - } else { - suite.Require().Error(err) - } + err = assertEqual(tx.Raw.Transaction, tx2.Raw.Transaction) + if tc.expectPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) } } @@ -781,7 +751,7 @@ func (suite *MsgsTestSuite) TestTransactionCoding() { if err != nil { suite.T().Fatal(err) } - assertEqual(parsedTx.AsTransaction(), tx) + assertEqual(parsedTx.Raw.Transaction, tx) } } diff --git a/x/evm/types/tracer.go b/x/evm/types/tracer.go index ace4b4e224..ea4de00f3a 100644 --- a/x/evm/types/tracer.go +++ b/x/evm/types/tracer.go @@ -36,7 +36,7 @@ const ( // NewTracer creates a new Logger tracer to collect execution traces from an // EVM transaction. -func NewTracer(tracer string, msg core.Message, rules params.Rules) vm.EVMLogger { +func NewTracer(tracer string, msg *core.Message, rules params.Rules) vm.EVMLogger { // TODO: enable additional log configuration logCfg := &logger.Config{ Debug: true, diff --git a/x/evm/types/tx.go b/x/evm/types/tx.go index 6f8ea659cf..64e39bc534 100644 --- a/x/evm/types/tx.go +++ b/x/evm/types/tx.go @@ -28,9 +28,9 @@ import ( // tip price: // // tx_priority = tip_price / priority_reduction -func GetTxPriority(txData TxData, baseFee *big.Int) (priority int64) { +func GetTxPriority(msg *MsgEthereumTx, baseFee *big.Int) (priority int64) { // calculate priority based on effective gas price - tipPrice := txData.EffectiveGasPrice(baseFee) + tipPrice := msg.GetEffectiveGasPrice(baseFee) // if london hardfork is not enabled, tipPrice is the gasPrice if baseFee != nil { tipPrice = new(big.Int).Sub(tipPrice, baseFee) diff --git a/x/evm/types/tx.pb.go b/x/evm/types/tx.pb.go index d5c5aa0d26..e889b73d00 100644 --- a/x/evm/types/tx.pb.go +++ b/x/evm/types/tx.pb.go @@ -41,12 +41,14 @@ 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:"-"` + DeprecatedHash string `protobuf:"bytes,3,opt,name=deprecated_hash,json=deprecatedHash,proto3" json:"deprecated_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 []byte `protobuf:"bytes,5,opt,name=from,proto3" json:"from,omitempty"` + // raw is the raw bytes of the ethereum transaction + Raw EthereumTx `protobuf:"bytes,6,opt,name=raw,proto3,customtype=EthereumTx" json:"raw"` } func (m *MsgEthereumTx) Reset() { *m = MsgEthereumTx{} } @@ -457,72 +459,74 @@ func init() { func init() { proto.RegisterFile("ethermint/evm/v1/tx.proto", fileDescriptor_f75ac0a12d075f21) } var fileDescriptor_f75ac0a12d075f21 = []byte{ - // 1039 bytes of a gzipped FileDescriptorProto + // 1064 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xce, 0xda, 0xeb, 0x5f, 0x63, 0x37, 0xad, 0x46, 0x89, 0xba, 0xb6, 0x88, 0xd7, 0x6c, 0x05, - 0xb8, 0x45, 0xd9, 0x55, 0x83, 0x54, 0xa9, 0x3e, 0x11, 0x37, 0x09, 0x14, 0x25, 0xa2, 0x5a, 0xdc, - 0x0b, 0x20, 0x59, 0x93, 0xdd, 0xc9, 0x7a, 0x55, 0xef, 0xce, 0x6a, 0x67, 0x6c, 0xd9, 0x48, 0x48, - 0xa8, 0x27, 0x8e, 0x54, 0xfc, 0x03, 0x9c, 0x39, 0xf5, 0xd0, 0x33, 0x17, 0x84, 0x54, 0x71, 0xaa, - 0xe0, 0x82, 0x38, 0x18, 0xe4, 0x20, 0x55, 0xe4, 0xc8, 0x99, 0x03, 0x9a, 0x99, 0x75, 0x1c, 0x77, - 0x71, 0x02, 0x95, 0xe0, 0x36, 0x6f, 0xde, 0x37, 0x3b, 0xdf, 0xfb, 0xbe, 0xf1, 0x7b, 0x06, 0x55, - 0xcc, 0x7a, 0x38, 0x0e, 0xfc, 0x90, 0x59, 0x78, 0x18, 0x58, 0xc3, 0x9b, 0x16, 0x1b, 0x99, 0x51, - 0x4c, 0x18, 0x81, 0x57, 0x4e, 0x53, 0x26, 0x1e, 0x06, 0xe6, 0xf0, 0x66, 0xed, 0xaa, 0x43, 0x68, - 0x40, 0xa8, 0x15, 0x50, 0x8f, 0x23, 0x03, 0xea, 0x49, 0x68, 0xad, 0x2a, 0x13, 0x5d, 0x11, 0x59, - 0x32, 0x48, 0x52, 0x6b, 0x1e, 0xf1, 0x88, 0xdc, 0xe7, 0xab, 0x64, 0xf7, 0x15, 0x8f, 0x10, 0xaf, - 0x8f, 0x2d, 0x14, 0xf9, 0x16, 0x0a, 0x43, 0xc2, 0x10, 0xf3, 0x49, 0x38, 0x3b, 0x53, 0x4d, 0xb2, - 0x22, 0x3a, 0x1c, 0x1c, 0x59, 0x28, 0x1c, 0x27, 0xa9, 0x6b, 0x29, 0xbe, 0xc8, 0x71, 0x30, 0xa5, - 0x5d, 0x36, 0x88, 0xfa, 0x38, 0x01, 0xd5, 0x52, 0xa0, 0x3e, 0x99, 0x51, 0xdd, 0x48, 0xe5, 0x22, - 0x14, 0xa3, 0x20, 0xb9, 0xda, 0xf8, 0x4e, 0x01, 0x97, 0x0e, 0xa8, 0xb7, 0xcb, 0x41, 0x78, 0x10, - 0x74, 0x46, 0xb0, 0x09, 0x54, 0x17, 0x31, 0xa4, 0x29, 0x0d, 0xa5, 0x59, 0xde, 0x5a, 0x33, 0x25, - 0x37, 0x73, 0xc6, 0xcd, 0xdc, 0x0e, 0xc7, 0xb6, 0x40, 0xc0, 0x2a, 0x50, 0xa9, 0xff, 0x09, 0xd6, - 0x32, 0x0d, 0xa5, 0xa9, 0xb4, 0x73, 0x27, 0x13, 0x5d, 0xd9, 0xb4, 0xc5, 0x16, 0xd4, 0x81, 0xda, - 0x43, 0xb4, 0xa7, 0x65, 0x1b, 0x4a, 0xb3, 0xd4, 0x2e, 0xff, 0x31, 0xd1, 0x0b, 0x71, 0x3f, 0x6a, - 0x19, 0x9b, 0x86, 0x2d, 0x12, 0xf0, 0x4d, 0x70, 0xd9, 0xc5, 0x51, 0x8c, 0x1d, 0xc4, 0xb0, 0xdb, - 0x3d, 0x8a, 0x49, 0xa0, 0xa9, 0x02, 0x9b, 0xd1, 0x14, 0x7b, 0x75, 0x9e, 0xda, 0x8b, 0x49, 0x00, - 0x21, 0x50, 0x05, 0x22, 0xd7, 0x50, 0x9a, 0x15, 0x5b, 0xac, 0x5b, 0x97, 0x3e, 0xff, 0x4a, 0x5f, - 0x79, 0xf8, 0xfc, 0xf1, 0x0d, 0x11, 0x1a, 0x8f, 0x32, 0xa0, 0xb8, 0x8f, 0x3d, 0xe4, 0x8c, 0x3b, - 0x23, 0xb8, 0x06, 0x72, 0x21, 0x09, 0x1d, 0x2c, 0x6a, 0x50, 0x6d, 0x19, 0xc0, 0x5b, 0xa0, 0xe4, - 0x21, 0xee, 0x99, 0xef, 0x48, 0xce, 0xa5, 0x76, 0xf5, 0xe7, 0x89, 0xbe, 0x2e, 0xed, 0xa3, 0xee, - 0x03, 0xd3, 0x27, 0x56, 0x80, 0x58, 0xcf, 0xbc, 0x1b, 0x32, 0xbb, 0xe8, 0x21, 0x7a, 0x8f, 0x43, - 0x61, 0x1d, 0x64, 0x3d, 0x44, 0x45, 0x29, 0x6a, 0xbb, 0x32, 0x9d, 0xe8, 0xc5, 0x77, 0x10, 0xdd, - 0xf7, 0x03, 0x9f, 0xd9, 0x3c, 0x01, 0x57, 0x41, 0x86, 0x11, 0xc9, 0xde, 0xce, 0x30, 0x02, 0x6f, - 0x83, 0xdc, 0x10, 0xf5, 0x07, 0x58, 0xd0, 0x2d, 0xb5, 0xaf, 0x2d, 0xbd, 0x63, 0x3a, 0xd1, 0xf3, - 0xdb, 0x01, 0x19, 0x84, 0xcc, 0x96, 0x27, 0x78, 0xa1, 0x42, 0xfb, 0xbc, 0x2c, 0x54, 0xa8, 0x5c, - 0x01, 0xca, 0x50, 0x2b, 0x88, 0x0d, 0x65, 0xc8, 0xa3, 0x58, 0x2b, 0xca, 0x28, 0xe6, 0x11, 0xd5, - 0x4a, 0x32, 0xa2, 0xad, 0x55, 0x2e, 0xc9, 0xf7, 0x4f, 0x36, 0xf3, 0x9d, 0xd1, 0x0e, 0x62, 0xc8, - 0xf8, 0x26, 0x0b, 0x2a, 0xdb, 0xe2, 0xb5, 0xec, 0xfb, 0x94, 0x75, 0x46, 0xf0, 0x3d, 0x50, 0x74, - 0x7a, 0xc8, 0x0f, 0xbb, 0xbe, 0x2b, 0xa4, 0x29, 0xb5, 0xad, 0xf3, 0xc8, 0x15, 0xee, 0x70, 0xf0, - 0xdd, 0x9d, 0x93, 0x89, 0x5e, 0x70, 0xe4, 0xd2, 0x4e, 0x16, 0xee, 0x5c, 0xe3, 0xcc, 0x52, 0x8d, - 0xb3, 0xff, 0x5a, 0x63, 0xf5, 0x7c, 0x8d, 0x73, 0x69, 0x8d, 0xf3, 0x2f, 0xad, 0x71, 0xe1, 0x8c, - 0xc6, 0x1f, 0x81, 0xa2, 0xfc, 0x59, 0x61, 0xaa, 0x15, 0x1b, 0xd9, 0x66, 0x79, 0x6b, 0xc3, 0x7c, - 0xb1, 0x1b, 0x98, 0x52, 0xca, 0x0e, 0xff, 0xdd, 0xb5, 0x1b, 0x4f, 0x27, 0xfa, 0xca, 0xc9, 0x44, - 0x07, 0xe8, 0x54, 0xdf, 0xaf, 0x7f, 0xd1, 0xc1, 0x5c, 0x6d, 0xfb, 0xf4, 0x83, 0xd2, 0xc0, 0xd2, - 0x82, 0x81, 0x60, 0xc1, 0xc0, 0xf2, 0x32, 0x03, 0xff, 0xcc, 0x82, 0xca, 0xce, 0x38, 0x44, 0x81, - 0xef, 0xec, 0x61, 0xfc, 0xbf, 0x18, 0x78, 0x1b, 0x94, 0xb9, 0x81, 0xcc, 0x8f, 0xba, 0x0e, 0x8a, - 0x2e, 0xb6, 0x90, 0xdb, 0xdd, 0xf1, 0xa3, 0x3b, 0x28, 0x9a, 0x1d, 0x3d, 0xc2, 0x58, 0x1c, 0x55, - 0xff, 0xc9, 0xd1, 0x3d, 0x8c, 0xf9, 0xd1, 0xc4, 0xfe, 0xdc, 0xf9, 0xf6, 0xe7, 0xd3, 0xf6, 0x17, - 0x5e, 0xda, 0xfe, 0xe2, 0x12, 0xfb, 0x4b, 0xff, 0x89, 0xfd, 0x60, 0xc1, 0xfe, 0xf2, 0x82, 0xfd, - 0x95, 0x65, 0xf6, 0x1b, 0xa0, 0xb6, 0x3b, 0x62, 0x38, 0xa4, 0x3e, 0x09, 0xdf, 0x8f, 0xc4, 0xc0, - 0x98, 0xf7, 0xe9, 0x96, 0xca, 0xd1, 0xc6, 0xb7, 0x0a, 0x58, 0x5f, 0xe8, 0xdf, 0x36, 0xa6, 0x11, - 0x09, 0xa9, 0x28, 0x54, 0xb4, 0x60, 0xf1, 0x4e, 0x92, 0xae, 0x7b, 0x1d, 0xa8, 0x7d, 0xe2, 0x51, - 0x2d, 0x23, 0x8a, 0x5c, 0x4f, 0x17, 0xb9, 0x4f, 0x3c, 0x5b, 0x40, 0xe0, 0x15, 0x90, 0x8d, 0x31, - 0x13, 0x0f, 0xa0, 0x62, 0xf3, 0x25, 0xac, 0x82, 0xe2, 0x30, 0xe8, 0xe2, 0x38, 0x26, 0x71, 0xd2, - 0xed, 0x0a, 0xc3, 0x60, 0x97, 0x87, 0x3c, 0xc5, 0xad, 0x1f, 0x50, 0xec, 0x4a, 0x13, 0xed, 0x82, - 0x87, 0xe8, 0x7d, 0x8a, 0x5d, 0xb8, 0x01, 0xc0, 0x61, 0x9f, 0x38, 0x0f, 0xba, 0x82, 0x8c, 0x6c, - 0x6c, 0x25, 0xb1, 0xf3, 0x2e, 0xa2, 0xbd, 0xa4, 0x8a, 0x47, 0x0a, 0xb8, 0x7c, 0x40, 0xbd, 0xfb, - 0x91, 0x8b, 0x18, 0xbe, 0x27, 0xe6, 0x13, 0x6f, 0x25, 0x68, 0xc0, 0x7a, 0x24, 0xf6, 0xd9, 0x38, - 0x79, 0xec, 0xda, 0x0f, 0x4f, 0x36, 0xd7, 0x92, 0x69, 0xbb, 0xed, 0xba, 0x31, 0xa6, 0xf4, 0x03, - 0x16, 0xfb, 0xa1, 0x67, 0xcf, 0xa1, 0xf0, 0x16, 0xc8, 0xcb, 0x09, 0x27, 0x1e, 0x76, 0x79, 0x4b, - 0x4b, 0x57, 0x29, 0x6f, 0x68, 0xab, 0xdc, 0x45, 0x3b, 0x41, 0xb7, 0x56, 0xf9, 0x30, 0x99, 0x7f, - 0xc7, 0xa8, 0x82, 0xab, 0x2f, 0x50, 0x9a, 0x49, 0xbb, 0xf5, 0xbb, 0x02, 0xb2, 0x07, 0xd4, 0x83, - 0x9f, 0x02, 0x70, 0x66, 0x70, 0xea, 0xe9, 0x8b, 0x16, 0x9c, 0xa9, 0xbd, 0x71, 0x01, 0x60, 0xf6, - 0x7d, 0xe3, 0xb5, 0x87, 0x3f, 0xfe, 0xf6, 0x65, 0x46, 0x37, 0x36, 0xac, 0xd4, 0xf0, 0xc6, 0x09, - 0xba, 0xcb, 0x46, 0xf0, 0x63, 0x50, 0x59, 0x50, 0xec, 0xd5, 0xbf, 0xfd, 0xfe, 0x59, 0x48, 0xed, - 0xfa, 0x85, 0x90, 0x19, 0x89, 0x5a, 0xee, 0xb3, 0xe7, 0x8f, 0x6f, 0x28, 0xed, 0xb7, 0x9f, 0x4e, - 0xeb, 0xca, 0xb3, 0x69, 0x5d, 0xf9, 0x75, 0x5a, 0x57, 0xbe, 0x38, 0xae, 0xaf, 0x3c, 0x3b, 0xae, - 0xaf, 0xfc, 0x74, 0x5c, 0x5f, 0xf9, 0xf0, 0x75, 0xcf, 0x67, 0xbd, 0xc1, 0xa1, 0xe9, 0x90, 0x80, - 0xb3, 0x23, 0xf4, 0x0c, 0xdb, 0x91, 0xe0, 0xcb, 0xc6, 0x11, 0xa6, 0x87, 0x79, 0xf1, 0xd7, 0xe1, - 0xad, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x65, 0x8d, 0x8e, 0x0a, 0x7b, 0x09, 0x00, 0x00, + 0x14, 0xce, 0xda, 0xeb, 0x5f, 0x63, 0x37, 0xad, 0x46, 0x89, 0xba, 0xb6, 0x88, 0xd7, 0x6c, 0xf9, + 0xe1, 0x16, 0x65, 0x57, 0x0d, 0xa8, 0x52, 0x73, 0x22, 0xdb, 0x24, 0x50, 0x94, 0x88, 0x6a, 0x71, + 0x2f, 0x80, 0x64, 0x4d, 0x76, 0x27, 0xeb, 0x55, 0xbd, 0x3b, 0xab, 0x9d, 0xb1, 0xb1, 0x91, 0x90, + 0xaa, 0x9e, 0x38, 0x52, 0xf1, 0x0f, 0x70, 0xe6, 0xd4, 0x43, 0xcf, 0x5c, 0xb8, 0x54, 0x9c, 0x2a, + 0xb8, 0xa0, 0x1e, 0x0c, 0x4a, 0x90, 0x2a, 0x72, 0xe4, 0xcc, 0x01, 0xcd, 0xcc, 0x3a, 0xb6, 0x6b, + 0x9c, 0x40, 0x25, 0xb8, 0xcd, 0x9b, 0xf7, 0xbd, 0x99, 0xf7, 0xbe, 0x6f, 0xf6, 0xbd, 0x05, 0x55, + 0xcc, 0x3a, 0x38, 0x09, 0x83, 0x88, 0x59, 0xb8, 0x1f, 0x5a, 0xfd, 0xeb, 0x16, 0x1b, 0x98, 0x71, + 0x42, 0x18, 0x81, 0x97, 0x4e, 0x5d, 0x26, 0xee, 0x87, 0x66, 0xff, 0x7a, 0xed, 0xb2, 0x4b, 0x68, + 0x48, 0xa8, 0x15, 0x52, 0x9f, 0x23, 0x43, 0xea, 0x4b, 0x68, 0xad, 0x2a, 0x1d, 0x6d, 0x61, 0x59, + 0xd2, 0x48, 0x5d, 0x2b, 0x3e, 0xf1, 0x89, 0xdc, 0xe7, 0xab, 0x74, 0xf7, 0x15, 0x9f, 0x10, 0xbf, + 0x8b, 0x2d, 0x14, 0x07, 0x16, 0x8a, 0x22, 0xc2, 0x10, 0x0b, 0x48, 0x34, 0x8e, 0xa9, 0xa6, 0x5e, + 0x61, 0x1d, 0xf4, 0x0e, 0x2d, 0x14, 0x0d, 0x53, 0xd7, 0x95, 0xb9, 0x7c, 0x91, 0xeb, 0x62, 0x4a, + 0xdb, 0xac, 0x17, 0x77, 0x71, 0x0a, 0xaa, 0xcd, 0x81, 0xba, 0x64, 0x9c, 0xea, 0xda, 0x9c, 0x2f, + 0x46, 0x09, 0x0a, 0xd3, 0xab, 0x8d, 0xfb, 0x19, 0x70, 0x61, 0x9f, 0xfa, 0x3b, 0x1c, 0x84, 0x7b, + 0x61, 0x6b, 0x00, 0x9b, 0x40, 0xf5, 0x10, 0x43, 0x9a, 0xd2, 0x50, 0x9a, 0xe5, 0x8d, 0x15, 0x53, + 0xe6, 0x66, 0x8e, 0x73, 0x33, 0xb7, 0xa2, 0xa1, 0x23, 0x10, 0xb0, 0x0a, 0x54, 0x1a, 0x7c, 0x8e, + 0xb5, 0x4c, 0x43, 0x69, 0x2a, 0x76, 0xee, 0x64, 0xa4, 0x2b, 0xeb, 0x8e, 0xd8, 0x82, 0xef, 0x80, + 0x8b, 0x1e, 0x8e, 0x13, 0xec, 0x22, 0x86, 0xbd, 0x76, 0x07, 0xd1, 0x8e, 0x96, 0x6d, 0x28, 0xcd, + 0x92, 0x5d, 0xfe, 0x63, 0xa4, 0x17, 0x92, 0x6e, 0xbc, 0x69, 0xac, 0x1b, 0xce, 0xf2, 0x04, 0xf3, + 0x3e, 0xa2, 0x1d, 0xf8, 0xd6, 0x4c, 0xd4, 0x61, 0x42, 0x42, 0x4d, 0x15, 0x51, 0x19, 0x4d, 0x99, + 0x06, 0xef, 0x26, 0x24, 0x84, 0x10, 0xa8, 0x02, 0x91, 0x6b, 0x28, 0xcd, 0x8a, 0x23, 0xd6, 0xf0, + 0x35, 0x90, 0x4d, 0xd0, 0x67, 0x5a, 0x9e, 0x6f, 0xd9, 0xf0, 0xc9, 0x48, 0x5f, 0x7a, 0x36, 0xd2, + 0xc1, 0xa4, 0x38, 0x87, 0xbb, 0x37, 0x2f, 0x7c, 0xf9, 0x8d, 0xbe, 0xf4, 0xe0, 0xf9, 0xa3, 0x6b, + 0x22, 0xc8, 0x78, 0x98, 0x01, 0xc5, 0x3d, 0xec, 0x23, 0x77, 0xd8, 0x1a, 0xc0, 0x15, 0x90, 0x8b, + 0x48, 0xe4, 0x62, 0x51, 0xbe, 0xea, 0x48, 0x03, 0xde, 0x00, 0x25, 0x1f, 0x71, 0xb9, 0x03, 0x57, + 0x96, 0x5b, 0xb2, 0xab, 0xcf, 0x46, 0xfa, 0xaa, 0x54, 0x9e, 0x7a, 0xf7, 0xcc, 0x80, 0x58, 0x21, + 0x62, 0x1d, 0xf3, 0x76, 0xc4, 0x9c, 0xa2, 0x8f, 0xe8, 0x1d, 0x0e, 0x85, 0x75, 0x90, 0xf5, 0x11, + 0x15, 0xa5, 0xab, 0x76, 0xe5, 0x68, 0xa4, 0x17, 0xdf, 0x43, 0x74, 0x2f, 0x08, 0x03, 0xe6, 0x70, + 0x07, 0x5c, 0x06, 0x19, 0x46, 0x64, 0x8d, 0x4e, 0x86, 0x11, 0x78, 0x13, 0xe4, 0xfa, 0xa8, 0xdb, + 0xc3, 0xa2, 0xa8, 0x92, 0x7d, 0x65, 0xe1, 0x1d, 0x47, 0x23, 0x3d, 0xbf, 0x15, 0x92, 0x5e, 0xc4, + 0x1c, 0x19, 0xc1, 0xe9, 0x10, 0xb2, 0xe5, 0x25, 0x1d, 0x42, 0xa0, 0x0a, 0x50, 0xfa, 0x5a, 0x41, + 0x6c, 0x28, 0x7d, 0x6e, 0x25, 0x5a, 0x51, 0x5a, 0x09, 0xb7, 0xa8, 0x56, 0x92, 0x16, 0xdd, 0x5c, + 0xe6, 0x94, 0xfc, 0xf0, 0x78, 0x3d, 0xdf, 0x1a, 0x6c, 0x23, 0x86, 0x8c, 0xef, 0xb2, 0xa0, 0xb2, + 0x25, 0x1e, 0xda, 0x5e, 0x40, 0x59, 0x6b, 0x00, 0x3f, 0x00, 0x45, 0xb7, 0x83, 0x82, 0xa8, 0x1d, + 0x78, 0x82, 0x9a, 0x92, 0x6d, 0x9d, 0x95, 0x5c, 0xe1, 0x16, 0x07, 0xdf, 0xde, 0x3e, 0x19, 0xe9, + 0x05, 0x57, 0x2e, 0x9d, 0x74, 0xe1, 0x4d, 0x38, 0xce, 0x2c, 0xe4, 0x38, 0xfb, 0xaf, 0x39, 0x56, + 0xcf, 0xe6, 0x38, 0x37, 0xcf, 0x71, 0xfe, 0xa5, 0x39, 0x2e, 0x4c, 0x71, 0xfc, 0x09, 0x28, 0xca, + 0x2f, 0x12, 0x53, 0xad, 0xd8, 0xc8, 0x36, 0xcb, 0x1b, 0x6b, 0xe6, 0x8b, 0x8d, 0xc4, 0x94, 0x54, + 0xb6, 0xf8, 0x27, 0x6b, 0x37, 0xf8, 0xb3, 0x3c, 0x19, 0xe9, 0x00, 0x9d, 0xf2, 0xfb, 0xed, 0x2f, + 0x3a, 0x98, 0xb0, 0xed, 0x9c, 0x1e, 0x28, 0x05, 0x2c, 0xcd, 0x08, 0x08, 0x66, 0x04, 0x2c, 0x2f, + 0x12, 0xf0, 0xcf, 0x2c, 0xa8, 0x6c, 0x0f, 0x23, 0x14, 0x06, 0xee, 0x2e, 0xc6, 0xff, 0x8b, 0x80, + 0x37, 0x41, 0x99, 0x0b, 0xc8, 0x82, 0xb8, 0xed, 0xa2, 0xf8, 0x7c, 0x09, 0xb9, 0xdc, 0xad, 0x20, + 0xbe, 0x85, 0xe2, 0x71, 0xe8, 0x21, 0xc6, 0x22, 0x54, 0xfd, 0x27, 0xa1, 0xbb, 0x18, 0xf3, 0xd0, + 0x54, 0xfe, 0xdc, 0xd9, 0xf2, 0xe7, 0xe7, 0xe5, 0x2f, 0xbc, 0xb4, 0xfc, 0xc5, 0x05, 0xf2, 0x97, + 0xfe, 0x13, 0xf9, 0xc1, 0x8c, 0xfc, 0xe5, 0x19, 0xf9, 0x2b, 0x8b, 0xe4, 0x37, 0x40, 0x6d, 0x67, + 0xc0, 0x70, 0x44, 0x03, 0x12, 0x7d, 0x18, 0x8b, 0x59, 0x33, 0xe9, 0x82, 0x9b, 0x2a, 0x47, 0x1b, + 0xdf, 0x2b, 0x60, 0x75, 0xa6, 0xf5, 0x3b, 0x98, 0xc6, 0x24, 0xa2, 0xa2, 0x50, 0xd1, 0xb2, 0xc5, + 0x3b, 0x71, 0xc4, 0x1a, 0x5e, 0x05, 0x6a, 0x97, 0xf8, 0x54, 0xcb, 0x88, 0x22, 0x57, 0xe7, 0x8b, + 0xdc, 0x23, 0xbe, 0x23, 0x20, 0xf0, 0x12, 0xc8, 0x26, 0x98, 0x89, 0x07, 0x50, 0x71, 0xf8, 0x12, + 0x56, 0x41, 0xb1, 0x1f, 0xb6, 0x71, 0x92, 0x90, 0x24, 0xed, 0x76, 0x85, 0x7e, 0xb8, 0xc3, 0x4d, + 0xee, 0xe2, 0xd2, 0xf7, 0x28, 0xf6, 0xa4, 0x88, 0x4e, 0xc1, 0x47, 0xf4, 0x2e, 0xc5, 0x1e, 0x5c, + 0x03, 0xe0, 0xa0, 0x4b, 0xdc, 0x7b, 0x72, 0x7e, 0xc8, 0xc6, 0x56, 0x12, 0x3b, 0x7c, 0x5a, 0xa4, + 0x55, 0x3c, 0x54, 0xc0, 0xc5, 0x7d, 0xea, 0xdf, 0x8d, 0x3d, 0xc4, 0xf0, 0x1d, 0x31, 0xda, 0x78, + 0x2b, 0x41, 0x3d, 0xd6, 0x21, 0x49, 0xc0, 0x86, 0xe9, 0x63, 0xd7, 0x7e, 0x7c, 0xbc, 0xbe, 0x92, + 0x0e, 0xea, 0x2d, 0xcf, 0x4b, 0x30, 0xa5, 0x1f, 0xb1, 0x24, 0x88, 0x7c, 0x67, 0x02, 0x85, 0x37, + 0x40, 0x5e, 0x0e, 0x47, 0xf1, 0xb0, 0xcb, 0x1b, 0xda, 0x7c, 0x95, 0xf2, 0x06, 0x5b, 0xe5, 0x2a, + 0x3a, 0x29, 0x7a, 0x73, 0x99, 0x0f, 0x93, 0xc9, 0x39, 0x46, 0x15, 0x5c, 0x7e, 0x21, 0xa5, 0x31, + 0xb5, 0x1b, 0xbf, 0x2b, 0x20, 0xbb, 0x4f, 0x7d, 0xf8, 0x05, 0x98, 0x1a, 0x4b, 0x50, 0x9f, 0xbf, + 0x68, 0x46, 0x99, 0xda, 0x9b, 0xe7, 0x00, 0xc6, 0xe7, 0x1b, 0xaf, 0x3f, 0xf8, 0xe9, 0xb7, 0xaf, + 0x33, 0xba, 0xb1, 0x66, 0xcd, 0xcd, 0x7d, 0x9c, 0xa2, 0xdb, 0x6c, 0x00, 0x3f, 0x05, 0x95, 0x19, + 0xc6, 0x5e, 0xfd, 0xdb, 0xf3, 0xa7, 0x21, 0xb5, 0xab, 0xe7, 0x42, 0xc6, 0x49, 0xd4, 0x72, 0xf7, + 0x9f, 0x3f, 0xba, 0xa6, 0xd8, 0xef, 0x3e, 0x39, 0xaa, 0x2b, 0x4f, 0x8f, 0xea, 0xca, 0xaf, 0x47, + 0x75, 0xe5, 0xab, 0xe3, 0xfa, 0xd2, 0xd3, 0xe3, 0xfa, 0xd2, 0xcf, 0xc7, 0xf5, 0xa5, 0x8f, 0xdf, + 0xf0, 0x03, 0xd6, 0xe9, 0x1d, 0x98, 0x2e, 0x09, 0x79, 0x76, 0x84, 0x4e, 0x65, 0x3b, 0x10, 0xf9, + 0xb2, 0x61, 0x8c, 0xe9, 0x41, 0x5e, 0xfc, 0x75, 0xbc, 0xfd, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xb5, 0x29, 0xc9, 0x6e, 0xb6, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -667,6 +671,16 @@ func (m *MsgEthereumTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.Raw.Size() + i -= size + if _, err := m.Raw.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 if len(m.From) > 0 { i -= len(m.From) copy(dAtA[i:], m.From) @@ -681,10 +695,10 @@ func (m *MsgEthereumTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if len(m.Hash) > 0 { - i -= len(m.Hash) - copy(dAtA[i:], m.Hash) - i = encodeVarintTx(dAtA, i, uint64(len(m.Hash))) + if len(m.DeprecatedHash) > 0 { + i -= len(m.DeprecatedHash) + copy(dAtA[i:], m.DeprecatedHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.DeprecatedHash))) i-- dAtA[i] = 0x1a } @@ -1229,7 +1243,7 @@ func (m *MsgEthereumTx) Size() (n int) { if m.Size_ != 0 { n += 9 } - l = len(m.Hash) + l = len(m.DeprecatedHash) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1241,6 +1255,8 @@ func (m *MsgEthereumTx) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = m.Raw.Size() + n += 1 + l + sovTx(uint64(l)) return n } @@ -1548,7 +1564,7 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { m.Size_ = float64(math.Float64frombits(v)) case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedHash", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1576,7 +1592,7 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hash = string(dAtA[iNdEx:postIndex]) + m.DeprecatedHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { @@ -1644,6 +1660,39 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { m.From = []byte{} } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Raw", 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 + } + if err := m.Raw.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/evm/types/tx_args.go b/x/evm/types/tx_args.go index c3ef8ab99d..dd7b6475e4 100644 --- a/x/evm/types/tx_args.go +++ b/x/evm/types/tx_args.go @@ -20,8 +20,6 @@ import ( "fmt" "math/big" - sdkmath "cosmossdk.io/math" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" @@ -71,18 +69,7 @@ func (args *TransactionArgs) String() string { // ToTransaction converts the arguments to an ethereum transaction. // This assumes that setTxDefaults has been called. func (args *TransactionArgs) ToTransaction() *MsgEthereumTx { - var ( - chainID, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas sdkmath.Int - gas, nonce uint64 - to string - from []byte - ) - - // Set sender address or use zero address if none specified. - if args.ChainID != nil { - chainID = sdkmath.NewIntFromBigInt(args.ChainID.ToInt()) - } - + var gas, nonce uint64 if args.Nonce != nil { nonce = uint64(*args.Nonce) } @@ -91,90 +78,59 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx { gas = uint64(*args.Gas) } - if args.GasPrice != nil { - gasPrice = sdkmath.NewIntFromBigInt(args.GasPrice.ToInt()) - } - - if args.MaxFeePerGas != nil { - maxFeePerGas = sdkmath.NewIntFromBigInt(args.MaxFeePerGas.ToInt()) - } - - if args.MaxPriorityFeePerGas != nil { - maxPriorityFeePerGas = sdkmath.NewIntFromBigInt(args.MaxPriorityFeePerGas.ToInt()) - } - - if args.Value != nil { - value = sdkmath.NewIntFromBigInt(args.Value.ToInt()) - } - - if args.To != nil { - to = args.To.Hex() - } - - var data TxData + var data types.TxData switch { case args.MaxFeePerGas != nil: - al := AccessList{} + al := types.AccessList{} if args.AccessList != nil { - al = NewAccessList(args.AccessList) + al = *args.AccessList } - - data = &DynamicFeeTx{ - To: to, - ChainID: &chainID, - Nonce: nonce, - GasLimit: gas, - GasFeeCap: &maxFeePerGas, - GasTipCap: &maxPriorityFeePerGas, - Amount: &value, - Data: args.GetData(), - Accesses: al, + data = &types.DynamicFeeTx{ + To: args.To, + ChainID: (*big.Int)(args.ChainID), + Nonce: nonce, + Gas: gas, + GasFeeCap: (*big.Int)(args.MaxFeePerGas), + GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), + Value: (*big.Int)(args.Value), + Data: args.GetData(), + AccessList: al, } case args.AccessList != nil: - data = &AccessListTx{ - To: to, - ChainID: &chainID, - Nonce: nonce, - GasLimit: gas, - GasPrice: &gasPrice, - Amount: &value, - Data: args.GetData(), - Accesses: NewAccessList(args.AccessList), + data = &types.AccessListTx{ + To: args.To, + ChainID: (*big.Int)(args.ChainID), + Nonce: nonce, + Gas: gas, + GasPrice: (*big.Int)(args.GasPrice), + Value: (*big.Int)(args.Value), + Data: args.GetData(), + AccessList: *args.AccessList, } default: - data = &LegacyTx{ - To: to, + data = &types.LegacyTx{ + To: args.To, Nonce: nonce, - GasLimit: gas, - GasPrice: &gasPrice, - Amount: &value, + Gas: gas, + GasPrice: (*big.Int)(args.GasPrice), + Value: (*big.Int)(args.Value), Data: args.GetData(), } } - anyData, err := PackTxData(data) - if err != nil { - return nil - } - + tx := NewTxWithData(data) if args.From != nil { - from = args.From.Bytes() - } - - msg := MsgEthereumTx{ - Data: anyData, - From: from, + tx.From = args.From.Bytes() } - msg.Hash = msg.AsTransaction().Hash().Hex() - return &msg + return tx } // ToMessage converts the arguments to the Message type used by the core evm. // This assumes that setTxDefaults has been called. -func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (core.Message, error) { +func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*core.Message, error) { // Reject invalid combinations of pre- and post-1559 fee styles if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return core.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") + return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") } // Set sender address or use zero address if none specified. @@ -241,7 +197,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (c nonce = uint64(*args.Nonce) } - msg := core.Message{ + msg := &core.Message{ From: addr, To: args.To, Nonce: nonce, diff --git a/x/evm/types/utils.go b/x/evm/types/utils.go index 145077146c..a4b0e577cd 100644 --- a/x/evm/types/utils.go +++ b/x/evm/types/utils.go @@ -150,7 +150,6 @@ func UnwrapEthereumMsg(tx *sdk.Tx, ethHash common.Hash) (*MsgEthereumTx, error) return nil, fmt.Errorf("invalid tx type: %T", tx) } txHash := ethMsg.AsTransaction().Hash() - ethMsg.Hash = txHash.Hex() if txHash == ethHash { return ethMsg, nil } diff --git a/x/evm/types/utils_test.go b/x/evm/types/utils_test.go index 95175835ae..b9f3ccf98e 100644 --- a/x/evm/types/utils_test.go +++ b/x/evm/types/utils_test.go @@ -61,6 +61,7 @@ func TestUnwrapEthererumMsg(t *testing.T) { msg := evmtypes.NewTx(big.NewInt(1), 0, &common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil, nil, []byte{}, nil) err = builder.SetMsgs(msg) + require.NoError(t, err) tx = builder.GetTx().(sdk.Tx) msg_, err := evmtypes.UnwrapEthereumMsg(&tx, msg.AsTransaction().Hash())