|
| 1 | +package app |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "math/big" |
| 6 | + "testing" |
| 7 | + |
| 8 | + sdkmath "cosmossdk.io/math" |
| 9 | + "github.com/cosmos/cosmos-sdk/testutil/mock" |
| 10 | + sdk "github.com/cosmos/cosmos-sdk/types" |
| 11 | + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" |
| 12 | + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" |
| 13 | + "github.com/crypto-org-chain/cronos/v2/x/cronos/types" |
| 14 | + "github.com/ethereum/go-ethereum/common" |
| 15 | + ethtypes "github.com/ethereum/go-ethereum/core/types" |
| 16 | + "github.com/ethereum/go-ethereum/crypto" |
| 17 | + "github.com/evmos/ethermint/crypto/ethsecp256k1" |
| 18 | + "github.com/evmos/ethermint/tests" |
| 19 | + evmtypes "github.com/evmos/ethermint/x/evm/types" |
| 20 | + "github.com/stretchr/testify/require" |
| 21 | + abci "github.com/tendermint/tendermint/abci/types" |
| 22 | + "github.com/tendermint/tendermint/libs/log" |
| 23 | + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" |
| 24 | + tmtypes "github.com/tendermint/tendermint/types" |
| 25 | + dbm "github.com/tendermint/tm-db" |
| 26 | +) |
| 27 | + |
| 28 | +// BenchmarkERC20Transfer benchmarks execution of standard erc20 token transfer transactions |
| 29 | +func BenchmarkERC20Transfer(b *testing.B) { |
| 30 | + txsPerBlock := 100 |
| 31 | + gasPrice := big.NewInt(100000000000) |
| 32 | + |
| 33 | + encodingConfig := MakeEncodingConfig() |
| 34 | + db := dbm.NewMemDB() |
| 35 | + app := New(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encodingConfig, EmptyAppOptions{}) |
| 36 | + |
| 37 | + priv, err := ethsecp256k1.GenerateKey() |
| 38 | + address := common.BytesToAddress(priv.PubKey().Address().Bytes()) |
| 39 | + signer := tests.NewSigner(priv) |
| 40 | + chainID := big.NewInt(777) |
| 41 | + ethSigner := ethtypes.LatestSignerForChainID(chainID) |
| 42 | + |
| 43 | + signTx := func(msg *evmtypes.MsgEthereumTx) ([]byte, error) { |
| 44 | + msg.From = address.String() |
| 45 | + if err := msg.Sign(ethSigner, signer); err != nil { |
| 46 | + return nil, err |
| 47 | + } |
| 48 | + require.NoError(b, err) |
| 49 | + tx, err := msg.BuildTx(encodingConfig.TxConfig.NewTxBuilder(), evmtypes.DefaultEVMDenom) |
| 50 | + if err != nil { |
| 51 | + return nil, err |
| 52 | + } |
| 53 | + return encodingConfig.TxConfig.TxEncoder()(tx) |
| 54 | + } |
| 55 | + |
| 56 | + ctor, err := types.ModuleCRC21Contract.ABI.Pack("", "test", uint8(0), false) |
| 57 | + require.NoError(b, err) |
| 58 | + deployTxBz, err := signTx(evmtypes.NewTxContract(chainID, 0, big.NewInt(0), 2100000, gasPrice, nil, nil, ctor, nil)) |
| 59 | + require.NoError(b, err) |
| 60 | + |
| 61 | + privVal := mock.NewPV() |
| 62 | + pubKey, err := privVal.GetPubKey() |
| 63 | + consAddress := sdk.ConsAddress(pubKey.Address()) |
| 64 | + require.NoError(b, err) |
| 65 | + validator := tmtypes.NewValidator(pubKey, 1) |
| 66 | + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) |
| 67 | + acc := authtypes.NewBaseAccount(priv.PubKey().Address().Bytes(), priv.PubKey(), 0, 0) |
| 68 | + balance := banktypes.Balance{ |
| 69 | + Address: acc.GetAddress().String(), |
| 70 | + Coins: sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewIntWithDecimal(10000000, 18))), |
| 71 | + } |
| 72 | + genesisState := NewDefaultGenesisState(encodingConfig.Codec) |
| 73 | + genesisState = genesisStateWithValSet(b, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) |
| 74 | + |
| 75 | + appState, err := json.MarshalIndent(genesisState, "", " ") |
| 76 | + require.NoError(b, err) |
| 77 | + app.InitChain(abci.RequestInitChain{ |
| 78 | + ChainId: SimAppChainID, |
| 79 | + AppStateBytes: appState, |
| 80 | + ConsensusParams: DefaultConsensusParams, |
| 81 | + }) |
| 82 | + app.BeginBlock(abci.RequestBeginBlock{ |
| 83 | + Header: tmproto.Header{ |
| 84 | + Height: 1, |
| 85 | + ChainID: SimAppChainID, |
| 86 | + ProposerAddress: consAddress, |
| 87 | + }, |
| 88 | + }) |
| 89 | + res := app.DeliverTx(abci.RequestDeliverTx{ |
| 90 | + Tx: deployTxBz, |
| 91 | + }) |
| 92 | + require.Equal(b, 0, int(res.Code)) |
| 93 | + app.EndBlock(abci.RequestEndBlock{}) |
| 94 | + app.Commit() |
| 95 | + |
| 96 | + // prepare transactions |
| 97 | + contractAddr := crypto.CreateAddress(address, 1) |
| 98 | + var transferTxs [][]byte |
| 99 | + for i := 0; i < b.N; i++ { |
| 100 | + for j := 0; j < txsPerBlock; j++ { |
| 101 | + idx := int64(i*txsPerBlock + j) |
| 102 | + recipient := common.BigToAddress(big.NewInt(idx)) |
| 103 | + data, err := types.ModuleCRC21Contract.ABI.Pack("transfer", recipient, big.NewInt(1)) |
| 104 | + bz, err := signTx(evmtypes.NewTx(chainID, uint64(idx)+1, &contractAddr, big.NewInt(0), 210000, gasPrice, nil, nil, data, nil)) |
| 105 | + require.NoError(b, err) |
| 106 | + transferTxs = append(transferTxs, bz) |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + /* |
| 111 | + { |
| 112 | + fp, err := os.Create("cpu.profile") |
| 113 | + require.NoError(b, err) |
| 114 | + defer fp.Close() |
| 115 | + require.NoError(b, pprof.StartCPUProfile(fp)) |
| 116 | + defer pprof.StopCPUProfile() |
| 117 | + } |
| 118 | + */ |
| 119 | + |
| 120 | + b.ResetTimer() |
| 121 | + for i := 0; i < b.N; i++ { |
| 122 | + app.BeginBlock(abci.RequestBeginBlock{ |
| 123 | + Header: tmproto.Header{ |
| 124 | + Height: int64(i) + 2, |
| 125 | + ChainID: SimAppChainID, |
| 126 | + ProposerAddress: consAddress, |
| 127 | + }, |
| 128 | + }) |
| 129 | + for j := 0; j < txsPerBlock; j++ { |
| 130 | + idx := i*txsPerBlock + j |
| 131 | + res := app.DeliverTx(abci.RequestDeliverTx{ |
| 132 | + Tx: transferTxs[idx], |
| 133 | + }) |
| 134 | + require.Equal(b, 0, int(res.Code)) |
| 135 | + } |
| 136 | + app.EndBlock(abci.RequestEndBlock{}) |
| 137 | + app.Commit() |
| 138 | + } |
| 139 | +} |
0 commit comments