package keeper_test import ( _ "embed" "math/big" "testing" "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/stretchr/testify/require" "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" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cerc-io/laconicd/app" "github.com/cerc-io/laconicd/crypto/ethsecp256k1" "github.com/cerc-io/laconicd/encoding" "github.com/cerc-io/laconicd/tests" laconicd "github.com/cerc-io/laconicd/types" evmtypes "github.com/cerc-io/laconicd/x/evm/types" "github.com/cerc-io/laconicd/x/feemarket/types" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/tmhash" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmversion "github.com/tendermint/tendermint/proto/tendermint/version" "github.com/tendermint/tendermint/version" ) type KeeperTestSuite struct { suite.Suite ctx sdk.Context app *app.LaconicApp queryClient types.QueryClient address common.Address consAddress sdk.ConsAddress // for generate test tx clientCtx client.Context ethSigner ethtypes.Signer appCodec codec.Codec signer keyring.Signer denom string } var s *KeeperTestSuite func TestKeeperTestSuite(t *testing.T) { s = new(KeeperTestSuite) suite.Run(t, s) // Run Ginkgo integration tests RegisterFailHandler(Fail) RunSpecs(t, "Keeper Suite") } // SetupTest setup test environment, it uses`require.TestingT` to support both `testing.T` and `testing.B`. func (suite *KeeperTestSuite) SetupTest() { checkTx := false suite.app = app.Setup(checkTx, nil) suite.SetupApp(checkTx) } func (suite *KeeperTestSuite) SetupApp(checkTx bool) { t := suite.T() // account key priv, err := ethsecp256k1.GenerateKey() require.NoError(t, err) suite.address = common.BytesToAddress(priv.PubKey().Address().Bytes()) suite.signer = tests.NewSigner(priv) // consensus key priv, err = ethsecp256k1.GenerateKey() require.NoError(t, err) suite.consAddress = sdk.ConsAddress(priv.PubKey().Address()) suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{ Height: 1, ChainID: "laconic_9000-1", Time: time.Now().UTC(), ProposerAddress: suite.consAddress.Bytes(), Version: tmversion.Consensus{ Block: version.BlockProtocol, }, LastBlockId: tmproto.BlockID{ Hash: tmhash.Sum([]byte("block_id")), PartSetHeader: tmproto.PartSetHeader{ Total: 11, Hash: tmhash.Sum([]byte("partset_header")), }, }, AppHash: tmhash.Sum([]byte("app")), DataHash: tmhash.Sum([]byte("data")), EvidenceHash: tmhash.Sum([]byte("evidence")), ValidatorsHash: tmhash.Sum([]byte("validators")), NextValidatorsHash: tmhash.Sum([]byte("next_validators")), ConsensusHash: tmhash.Sum([]byte("consensus")), LastResultsHash: tmhash.Sum([]byte("last_result")), }) queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) types.RegisterQueryServer(queryHelper, suite.app.FeeMarketKeeper) suite.queryClient = types.NewQueryClient(queryHelper) acc := &laconicd.EthAccount{ BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(suite.address.Bytes()), nil, 0, 0), CodeHash: common.BytesToHash(crypto.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{}) require.NoError(t, err) validator = stakingkeeper.TestingUpdateValidator(suite.app.StakingKeeper, suite.ctx, validator, true) err = suite.app.StakingKeeper.AfterValidatorCreated(suite.ctx, validator.GetOperator()) require.NoError(t, err) err = suite.app.StakingKeeper.SetValidatorByConsAddr(suite.ctx, validator) require.NoError(t, 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.Codec suite.denom = evmtypes.DefaultEVMDenom } // Commit commits and starts a new block with an updated context. func (suite *KeeperTestSuite) Commit() { suite.CommitAfter(time.Second * 0) } // Commit commits a block at a given time. func (suite *KeeperTestSuite) CommitAfter(t time.Duration) { header := suite.ctx.BlockHeader() suite.app.EndBlock(abci.RequestEndBlock{Height: header.Height}) _ = suite.app.Commit() header.Height += 1 header.Time = header.Time.Add(t) suite.app.BeginBlock(abci.RequestBeginBlock{ Header: header, }) // update ctx suite.ctx = suite.app.BaseApp.NewContext(false, header) queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) types.RegisterQueryServer(queryHelper, suite.app.FeeMarketKeeper) suite.queryClient = types.NewQueryClient(queryHelper) } func (suite *KeeperTestSuite) TestSetGetBlockGasWanted() { testCases := []struct { name string malleate func() expGas uint64 }{ { "with last block given", func() { suite.app.FeeMarketKeeper.SetBlockGasWanted(suite.ctx, uint64(1000000)) }, uint64(1000000), }, } for _, tc := range testCases { tc.malleate() gas := suite.app.FeeMarketKeeper.GetBlockGasWanted(suite.ctx) suite.Require().Equal(tc.expGas, gas, tc.name) } } func (suite *KeeperTestSuite) TestSetGetGasFee() { testCases := []struct { name string malleate func() expFee *big.Int }{ { "with last block given", func() { suite.app.FeeMarketKeeper.SetBaseFee(suite.ctx, sdk.OneDec().BigInt()) }, sdk.OneDec().BigInt(), }, } for _, tc := range testCases { tc.malleate() fee := suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx) suite.Require().Equal(tc.expFee, fee, tc.name) } }