Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(evm): fix wrong Ethereum Tx type when convert to MsgEthereumTx #76

Merged
merged 5 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (test) [#50](https:/EscanBE/evermint/pull/50) Set chain-id into client.toml during init testnet
- (ante) [#59](https:/EscanBE/evermint/pull/59) Prevent panic when building error message of fee which overflow int64
- (swagger) [#66](https:/EscanBE/evermint/pull/66) Correct script gen swagger after switched to use vanilla Cosmos-SDK
- (evm) [#76](https:/EscanBE/evermint/pull/76) Fix wrong Ethereum Tx type when convert to `MsgEthereumTx`

### Client Breaking

Expand Down
3 changes: 2 additions & 1 deletion integration_test_util/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,12 @@ func newTestAccountFromMnemonic(t *testing.T, mnemonic string) *itutiltypes.Test

//goland:noinspection SpellCheckingInspection
algo, err = keyring.NewSigningAlgoFromString("eth_secp256k1", supportedKeyringAlgorithms)
require.NoError(t, err)

derivedPriv, err := algo.Derive()(mnemonic, "", hdPath)
require.NoError(t, err)

privKey := algo.Generate()(derivedPriv)
require.NoError(t, err)

priv := &ethsecp256k1.PrivKey{
Key: privKey.Bytes(),
Expand Down
13 changes: 10 additions & 3 deletions integration_test_util/types/chain_app_imp_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ func NewChainApp(chainCfg ChainConfig, disableTendermint bool, testConfig TestCo
BaseAccount: authtypes.NewBaseAccount(account.GetCosmosAddress(), account.GetPubKey(), uint64(i), 0),
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
}
if account.Type == TestAccountTypeValidator {

switch account.Type {
case TestAccountTypeValidator:
genesisValidatorAccounts = append(genesisValidatorAccounts, acc)

signingInfos = append(signingInfos, slashingtypes.SigningInfo{
Expand All @@ -102,11 +104,16 @@ func NewChainApp(chainCfg ChainConfig, disableTendermint bool, testConfig TestCo
MissedBlocksCounter: 0,
},
})
} else if account.Type == TestAccountTypeWallet {

break
case TestAccountTypeWallet:
genesisWalletAccounts = append(genesisWalletAccounts, acc)
} else {

break
default:
panic(fmt.Sprintf("unknown account type %d", account.Type))
}

genesisBalances = append(genesisBalances, banktypes.Balance{
Address: acc.GetAddress().String(),
Coins: genesisAccountBalance,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package demo

import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/EscanBE/evermint/v12/integration_test_util"
Expand Down Expand Up @@ -627,20 +628,45 @@ func (suite *EthRpcTestSuite) Test_SendRawTransaction() {

// helper methods

newMsgEthTx := func(sender *itutiltypes.TestAccount) *evmtypes.MsgEthereumTx {
newMsgEthTxDynamic := func(sender *itutiltypes.TestAccount) *evmtypes.MsgEthereumTx {
to := receiver.GetEthAddress()

gasPrice := suite.App().FeeMarketKeeper().GetBaseFee(suite.Ctx())
baseFee := suite.App().FeeMarketKeeper().GetBaseFee(suite.Ctx())
gasTipCap := big.NewInt(10000)
gasFeeCap := new(big.Int).Mul(baseFee, gasTipCap)
evmTxArgs := &evmtypes.EvmTxArgs{
ChainID: suite.App().EvmKeeper().ChainID(),
Nonce: suite.App().EvmKeeper().GetNonce(suite.Ctx(), sender.GetEthAddress()),
GasLimit: 21000,
Input: nil,
GasFeeCap: gasFeeCap,
GasPrice: nil,
ChainID: suite.App().EvmKeeper().ChainID(),
Amount: big.NewInt(1),
GasTipCap: gasTipCap,
To: &to,
Accesses: nil,
}

msgEvmTx := evmtypes.NewTx(evmTxArgs)
msgEvmTx.From = sender.GetEthAddress().String()

return msgEvmTx
}

newMsgEthTxLegacy := func(sender *itutiltypes.TestAccount) *evmtypes.MsgEthereumTx {
to := receiver.GetEthAddress()

baseFee := suite.App().FeeMarketKeeper().GetBaseFee(suite.Ctx())
evmTxArgs := &evmtypes.EvmTxArgs{
Nonce: suite.App().EvmKeeper().GetNonce(suite.Ctx(), sender.GetEthAddress()),
GasLimit: 21000,
Input: nil,
GasFeeCap: nil,
GasPrice: baseFee,
ChainID: suite.App().EvmKeeper().ChainID(),
Amount: big.NewInt(1),
GasFeeCap: gasPrice,
GasPrice: gasPrice,
GasTipCap: big.NewInt(1),
GasTipCap: nil,
To: &to,
Accesses: nil,
}

Expand All @@ -650,8 +676,8 @@ func (suite *EthRpcTestSuite) Test_SendRawTransaction() {
return msgEvmTx
}

newSignedEthTx := func(sender *itutiltypes.TestAccount) *ethtypes.Transaction {
msgEvmTx := newMsgEthTx(sender)
newSignedEthTx := func(sender *itutiltypes.TestAccount, createMsgEthTx func(*itutiltypes.TestAccount) *evmtypes.MsgEthereumTx) *ethtypes.Transaction {
msgEvmTx := createMsgEthTx(sender)

ethTx := msgEvmTx.AsTransaction()
sig, _, err := sender.Signer.SignByAddress(msgEvmTx.GetFrom(), suite.CITS.EthSigner.Hash(ethTx).Bytes())
Expand All @@ -665,30 +691,40 @@ func (suite *EthRpcTestSuite) Test_SendRawTransaction() {

// signed tx

senderForSignedEthTx := suite.CITS.WalletAccounts.Number(1)
signedEthTx := newSignedEthTx(senderForSignedEthTx)
signedRlpBz, err := rlp.EncodeToBytes(signedEthTx)
senderForSignedEthTxDynamic1 := suite.CITS.WalletAccounts.Number(1)
signedEthTxDynamic1 := newSignedEthTx(senderForSignedEthTxDynamic1, newMsgEthTxDynamic)
bzSignedEthTx1, err := signedEthTxDynamic1.MarshalBinary()
suite.Require().NoError(err)

senderForSignedEthTxDynamic2 := suite.CITS.WalletAccounts.Number(2)
signedEthTxDynamic2 := newSignedEthTx(senderForSignedEthTxDynamic2, newMsgEthTxDynamic)
rlpSignedEthTxDynamic2, err := rlp.EncodeToBytes(signedEthTxDynamic2)
suite.Require().NoError(err)

senderForToBeSignedMsgEthTx := suite.CITS.WalletAccounts.Number(2)
toBeSignedMsgEthTx := newMsgEthTx(senderForToBeSignedMsgEthTx)
senderForSignedEthTxLegacy := suite.CITS.WalletAccounts.Number(3)
signedEthTxLegacy := newSignedEthTx(senderForSignedEthTxLegacy, newMsgEthTxLegacy)
rlpSignedEthTxLegacy, err := rlp.EncodeToBytes(signedEthTxLegacy)
suite.Require().NoError(err)

senderForToBeSignedMsgEthTx := suite.CITS.WalletAccounts.Number(4)
toBeSignedMsgEthTx := newMsgEthTxDynamic(senderForToBeSignedMsgEthTx)
signedCosmosMsgEthTx, err := suite.CITS.PrepareEthTx(senderForToBeSignedMsgEthTx, toBeSignedMsgEthTx)
suite.Require().NoError(err)
bzSignedCosmosMsgEthTx, err := txEncoder(signedCosmosMsgEthTx)
suite.Require().NoError(err)

// non-signed tx

senderForNonSignedMsgEthTx := suite.CITS.WalletAccounts.Number(3)
nonSignedMsgEthTx := newMsgEthTx(senderForNonSignedMsgEthTx)
nonSignedEthTx := nonSignedMsgEthTx.AsTransaction()
notSignedRlpBz, err := rlp.EncodeToBytes(nonSignedEthTx)
senderForNonSignedMsgEthTxDynamic := suite.CITS.WalletAccounts.Number(5)
nonSignedMsgEthTxDynamic := newMsgEthTxDynamic(senderForNonSignedMsgEthTxDynamic)
nonSignedEthTxDynamic := nonSignedMsgEthTxDynamic.AsTransaction()
bzNotSignedEthTxDynamic, err := nonSignedEthTxDynamic.MarshalBinary()
suite.Require().NoError(err)

err = txBuilder.SetMsgs(nonSignedMsgEthTx)
err = txBuilder.SetMsgs(nonSignedMsgEthTxDynamic)
suite.Require().NoError(err)

nonSignedTxEncodedBz, err := txEncoder(txBuilder.GetTx())
bzNotSignedTxEncoded1, err := txEncoder(txBuilder.GetTx())
suite.Require().NoError(err)

// begin test
Expand All @@ -701,24 +737,37 @@ func (suite *EthRpcTestSuite) Test_SendRawTransaction() {
expErrContains string
}{
{
name: "send signed tx",
rawTx: signedRlpBz,
sourceTxHash: signedEthTx.Hash(),
name: "send signed dynamic tx",
rawTx: bzSignedEthTx1,
sourceTxHash: signedEthTxDynamic1.Hash(),
expPass: true,
},
{
name: "send signed dynamic tx but dynamic can not be RLP encoded",
rawTx: rlpSignedEthTxDynamic2,
sourceTxHash: signedEthTxDynamic2.Hash(),
expPass: false,
expErrContains: "rlp: expected input list for types.LegacyTx",
},
{
name: "send signed legacy tx, RLP encoded",
rawTx: rlpSignedEthTxLegacy,
sourceTxHash: signedEthTxLegacy.Hash(),
expPass: true,
},
{
name: "not accept Cosmos tx, even tho signed",
rawTx: bzSignedCosmosMsgEthTx,
sourceTxHash: signedEthTx.Hash(),
sourceTxHash: signedEthTxDynamic1.Hash(),
expPass: false,
expErrContains: "transaction type not supported",
},
{
name: "send non-signed tx",
rawTx: notSignedRlpBz,
sourceTxHash: nonSignedEthTx.Hash(),
rawTx: bzNotSignedEthTxDynamic,
sourceTxHash: nonSignedEthTxDynamic.Hash(),
expPass: false,
expErrContains: "only replay-protected (EIP-155) transactions allowed over RPC",
expErrContains: "couldn't retrieve sender address from the ethereum transaction: invalid transaction v, r, s values",
},
{
name: "fail - empty bytes",
Expand All @@ -729,14 +778,15 @@ func (suite *EthRpcTestSuite) Test_SendRawTransaction() {
},
{
name: "fail - no RLP encoded bytes",
rawTx: nonSignedTxEncodedBz,
sourceTxHash: nonSignedMsgEthTx.AsTransaction().Hash(),
rawTx: bzNotSignedTxEncoded1,
sourceTxHash: nonSignedMsgEthTxDynamic.AsTransaction().Hash(),
expPass: false,
expErrContains: "transaction type not supported",
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
fmt.Println(hex.EncodeToString(tc.rawTx))
hash, err := suite.GetEthPublicAPI().SendRawTransaction(tc.rawTx)

if tc.expPass {
Expand All @@ -748,7 +798,6 @@ func (suite *EthRpcTestSuite) Test_SendRawTransaction() {
suite.Require().Error(err)
suite.Require().NotEmptyf(tc.expErrContains, "missing expected error to check against: %s", err.Error())
suite.Require().Contains(err.Error(), tc.expErrContains)
suite.Require().Equal(common.Hash{}, hash)

if tc.sourceTxHash == ([32]byte{}) { // empty
// ignore later tests
Expand Down
9 changes: 5 additions & 4 deletions x/evm/keeper/statedb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper_test

import (
"fmt"
"github.com/EscanBE/evermint/v12/constants"
"math/big"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
Expand Down Expand Up @@ -628,7 +629,7 @@ func (suite *KeeperTestSuite) CreateTestTx(msg *types.MsgEthereumTx, priv crypto
func (suite *KeeperTestSuite) TestAddLog() {
addr, privKey := utiltx.NewAddrKey()
ethTxParams := &types.EvmTxArgs{
ChainID: big.NewInt(1),
ChainID: big.NewInt(constants.TestnetEIP155ChainId),
Nonce: 0,
To: &suite.address,
Amount: big.NewInt(1),
Expand All @@ -644,7 +645,7 @@ func (suite *KeeperTestSuite) TestAddLog() {
txHash := msg.AsTransaction().Hash()

ethTx2Params := &types.EvmTxArgs{
ChainID: big.NewInt(1),
ChainID: big.NewInt(constants.TestnetEIP155ChainId),
Nonce: 2,
To: &suite.address,
Amount: big.NewInt(1),
Expand All @@ -656,7 +657,7 @@ func (suite *KeeperTestSuite) TestAddLog() {
msg2.From = addr.Hex()

ethTx3Params := &types.EvmTxArgs{
ChainID: big.NewInt(1),
ChainID: big.NewInt(constants.TestnetEIP155ChainId),
Nonce: 0,
To: &suite.address,
Amount: big.NewInt(1),
Expand All @@ -673,7 +674,7 @@ func (suite *KeeperTestSuite) TestAddLog() {
txHash3 := msg3.AsTransaction().Hash()

ethTx4Params := &types.EvmTxArgs{
ChainID: big.NewInt(1),
ChainID: big.NewInt(constants.TestnetEIP155ChainId),
Nonce: 1,
To: &suite.address,
Amount: big.NewInt(1),
Expand Down
33 changes: 19 additions & 14 deletions x/evm/types/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,23 @@ func newMsgEthereumTx(
}

switch {
case tx.Accesses == nil:
txData = &LegacyTx{
To: toAddr,
Amount: amt,
GasPrice: gp,
Nonce: tx.Nonce,
GasLimit: tx.GasLimit,
Data: tx.Input,
}
case tx.Accesses != nil && tx.GasFeeCap != nil && tx.GasTipCap != nil:
gtc := sdkmath.NewIntFromBigInt(tx.GasTipCap)
gfc := sdkmath.NewIntFromBigInt(tx.GasFeeCap)
case tx.GasTipCap != nil && tx.GasFeeCap != nil:
gasTipCap := sdkmath.NewIntFromBigInt(tx.GasTipCap)
gasFeeCap := sdkmath.NewIntFromBigInt(tx.GasFeeCap)

txData = &DynamicFeeTx{
ChainID: cid,
Amount: amt,
To: toAddr,
GasTipCap: &gtc,
GasFeeCap: &gfc,
GasTipCap: &gasTipCap,
GasFeeCap: &gasFeeCap,
Nonce: tx.Nonce,
GasLimit: tx.GasLimit,
Data: tx.Input,
Accesses: NewAccessList(tx.Accesses),
}

break
case tx.Accesses != nil:
txData = &AccessListTx{
ChainID: cid,
Expand All @@ -110,7 +103,19 @@ func newMsgEthereumTx(
Data: tx.Input,
Accesses: NewAccessList(tx.Accesses),
}

break
default:
txData = &LegacyTx{
To: toAddr,
Amount: amt,
GasPrice: gp,
Nonce: tx.Nonce,
GasLimit: tx.GasLimit,
Data: tx.Input,
}

break
}

dataAny, err := PackTxData(txData)
Expand Down