tests: add message call benchmark (#717)
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
e04422b6ff
commit
7c7f3f02bb
@ -4,3 +4,7 @@
|
|||||||
solc --combined-json bin,abi --allow-paths . ./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol \
|
solc --combined-json bin,abi --allow-paths . ./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol \
|
||||||
| jq ".contracts.\"./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol:StandardTokenMock\"" \
|
| jq ".contracts.\"./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol:StandardTokenMock\"" \
|
||||||
> x/evm/types/ERC20Contract.json
|
> x/evm/types/ERC20Contract.json
|
||||||
|
|
||||||
|
solc --combined-json bin,abi --allow-paths . ./tests/solidity/suites/basic/contracts/TestMessageCall.sol \
|
||||||
|
| jq ".contracts.\"./tests/solidity/suites/basic/contracts/TestMessageCall.sol:TestMessageCall\"" \
|
||||||
|
> x/evm/types/TestMessageCall.json
|
||||||
|
25
tests/solidity/suites/basic/contracts/TestMessageCall.sol
Normal file
25
tests/solidity/suites/basic/contracts/TestMessageCall.sol
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
pragma solidity 0.5.17;
|
||||||
|
|
||||||
|
contract Inner {
|
||||||
|
event TestEvent(uint256);
|
||||||
|
function test() public returns (uint256) {
|
||||||
|
emit TestEvent(42);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract TestMessageCall {
|
||||||
|
Inner _inner;
|
||||||
|
constructor() public {
|
||||||
|
_inner = new Inner();
|
||||||
|
}
|
||||||
|
|
||||||
|
// benchmarks
|
||||||
|
function benchmarkMessageCall(uint iterations) public returns (uint256) {
|
||||||
|
uint256 n = 0;
|
||||||
|
for (uint i=0; i < iterations; i++) {
|
||||||
|
n += _inner.test();
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,22 @@ func SetupContract(b *testing.B) (*KeeperTestSuite, common.Address) {
|
|||||||
return &suite, contractAddr
|
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
|
type TxBuilder func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx
|
||||||
|
|
||||||
func DoBenchmark(b *testing.B, txBuilder TxBuilder) {
|
func DoBenchmark(b *testing.B, txBuilder TxBuilder) {
|
||||||
@ -97,6 +113,37 @@ func BenchmarkTokenMint(b *testing.B) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.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 = authante.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 DoBenchmarkDeepContextStack(b *testing.B, depth int) {
|
func DoBenchmarkDeepContextStack(b *testing.B, depth int) {
|
||||||
begin := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
begin := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
end := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
end := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||||
|
@ -311,6 +311,61 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd
|
|||||||
return ercTransferTx
|
return ercTransferTx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeployTestMessageCall deploy a test erc20 contract and returns the contract address
|
||||||
|
func (suite *KeeperTestSuite) DeployTestMessageCall(t require.TestingT) common.Address {
|
||||||
|
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||||
|
chainID := suite.app.EvmKeeper.ChainID()
|
||||||
|
|
||||||
|
data := types.TestMessageCall.Bin
|
||||||
|
args, err := json.Marshal(&types.TransactionArgs{
|
||||||
|
From: &suite.address,
|
||||||
|
Data: (*hexutil.Bytes)(&data),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
res, err := suite.queryClient.EstimateGas(ctx, &types.EthCallRequest{
|
||||||
|
Args: args,
|
||||||
|
GasCap: uint64(config.DefaultGasCap),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||||
|
|
||||||
|
var erc20DeployTx *types.MsgEthereumTx
|
||||||
|
if suite.dynamicTxFee {
|
||||||
|
erc20DeployTx = types.NewTxContract(
|
||||||
|
chainID,
|
||||||
|
nonce,
|
||||||
|
nil, // amount
|
||||||
|
res.Gas, // gasLimit
|
||||||
|
nil, // gasPrice
|
||||||
|
suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx),
|
||||||
|
big.NewInt(1),
|
||||||
|
data, // input
|
||||||
|
ðtypes.AccessList{}, // accesses
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
erc20DeployTx = types.NewTxContract(
|
||||||
|
chainID,
|
||||||
|
nonce,
|
||||||
|
nil, // amount
|
||||||
|
res.Gas, // gasLimit
|
||||||
|
nil, // gasPrice
|
||||||
|
nil, nil,
|
||||||
|
data, // input
|
||||||
|
nil, // accesses
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
erc20DeployTx.From = suite.address.Hex()
|
||||||
|
err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), suite.signer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
rsp, err := suite.app.EvmKeeper.EthereumTx(ctx, erc20DeployTx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Empty(t, rsp.VmError)
|
||||||
|
return crypto.CreateAddress(suite.address, nonce)
|
||||||
|
}
|
||||||
|
|
||||||
func TestKeeperTestSuite(t *testing.T) {
|
func TestKeeperTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(KeeperTestSuite))
|
suite.Run(t, new(KeeperTestSuite))
|
||||||
}
|
}
|
||||||
|
4
x/evm/types/TestMessageCall.json
Normal file
4
x/evm/types/TestMessageCall.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"abi": "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"iterations\",\"type\":\"uint256\"}],\"name\":\"benchmarkMessageCall\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
||||||
|
"bin": "608060405234801561001057600080fd5b5060405161001d9061007e565b604051809103906000f080158015610039573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061008a565b60dd8061021483390190565b61017b806100996000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806376e489f014610030575b600080fd5b61005c6004803603602081101561004657600080fd5b8101908080359060200190929190505050610072565b6040518082815260200191505060405180910390f35b6000806000905060008090505b8381101561013c576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8a8fd6d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156100f057600080fd5b505af1158015610104573d6000803e3d6000fd5b505050506040513d602081101561011a57600080fd5b810190808051906020019092919050505082019150808060010191505061007f565b508091505091905056fea265627a7a723158203bb5ea1d2b128eb07e834f8b4cab93aab73270ef20cb80c1d5e0e2ee4f10b7c264736f6c634300051100326080604052348015600f57600080fd5b5060bf8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063f8a8fd6d14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b60007f1440c4dd67b4344ea1905ec0318995133b550f168b4ee959a0da6b503d7d2414602a6040518082815260200191505060405180910390a1602a90509056fea265627a7a723158209236549244199cceaef9525385c8b6fccaf6390440ece080e2046d9f4a0035f564736f6c63430005110032"
|
||||||
|
}
|
@ -74,6 +74,12 @@ var (
|
|||||||
|
|
||||||
// ERC20Contract is the compiled test erc20 contract
|
// ERC20Contract is the compiled test erc20 contract
|
||||||
ERC20Contract CompiledContract
|
ERC20Contract CompiledContract
|
||||||
|
|
||||||
|
//go:embed TestMessageCall.json
|
||||||
|
testMessageCallJSON []byte
|
||||||
|
|
||||||
|
// TestMessageCall is the compiled message call benchmark contract
|
||||||
|
TestMessageCall CompiledContract
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -85,4 +91,13 @@ func init() {
|
|||||||
if len(ERC20Contract.Bin) == 0 {
|
if len(ERC20Contract.Bin) == 0 {
|
||||||
panic("load contract failed")
|
panic("load contract failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(testMessageCallJSON, &TestMessageCall)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(TestMessageCall.Bin) == 0 {
|
||||||
|
panic("load contract failed")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user