laconicd/x/evm/keeper/benchmark_test.go
2022-06-07 08:56:26 -05:00

146 lines
5.4 KiB
Go

package keeper_test
import (
"math/big"
"testing"
"cosmossdk.io/math"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
ante "github.com/cosmos/cosmos-sdk/x/auth/ante"
ethtypes "github.com/ethereum/go-ethereum/core/types"
ethermint "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm/types"
)
func SetupContract(b *testing.B) (*KeeperTestSuite, common.Address) {
suite := KeeperTestSuite{}
suite.DoSetupTest(b)
amt := sdk.Coins{ethermint.NewPhotonCoinInt64(1000000000000000000)}
err := suite.app.BankKeeper.MintCoins(suite.ctx, types.ModuleName, amt)
require.NoError(b, err)
err = suite.app.BankKeeper.SendCoinsFromModuleToAccount(suite.ctx, types.ModuleName, suite.address.Bytes(), amt)
require.NoError(b, err)
contractAddr := suite.DeployTestContract(b, suite.address, math.NewIntWithDecimal(1000, 18).BigInt())
suite.Commit()
return &suite, contractAddr
}
func SetupTestMessageCall(b *testing.B) (*KeeperTestSuite, common.Address) {
suite := KeeperTestSuite{}
suite.DoSetupTest(b)
amt := sdk.Coins{ethermint.NewPhotonCoinInt64(1000000000000000000)}
err := suite.app.BankKeeper.MintCoins(suite.ctx, types.ModuleName, amt)
require.NoError(b, err)
err = suite.app.BankKeeper.SendCoinsFromModuleToAccount(suite.ctx, types.ModuleName, suite.address.Bytes(), amt)
require.NoError(b, err)
contractAddr := suite.DeployTestMessageCall(b)
suite.Commit()
return &suite, contractAddr
}
type TxBuilder func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx
func DoBenchmark(b *testing.B, txBuilder TxBuilder) {
suite, contractAddr := SetupContract(b)
msg := txBuilder(suite, contractAddr)
msg.From = suite.address.Hex()
err := msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer)
require.NoError(b, err)
b.ResetTimer()
b.StartTimer()
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(), sdk.NewIntFromBigInt(txData.Fee()))}
err = ante.DeductFees(suite.app.BankKeeper, suite.ctx, suite.app.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees)
require.NoError(b, err)
rsp, err := suite.app.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg)
require.NoError(b, err)
require.False(b, rsp.Failed())
}
}
func BenchmarkTokenTransfer(b *testing.B) {
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
input, err := types.ERC20Contract.ABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
require.NoError(b, err)
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address)
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
})
}
func BenchmarkEmitLogs(b *testing.B) {
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
input, err := types.ERC20Contract.ABI.Pack("benchmarkLogs", big.NewInt(1000))
require.NoError(b, err)
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address)
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 4100000, big.NewInt(1), nil, nil, input, nil)
})
}
func BenchmarkTokenTransferFrom(b *testing.B) {
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
input, err := types.ERC20Contract.ABI.Pack("transferFrom", suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(0))
require.NoError(b, err)
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address)
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
})
}
func BenchmarkTokenMint(b *testing.B) {
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
input, err := types.ERC20Contract.ABI.Pack("mint", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
require.NoError(b, err)
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address)
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
})
}
func BenchmarkMessageCall(b *testing.B) {
suite, contract := SetupTestMessageCall(b)
input, err := types.TestMessageCall.ABI.Pack("benchmarkMessageCall", big.NewInt(10000))
require.NoError(b, err)
nonce := suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address)
msg := types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 25000000, big.NewInt(1), nil, nil, input, nil)
msg.From = suite.address.Hex()
err = msg.Sign(ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID()), suite.signer)
require.NoError(b, err)
b.ResetTimer()
b.StartTimer()
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(), sdk.NewIntFromBigInt(txData.Fee()))}
err = ante.DeductFees(suite.app.BankKeeper, suite.ctx, suite.app.AccountKeeper.GetAccount(ctx, msg.GetFrom()), fees)
require.NoError(b, err)
rsp, err := suite.app.EvmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg)
require.NoError(b, err)
require.False(b, rsp.Failed())
}
}