laconicd/x/evm/keeper/keeper_test.go
yihuang f6dc80d949
evm: estimate gas unit tests (#324)
* add some unit tests for estimateGas

Also add some test environment setup, Closes #323

test estimateGas of erc20 token transfer

fix failed test case

the trick is to keep a clean transient store, by doing a commit

put artifacts to external file

* fix test failure

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
2021-07-23 14:24:36 +00:00

152 lines
5.0 KiB
Go

package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/tharsis/ethermint/app"
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
"github.com/tharsis/ethermint/encoding"
"github.com/tharsis/ethermint/tests"
ethermint "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm/types"
"github.com/ethereum/go-ethereum/common"
ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
var testTokens = sdk.NewIntWithDecimal(1000, 18)
type KeeperTestSuite struct {
suite.Suite
ctx sdk.Context
app *app.EthermintApp
queryClient types.QueryClient
address ethcmn.Address
consAddress sdk.ConsAddress
// for generate test tx
clientCtx client.Context
ethSigner ethtypes.Signer
appCodec codec.Codec
signer keyring.Signer
}
func (suite *KeeperTestSuite) SetupTest() {
checkTx := false
// account key
priv, err := ethsecp256k1.GenerateKey()
suite.Require().NoError(err)
suite.address = ethcmn.BytesToAddress(priv.PubKey().Address().Bytes())
suite.signer = tests.NewSigner(priv)
// consensus key
priv, err = ethsecp256k1.GenerateKey()
suite.Require().NoError(err)
suite.consAddress = sdk.ConsAddress(priv.PubKey().Address())
suite.app = app.Setup(checkTx)
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{
Height: 1,
ChainID: "ethermint-1",
Time: time.Now().UTC(),
ProposerAddress: suite.consAddress.Bytes(),
})
suite.app.EvmKeeper.WithContext(suite.ctx)
queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.app.EvmKeeper)
suite.queryClient = types.NewQueryClient(queryHelper)
acc := &ethermint.EthAccount{
BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(suite.address.Bytes()), nil, 0, 0),
CodeHash: common.BytesToHash(ethcrypto.Keccak256(nil)).String(),
}
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
valAddr := sdk.ValAddress(suite.address.Bytes())
validator, err := stakingtypes.NewValidator(valAddr, priv.PubKey(), stakingtypes.Description{})
err = suite.app.StakingKeeper.SetValidatorByConsAddr(suite.ctx, validator)
suite.Require().NoError(err)
err = suite.app.StakingKeeper.SetValidatorByConsAddr(suite.ctx, validator)
suite.Require().NoError(err)
suite.app.StakingKeeper.SetValidator(suite.ctx, validator)
encodingConfig := encoding.MakeConfig(app.ModuleBasics)
suite.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig)
suite.ethSigner = ethtypes.LatestSignerForChainID(suite.app.EvmKeeper.ChainID())
suite.appCodec = encodingConfig.Marshaler
// mint some tokens to coinbase address
_, bankKeeper := suite.initKeepersWithmAccPerms()
ctx := sdk.WrapSDKContext(suite.ctx)
rsp, err := suite.queryClient.Params(ctx, &types.QueryParamsRequest{})
suite.Require().NoError(err)
initCoin := sdk.NewCoins(sdk.NewCoin(rsp.Params.EvmDenom, testTokens))
err = simapp.FundAccount(bankKeeper, suite.ctx, acc.GetAddress(), initCoin)
suite.Require().NoError(err)
}
// Commit and begin new block
func (suite *KeeperTestSuite) Commit() {
suite.app.Commit()
header := suite.ctx.BlockHeader()
header.Height += 1
suite.app.BeginBlock(abci.RequestBeginBlock{
Header: header,
})
// update ctx
suite.ctx = suite.app.BaseApp.NewContext(false, header)
suite.app.EvmKeeper.WithContext(suite.ctx)
queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.app.EvmKeeper)
suite.queryClient = types.NewQueryClient(queryHelper)
}
// initKeepersWithmAccPerms construct a bank keeper that can mint tokens out of thin air
func (suite *KeeperTestSuite) initKeepersWithmAccPerms() (authkeeper.AccountKeeper, bankkeeper.BaseKeeper) {
maccPerms := app.GetMaccPerms()
maccPerms[authtypes.Burner] = []string{authtypes.Burner}
maccPerms[authtypes.Minter] = []string{authtypes.Minter}
authKeeper := authkeeper.NewAccountKeeper(
suite.appCodec, suite.app.GetKey(types.StoreKey), suite.app.GetSubspace(types.ModuleName),
authtypes.ProtoBaseAccount, maccPerms,
)
keeper := bankkeeper.NewBaseKeeper(
suite.appCodec, suite.app.GetKey(types.StoreKey), authKeeper,
suite.app.GetSubspace(types.ModuleName), map[string]bool{},
)
return authKeeper, keeper
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}