From 8ae901b9086b9dad85a3c454e1488b7194ee0112 Mon Sep 17 00:00:00 2001 From: jayt106 Date: Mon, 20 Sep 2021 14:28:27 -0400 Subject: [PATCH 1/9] adds more erc20 token benchmark tests --- x/evm/keeper/benchmark_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/x/evm/keeper/benchmark_test.go b/x/evm/keeper/benchmark_test.go index 4ae6bddd51..38fe89e15b 100644 --- a/x/evm/keeper/benchmark_test.go +++ b/x/evm/keeper/benchmark_test.go @@ -77,3 +77,21 @@ func BenchmarkEmitLogs(b *testing.B) { return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 4100000, big.NewInt(1), input, nil) }) } + +func BenchmarkTokenTransferForm(b *testing.B) { + DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx { + input, err := ContractABI.Pack("transferFrom", suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(0)) + require.NoError(b, err) + nonce := suite.app.EvmKeeper.GetNonce(suite.address) + return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), input, nil) + }) +} + +func BenchmarkTokenMint(b *testing.B) { + DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx { + input, err := ContractABI.Pack("mint", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000)) + require.NoError(b, err) + nonce := suite.app.EvmKeeper.GetNonce(suite.address) + return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), input, nil) + }) +} From bdf178142777631a4df54c4379a0e7e43dda9efe Mon Sep 17 00:00:00 2001 From: jayt106 Date: Mon, 20 Sep 2021 15:36:26 -0400 Subject: [PATCH 2/9] add more benchmark for statedb --- x/evm/keeper/statedb_benchmark_test.go | 54 ++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/x/evm/keeper/statedb_benchmark_test.go b/x/evm/keeper/statedb_benchmark_test.go index 10ddf7fb51..baaa27a4cc 100644 --- a/x/evm/keeper/statedb_benchmark_test.go +++ b/x/evm/keeper/statedb_benchmark_test.go @@ -126,3 +126,57 @@ func BenchmarkSnapshot(b *testing.B) { }) } } + +func BenchmarkSubBalance(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + amt := big.NewInt(10) + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + suite.app.EvmKeeper.SubBalance(suite.address, amt) + } +} + +func BenchmarkSetNonce(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + suite.app.EvmKeeper.SetNonce(suite.address, 1) + } +} + +func BenchmarkAddRefund(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + suite.app.EvmKeeper.AddRefund(1) + } +} + +func BenchmarkSuicide(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + b.StopTimer() + addr := tests.GenerateAddress() + suite.app.EvmKeeper.CreateAccount(addr) + b.StartTimer() + + suite.app.EvmKeeper.Suicide(addr) + } +} From 418cd49045a07c4716420f37d28ef2e18fbcf7ea Mon Sep 17 00:00:00 2001 From: jayt106 Date: Mon, 20 Sep 2021 17:26:10 -0400 Subject: [PATCH 3/9] adds benchmark for state_transition --- .../keeper/state_transition_benchmark_test.go | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 x/evm/keeper/state_transition_benchmark_test.go diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go new file mode 100644 index 0000000000..4cc3aa3bf7 --- /dev/null +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -0,0 +1,62 @@ +package keeper_test + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + evmtypes "github.com/tharsis/ethermint/x/evm/types" +) + +func BenchmarkApplyTransaction(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + b.StopTimer() + nonce := suite.app.EvmKeeper.GetNonce(suite.address) + msg := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil, nil) + msg.From = suite.address.Hex() + err := msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer) + require.NoError(b, err) + + b.StartTimer() + _, err = suite.app.EvmKeeper.ApplyTransaction(msg.AsTransaction()) + b.StopTimer() + require.NoError(b, err) + } +} + +func BenchmarkApplyNativeMessage(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + params := suite.app.EvmKeeper.GetParams(suite.ctx) + ethCfg := params.ChainConfig.EthereumConfig(suite.app.EvmKeeper.ChainID()) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + b.StopTimer() + nonce := suite.app.EvmKeeper.GetNonce(suite.address) + msg := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil, nil) + msg.From = suite.address.Hex() + err := msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer) + require.NoError(b, err) + + blockNum := big.NewInt(suite.ctx.BlockHeight()) + signer := ethtypes.MakeSigner(ethCfg, blockNum) + + m, err := msg.AsMessage(signer) + require.NoError(b, err) + + b.StartTimer() + _, err = suite.app.EvmKeeper.ApplyNativeMessage(m) + b.StopTimer() + require.NoError(b, err) + } +} From fde55ecef6bd8c4e57870ce15cf839b99a054f34 Mon Sep 17 00:00:00 2001 From: jayt106 Date: Wed, 22 Sep 2021 14:44:40 -0400 Subject: [PATCH 4/9] fix typo --- x/evm/keeper/benchmark_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/evm/keeper/benchmark_test.go b/x/evm/keeper/benchmark_test.go index 38fe89e15b..66cfeffd3d 100644 --- a/x/evm/keeper/benchmark_test.go +++ b/x/evm/keeper/benchmark_test.go @@ -78,7 +78,7 @@ func BenchmarkEmitLogs(b *testing.B) { }) } -func BenchmarkTokenTransferForm(b *testing.B) { +func BenchmarkTokenTransferFrom(b *testing.B) { DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx { input, err := ContractABI.Pack("transferFrom", suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(0)) require.NoError(b, err) From f9b33aa97c2387ee6f7bc27398c9c6994a1e210f Mon Sep 17 00:00:00 2001 From: jayt106 Date: Wed, 22 Sep 2021 14:46:44 -0400 Subject: [PATCH 5/9] refactor state_transition_benchmark_test --- .../keeper/state_transition_benchmark_test.go | 102 +++++++++++++++--- 1 file changed, 87 insertions(+), 15 deletions(-) diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 4cc3aa3bf7..8fe0054e95 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -4,30 +4,100 @@ import ( "math/big" "testing" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" evmtypes "github.com/tharsis/ethermint/x/evm/types" ) +var templateTx = ðtypes.LegacyTx{ + GasPrice: big.NewInt(1), + Gas: 21000, + To: &common.Address{}, + Value: big.NewInt(0), + Data: []byte{}, +} + +func newSignedEthTx( + txData *ethtypes.LegacyTx, + nonce uint64, + addr sdk.Address, + krSigner keyring.Signer, + ethSigner ethtypes.Signer, +) (*ethtypes.Transaction, error) { + txData.Nonce = nonce + ethTx := ethtypes.NewTx(txData) + + sig, _, err := krSigner.SignByAddress(addr, ethTx.Hash().Bytes()) + if err != nil { + return nil, err + } + + ethTx, err = ethTx.WithSignature(ethSigner, sig) + if err != nil { + return nil, err + } + + return ethTx, nil +} + +func newNativeMessage( + nonce uint64, + blockHeight int64, + address common.Address, + cfg *params.ChainConfig, + krSigner keyring.Signer, + ethSigner ethtypes.Signer, +) (core.Message, error) { + msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight)) + + templateTx.Nonce = nonce + ethTx := ethtypes.NewTx(templateTx) + + msg := &evmtypes.MsgEthereumTx{} + msg.FromEthereumTx(ethTx) + msg.From = address.Hex() + + if err := msg.Sign(ethSigner, krSigner); err != nil { + return nil, err + } + + m, err := msg.AsMessage(msgSigner) + if err != nil { + return nil, err + } + + return m, nil +} + func BenchmarkApplyTransaction(b *testing.B) { suite := KeeperTestSuite{} suite.DoSetupTest(b) + ethSigner := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) + b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { b.StopTimer() - nonce := suite.app.EvmKeeper.GetNonce(suite.address) - msg := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil, nil) - msg.From = suite.address.Hex() - err := msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer) + tx, err := newSignedEthTx(templateTx, + suite.app.EvmKeeper.GetNonce(suite.address), + sdk.AccAddress(suite.address.Bytes()), + suite.signer, + ethSigner, + ) require.NoError(b, err) b.StartTimer() - _, err = suite.app.EvmKeeper.ApplyTransaction(msg.AsTransaction()) + resp, err := suite.app.EvmKeeper.ApplyTransaction(tx) b.StopTimer() + require.NoError(b, err) + require.False(b, resp.Failed()) } } @@ -37,26 +107,28 @@ func BenchmarkApplyNativeMessage(b *testing.B) { params := suite.app.EvmKeeper.GetParams(suite.ctx) ethCfg := params.ChainConfig.EthereumConfig(suite.app.EvmKeeper.ChainID()) + signer := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { b.StopTimer() - nonce := suite.app.EvmKeeper.GetNonce(suite.address) - msg := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil, nil) - msg.From = suite.address.Hex() - err := msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer) - require.NoError(b, err) - blockNum := big.NewInt(suite.ctx.BlockHeight()) - signer := ethtypes.MakeSigner(ethCfg, blockNum) - - m, err := msg.AsMessage(signer) + m, err := newNativeMessage( + suite.app.EvmKeeper.GetNonce(suite.address), + suite.ctx.BlockHeight(), + suite.address, + ethCfg, + suite.signer, + signer, + ) require.NoError(b, err) b.StartTimer() - _, err = suite.app.EvmKeeper.ApplyNativeMessage(m) + resp, err := suite.app.EvmKeeper.ApplyNativeMessage(m) b.StopTimer() + require.NoError(b, err) + require.False(b, resp.Failed()) } } From f088f483726017c9136bb317bbf27e72dece84ea Mon Sep 17 00:00:00 2001 From: jayt106 Date: Thu, 23 Sep 2021 11:42:45 -0400 Subject: [PATCH 6/9] update newSignedEthTx input argument --- x/evm/keeper/state_transition_benchmark_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 8fe0054e95..1ca22621b2 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -23,14 +23,15 @@ var templateTx = ðtypes.LegacyTx{ } func newSignedEthTx( - txData *ethtypes.LegacyTx, + txData ethtypes.TxData, nonce uint64, addr sdk.Address, krSigner keyring.Signer, ethSigner ethtypes.Signer, ) (*ethtypes.Transaction, error) { - txData.Nonce = nonce - ethTx := ethtypes.NewTx(txData) + t := txData.(*ethtypes.LegacyTx) + t.Nonce = nonce + ethTx := ethtypes.NewTx(t) sig, _, err := krSigner.SignByAddress(addr, ethTx.Hash().Bytes()) if err != nil { From e4a2df3301fca8639f8617b22cd6f446c922a913 Mon Sep 17 00:00:00 2001 From: jayt106 Date: Thu, 23 Sep 2021 11:47:03 -0400 Subject: [PATCH 7/9] revises tx template type --- x/evm/keeper/state_transition_benchmark_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 1ca22621b2..3e9fe0b4fd 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -14,7 +14,7 @@ import ( evmtypes "github.com/tharsis/ethermint/x/evm/types" ) -var templateTx = ðtypes.LegacyTx{ +var templateAccessListTx = ðtypes.AccessListTx{ GasPrice: big.NewInt(1), Gas: 21000, To: &common.Address{}, @@ -29,7 +29,7 @@ func newSignedEthTx( krSigner keyring.Signer, ethSigner ethtypes.Signer, ) (*ethtypes.Transaction, error) { - t := txData.(*ethtypes.LegacyTx) + t := txData.(*ethtypes.AccessListTx) t.Nonce = nonce ethTx := ethtypes.NewTx(t) @@ -56,8 +56,8 @@ func newNativeMessage( ) (core.Message, error) { msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight)) - templateTx.Nonce = nonce - ethTx := ethtypes.NewTx(templateTx) + templateAccessListTx.Nonce = nonce + ethTx := ethtypes.NewTx(templateAccessListTx) msg := &evmtypes.MsgEthereumTx{} msg.FromEthereumTx(ethTx) @@ -85,7 +85,7 @@ func BenchmarkApplyTransaction(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { b.StopTimer() - tx, err := newSignedEthTx(templateTx, + tx, err := newSignedEthTx(templateAccessListTx, suite.app.EvmKeeper.GetNonce(suite.address), sdk.AccAddress(suite.address.Bytes()), suite.signer, From 2d2ada10af21c2ec9f4ba0daa30223f5e8111904 Mon Sep 17 00:00:00 2001 From: jayt106 Date: Thu, 23 Sep 2021 11:58:25 -0400 Subject: [PATCH 8/9] modify tests for both LegacyTx and AccessListTx --- .../keeper/state_transition_benchmark_test.go | 95 ++++++++++++++++++- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/x/evm/keeper/state_transition_benchmark_test.go b/x/evm/keeper/state_transition_benchmark_test.go index 3e9fe0b4fd..54ac09c89d 100644 --- a/x/evm/keeper/state_transition_benchmark_test.go +++ b/x/evm/keeper/state_transition_benchmark_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "errors" "math/big" "testing" @@ -22,6 +23,14 @@ var templateAccessListTx = ðtypes.AccessListTx{ Data: []byte{}, } +var templateLegacyTx = ðtypes.LegacyTx{ + GasPrice: big.NewInt(1), + Gas: 21000, + To: &common.Address{}, + Value: big.NewInt(0), + Data: []byte{}, +} + func newSignedEthTx( txData ethtypes.TxData, nonce uint64, @@ -29,9 +38,17 @@ func newSignedEthTx( krSigner keyring.Signer, ethSigner ethtypes.Signer, ) (*ethtypes.Transaction, error) { - t := txData.(*ethtypes.AccessListTx) - t.Nonce = nonce - ethTx := ethtypes.NewTx(t) + var ethTx *ethtypes.Transaction + switch txData := txData.(type) { + case *ethtypes.AccessListTx: + txData.Nonce = nonce + ethTx = ethtypes.NewTx(txData) + case *ethtypes.LegacyTx: + txData.Nonce = nonce + ethTx = ethtypes.NewTx(txData) + default: + return nil, errors.New("unknown transaction type!") + } sig, _, err := krSigner.SignByAddress(addr, ethTx.Hash().Bytes()) if err != nil { @@ -53,11 +70,18 @@ func newNativeMessage( cfg *params.ChainConfig, krSigner keyring.Signer, ethSigner ethtypes.Signer, + isLegacy bool, ) (core.Message, error) { msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight)) - templateAccessListTx.Nonce = nonce - ethTx := ethtypes.NewTx(templateAccessListTx) + var ethTx *ethtypes.Transaction + if isLegacy { + templateLegacyTx.Nonce = nonce + ethTx = ethtypes.NewTx(templateLegacyTx) + } else { + templateAccessListTx.Nonce = nonce + ethTx = ethtypes.NewTx(templateAccessListTx) + } msg := &evmtypes.MsgEthereumTx{} msg.FromEthereumTx(ethTx) @@ -102,6 +126,33 @@ func BenchmarkApplyTransaction(b *testing.B) { } } +func BenchmarkApplyTransactionWithLegacyTx(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + ethSigner := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + b.StopTimer() + tx, err := newSignedEthTx(templateLegacyTx, + suite.app.EvmKeeper.GetNonce(suite.address), + sdk.AccAddress(suite.address.Bytes()), + suite.signer, + ethSigner, + ) + require.NoError(b, err) + + b.StartTimer() + resp, err := suite.app.EvmKeeper.ApplyTransaction(tx) + b.StopTimer() + + require.NoError(b, err) + require.False(b, resp.Failed()) + } +} + func BenchmarkApplyNativeMessage(b *testing.B) { suite := KeeperTestSuite{} suite.DoSetupTest(b) @@ -122,6 +173,40 @@ func BenchmarkApplyNativeMessage(b *testing.B) { ethCfg, suite.signer, signer, + false, + ) + require.NoError(b, err) + + b.StartTimer() + resp, err := suite.app.EvmKeeper.ApplyNativeMessage(m) + b.StopTimer() + + require.NoError(b, err) + require.False(b, resp.Failed()) + } +} + +func BenchmarkApplyNativeMessageWithLegacyTx(b *testing.B) { + suite := KeeperTestSuite{} + suite.DoSetupTest(b) + + params := suite.app.EvmKeeper.GetParams(suite.ctx) + ethCfg := params.ChainConfig.EthereumConfig(suite.app.EvmKeeper.ChainID()) + signer := ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + b.StopTimer() + + m, err := newNativeMessage( + suite.app.EvmKeeper.GetNonce(suite.address), + suite.ctx.BlockHeight(), + suite.address, + ethCfg, + suite.signer, + signer, + true, ) require.NoError(b, err) From a05f1add9f215f798808e72f9ab48317532acdee Mon Sep 17 00:00:00 2001 From: jayt106 Date: Thu, 23 Sep 2021 15:40:41 -0400 Subject: [PATCH 9/9] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb90a9ec3b..3c4ed353ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (evm) [tharsis#461](https://github.com/tharsis/ethermint/pull/461) Increase performance of `StateDB` transaction log storage (r/w). * (evm) [tharsis#566](https://github.com/tharsis/ethermint/pull/566) Introduce `stateErr` store in `StateDB` to avoid meaningless operations if any error happened before +* (evm) [tharsis#586](https://github.com/tharsis/ethermint/pull/586) Benchmark evm keeper ## [v0.5.0] - 2021-08-20