Skip to content

Commit

Permalink
chore(tests): migrate vesting module tests (#2408)
Browse files Browse the repository at this point in the history
* refactor unit tests

* run make format

* start refactor on int_tests

* wip - integration tests

* fix some test cases

* fix some test cases

* fix some tests and fix setup

* fix some tests

* run make format

* remove unnecessary code

* migrate some tests

* fix vesting tests

* fix BroadcastTxSync finalize block req

* fix vesting integration tests

* update comment

* Update x/vesting/keeper/integration_test.go

Co-authored-by: Ramiro Carlucho <ramirocarlucho@gmail.com>
Signed-off-by: Tom <54514587+GAtom22@users.noreply.github.com>

* address review comments

---------

Signed-off-by: Tom <54514587+GAtom22@users.noreply.github.com>
Co-authored-by: GAtom22 <GAtom22@users.noreply.github.com>
Co-authored-by: Ramiro Carlucho <ramirocarlucho@gmail.com>
  • Loading branch information
3 people committed May 10, 2024
1 parent d7d283a commit 5f11136
Show file tree
Hide file tree
Showing 30 changed files with 1,913 additions and 1,588 deletions.
2 changes: 1 addition & 1 deletion app/ante/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ var _ = Describe("when sending a Cosmos transaction", Label("AnteHandler"), Orde

// delegate some tokens and make sure the remaining balance is not sufficient to cover the tx fees
valAddr := s.network.GetValidators()[1].OperatorAddress
err = s.factory.Delegate(priv, valAddr, sdk.NewCoin(s.network.GetDenom(), sdkmath.NewInt(9999e14)))
err = s.factory.Delegate(priv, valAddr, sdk.NewCoin(s.network.GetDenom(), sdkmath.NewInt(9888e14)))
Expect(err).To(BeNil())

_, err = integrationutils.WaitToAccrueRewards(s.network, s.grpcHandler, addr.String(), minExpRewards)
Expand Down
1 change: 1 addition & 0 deletions client/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ func initGenFiles(
clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState)

govGenState.Params.MinDeposit[0].Denom = coinDenom
govGenState.Params.ExpeditedMinDeposit[0].Denom = coinDenom
appGenState[govtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&govGenState)

var mintGenState mintypes.GenesisState
Expand Down
3 changes: 3 additions & 0 deletions cmd/evmosd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"

"github.com/evmos/evmos/v18/utils"
)

type printInfo struct {
Expand Down Expand Up @@ -175,6 +177,7 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
cmd.Flags().BoolP(genutilcli.FlagOverwrite, "o", false, "overwrite the genesis.json file")
cmd.Flags().Bool(genutilcli.FlagRecover, false, "provide seed phrase to recover existing key instead of creating")
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(genutilcli.FlagDefaultBondDenom, utils.BaseDenom, "defines the default denom to use in genesis file")

return cmd
}
1 change: 1 addition & 0 deletions cmd/evmosd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ func initGenFiles(
clientCtx.Codec.MustUnmarshalJSON(appGenState[govtypes.ModuleName], &govGenState)

govGenState.Params.MinDeposit[0].Denom = coinDenom
govGenState.Params.ExpeditedMinDeposit[0].Denom = coinDenom
appGenState[govtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&govGenState)

var evmGenState evmtypes.GenesisState
Expand Down
8 changes: 0 additions & 8 deletions local_node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,6 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then
# Set moniker and chain-id for Evmos (Moniker can be anything, chain-id must be an integer)
evmosd init $MONIKER -o --chain-id "$CHAINID" --home "$HOMEDIR"

# Change parameter token denominations to aevmos
jq '.app_state["staking"]["params"]["bond_denom"]="aevmos"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aevmos"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
# When upgrade to cosmos-sdk v0.47, use gov.params to edit the deposit params
jq '.app_state["gov"]["params"]["min_deposit"][0]["denom"]="aevmos"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["evm"]["params"]["evm_denom"]="aevmos"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
jq '.app_state["inflation"]["params"]["mint_denom"]="aevmos"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"

# Set gas limit in genesis
jq '.consensus_params["block"]["max_gas"]="10000000"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"

Expand Down
29 changes: 29 additions & 0 deletions testutil/integration/common/factory/base.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package factory

import (
"fmt"

errorsmod "cosmossdk.io/errors"
abcitypes "github.com/cometbft/cometbft/abci/types"
"github.com/cosmos/cosmos-sdk/client"
Expand All @@ -24,6 +26,9 @@ type BaseTxFactory interface {
ExecuteCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error)
// EncodeTx encodes the provided transaction
EncodeTx(tx sdktypes.Tx) ([]byte, error)
// CommitCosmosTx creates, signs and commits a cosmos tx
// (produces a block with the specified transaction)
CommitCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error)
}

// baseTxFactory is the struct of the basic tx factory
Expand Down Expand Up @@ -71,6 +76,30 @@ func (tf *baseTxFactory) ExecuteCosmosTx(privKey cryptotypes.PrivKey, txArgs Cos
return tf.network.BroadcastTxSync(txBytes)
}

// CommitCosmosTx creates and signs a Cosmos transaction, and then includes it in
// a block and commits the state changes on the chain
func (tf *baseTxFactory) CommitCosmosTx(privKey cryptotypes.PrivKey, txArgs CosmosTxArgs) (abcitypes.ExecTxResult, error) {
signedTx, err := tf.BuildCosmosTx(privKey, txArgs)
if err != nil {
return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to build tx")
}

txBytes, err := tf.EncodeTx(signedTx)
if err != nil {
return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to encode tx")
}

blockRes, err := tf.network.NextBlockWithTxs(txBytes)
if err != nil {
return abcitypes.ExecTxResult{}, errorsmod.Wrap(err, "failed to include the tx in a block")
}
txResCount := len(blockRes.TxResults)
if txResCount != 1 {
return abcitypes.ExecTxResult{}, fmt.Errorf("expected to receive only one tx result, but got %d", txResCount)
}
return *blockRes.TxResults[0], nil
}

// SignCosmosTx is a helper function that signs a Cosmos transaction
// with the provided private key and transaction builder
func (tf *baseTxFactory) SignCosmosTx(privKey cryptotypes.PrivKey, txBuilder client.TxBuilder) error {
Expand Down
19 changes: 14 additions & 5 deletions testutil/integration/common/factory/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
)

type StakingTxFactory interface {
// Delegate is a method to create and broadcast a MsgDelegate
// Delegate is a method to create and execute a MsgDelegate paying always the same fee amount
// The tx is included in a block and committed in the chain state
Delegate(delegatorPriv cryptotypes.PrivKey, validatorAddr string, amount sdk.Coin) error
// CreateValidator is a method to create and broadcast a MsgCreateValidator
CreateValidator(operatorPriv cryptotypes.PrivKey, pubKey cryptotypes.PubKey, selfDelegation sdk.Coin, description stakingtypes.Description, commission stakingtypes.CommissionRates, minSelfDelegation math.Int) error
Expand All @@ -39,12 +40,20 @@ func (tf *stakingTxFactory) Delegate(delegatorPriv cryptotypes.PrivKey, validato
amount,
)

resp, err := tf.ExecuteCosmosTx(delegatorPriv, CosmosTxArgs{
Msgs: []sdk.Msg{msgDelegate},
// set gas and gas prices to pay the same fees
// every time this function is called
feesToPay := math.NewInt(1e16)
gas := uint64(400_000)
gasPrice := feesToPay.QuoRaw(int64(gas))

res, err := tf.CommitCosmosTx(delegatorPriv, CosmosTxArgs{
Msgs: []sdk.Msg{msgDelegate},
Gas: &gas,
GasPrice: &gasPrice,
})

if resp.Code != 0 {
err = fmt.Errorf("received error code %d on Delegate transaction. Logs: %s", resp.Code, resp.Log)
if res.IsErr() {
return fmt.Errorf("tx result with code %d. Logs: %s", res.Code, res.Log)
}

return err
Expand Down
6 changes: 6 additions & 0 deletions testutil/integration/common/grpc/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ func (gqh *IntegrationHandler) GetTotalSupply() (*banktypes.QueryTotalSupplyResp
bankClient := gqh.network.GetBankClient()
return bankClient.TotalSupply(context.Background(), &banktypes.QueryTotalSupplyRequest{})
}

// GetSpendableBalance returns the spendable balance for the given denomination.
func (gqh *IntegrationHandler) GetSpendableBalance(address sdktypes.AccAddress, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error) {
bankClient := gqh.network.GetBankClient()
return bankClient.SpendableBalanceByDenom(context.Background(), &banktypes.QuerySpendableBalanceByDenomRequest{Address: address.String(), Denom: denom})
}
1 change: 1 addition & 0 deletions testutil/integration/common/grpc/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Handler interface {

// Bank methods
GetBalance(address sdktypes.AccAddress, denom string) (*banktypes.QueryBalanceResponse, error)
GetSpendableBalance(address sdktypes.AccAddress, denom string) (*banktypes.QuerySpendableBalanceByDenomResponse, error)
GetAllBalances(address sdktypes.AccAddress) (*banktypes.QueryAllBalancesResponse, error)
GetTotalSupply() (*banktypes.QueryTotalSupplyResponse, error)

Expand Down
1 change: 1 addition & 0 deletions testutil/integration/common/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Network interface {

NextBlock() error
NextBlockAfter(duration time.Duration) error
NextBlockWithTxs(txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error)

// Clients
GetAuthClient() authtypes.QueryClient
Expand Down
19 changes: 12 additions & 7 deletions testutil/integration/evmos/factory/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,9 @@ func (tf *IntegrationTxFactory) EstimateGasLimit(from *common.Address, txArgs *e

// GenerateSignedEthTx generates an Ethereum tx with the provided private key and txArgs but does not broadcast it.
func (tf *IntegrationTxFactory) GenerateSignedEthTx(privKey cryptotypes.PrivKey, txArgs evmtypes.EvmTxArgs) (signing.Tx, error) {
msgEthereumTx, err := tf.GenerateMsgEthereumTx(privKey, txArgs)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to create ethereum tx")
}

signedMsg, err := tf.SignMsgEthereumTx(privKey, msgEthereumTx)
signedMsg, err := tf.GenerateSignedMsgEthereumTx(privKey, txArgs)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to sign ethereum tx")
return nil, errorsmod.Wrap(err, "failed to generate signed MsgEthereumTx")
}

// Validate the transaction to avoid unrealistic behavior
Expand All @@ -78,6 +73,16 @@ func (tf *IntegrationTxFactory) GenerateSignedEthTx(privKey cryptotypes.PrivKey,
return tf.buildSignedTx(signedMsg)
}

// GenerateSignedMsgEthereumTx generates an MsgEthereumTx signed with the provided private key and txArgs.
func (tf *IntegrationTxFactory) GenerateSignedMsgEthereumTx(privKey cryptotypes.PrivKey, txArgs evmtypes.EvmTxArgs) (evmtypes.MsgEthereumTx, error) {
msgEthereumTx, err := tf.GenerateMsgEthereumTx(privKey, txArgs)
if err != nil {
return evmtypes.MsgEthereumTx{}, errorsmod.Wrap(err, "failed to create ethereum tx")
}

return tf.SignMsgEthereumTx(privKey, msgEthereumTx)
}

// GenerateMsgEthereumTx creates a new MsgEthereumTx with the provided arguments.
// If any of the arguments are not provided, they will be populated with default values.
func (tf *IntegrationTxFactory) GenerateMsgEthereumTx(
Expand Down
2 changes: 2 additions & 0 deletions testutil/integration/evmos/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type TxFactory interface {
GenerateDefaultTxTypeArgs(sender common.Address, txType int) (evmtypes.EvmTxArgs, error)
// GenerateSignedEthTx generates an Ethereum tx with the provided private key and txArgs but does not broadcast it.
GenerateSignedEthTx(privKey cryptotypes.PrivKey, txArgs evmtypes.EvmTxArgs) (signing.Tx, error)
// GenerateSignedMsgEthereumTx generates an MsgEthereumTx signed with the provided private key and txArgs.
GenerateSignedMsgEthereumTx(privKey cryptotypes.PrivKey, txArgs evmtypes.EvmTxArgs) (evmtypes.MsgEthereumTx, error)

// SignMsgEthereumTx signs a MsgEthereumTx with the provided private key.
SignMsgEthereumTx(privKey cryptotypes.PrivKey, msgEthereumTx evmtypes.MsgEthereumTx) (evmtypes.MsgEthereumTx, error)
Expand Down
7 changes: 7 additions & 0 deletions testutil/integration/evmos/keyring/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type Keyring interface {
GetAllAccAddrs() []sdktypes.AccAddress
// GetKey returns the key at the given keyring index
GetKey(index int) Key
// GetKeys returns all the keys
GetKeys() []Key

// AddKey adds a new account to the keyring
AddKey() int
Expand Down Expand Up @@ -94,6 +96,11 @@ func (kr *IntegrationKeyring) GetKey(index int) Key {
return kr.keys[index]
}

// GetKey returns the key specified by index
func (kr *IntegrationKeyring) GetKeys() []Key {
return kr.keys
}

// AddKey adds a new account to the keyring. It returns the index for the key
func (kr *IntegrationKeyring) AddKey() int {
acc := NewKey()
Expand Down
57 changes: 39 additions & 18 deletions testutil/integration/evmos/network/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,23 @@ func (n *IntegrationNetwork) NextBlock() error {
}

// NextBlockAfter is a private helper function that runs the FinalizeBlock logic, updates the context and
//
// commits the changes to have a block time after the given duration.
// commits the changes to have a block time after the given duration.
func (n *IntegrationNetwork) NextBlockAfter(duration time.Duration) error {
_, err := n.finalizeBlockAndCommit(duration)
return err
}

// NextBlockWithTxs is a helper function that runs the FinalizeBlock logic
// with the provided tx bytes, updates the context and
// commits the changes to have a block time after the given duration.
func (n *IntegrationNetwork) NextBlockWithTxs(txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error) {
return n.finalizeBlockAndCommit(time.Second, txBytes...)
}

// finalizeBlockAndCommit is a private helper function that runs the FinalizeBlock logic
// with the provided txBytes, updates the context and
// commits the changes to have a block time after the given duration.
func (n *IntegrationNetwork) finalizeBlockAndCommit(duration time.Duration, txBytes ...[]byte) (*abcitypes.ResponseFinalizeBlock, error) {
header := n.ctx.BlockHeader()
// Update block header and BeginBlock
header.Height++
Expand All @@ -29,21 +43,12 @@ func (n *IntegrationNetwork) NextBlockAfter(duration time.Duration) error {
newBlockTime := header.Time.Add(duration)
header.Time = newBlockTime

// add validator's commit info to allocate corresponding tokens to validators
ci := getCommitInfo(n.valSet.Validators)

// FinalizeBlock to run endBlock, deliverTx & beginBlock logic
req := &abcitypes.RequestFinalizeBlock{
Height: n.app.LastBlockHeight() + 1,
DecidedLastCommit: ci,
Hash: header.AppHash,
NextValidatorsHash: n.valSet.Hash(),
ProposerAddress: n.valSet.Proposer.Address,
Time: newBlockTime,
}
req := buildFinalizeBlockReq(header, n.valSet.Validators, txBytes...)

if _, err := n.app.FinalizeBlock(req); err != nil {
return err
res, err := n.app.FinalizeBlock(req)
if err != nil {
return nil, err
}

newCtx := n.app.BaseApp.NewContextLegacy(false, header)
Expand All @@ -55,13 +60,29 @@ func (n *IntegrationNetwork) NextBlockAfter(duration time.Duration) error {
newCtx = newCtx.WithConsensusParams(n.ctx.ConsensusParams())
// This might have to be changed with time if we want to test gas limits
newCtx = newCtx.WithBlockGasMeter(storetypes.NewInfiniteGasMeter())
newCtx = newCtx.WithVoteInfos(ci.GetVotes())
newCtx = newCtx.WithVoteInfos(req.DecidedLastCommit.GetVotes())
n.ctx = newCtx

// commit changes
_, err := n.app.Commit()
_, err = n.app.Commit()

return err
return res, err
}

// buildFinalizeBlockReq is a helper function to build
// properly the FinalizeBlock request
func buildFinalizeBlockReq(header cmtproto.Header, validators []*cmttypes.Validator, txs ...[]byte) *abcitypes.RequestFinalizeBlock {
// add validator's commit info to allocate corresponding tokens to validators
ci := getCommitInfo(validators)
return &abcitypes.RequestFinalizeBlock{
Height: header.Height,
DecidedLastCommit: ci,
Hash: header.AppHash,
NextValidatorsHash: header.ValidatorsHash,
ProposerAddress: header.ProposerAddress,
Time: header.Time,
Txs: txs,
}
}

func getCommitInfo(validators []*cmttypes.Validator) abcitypes.CommitInfo {
Expand Down
7 changes: 7 additions & 0 deletions testutil/integration/evmos/network/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
evmtypes "github.com/evmos/evmos/v18/x/evm/types"
feemarkettypes "github.com/evmos/evmos/v18/x/feemarket/types"
infltypes "github.com/evmos/evmos/v18/x/inflation/v1/types"
vestingtypes "github.com/evmos/evmos/v18/x/vesting/types"
)

func getQueryHelper(ctx sdktypes.Context) *baseapp.QueryServiceTestHelper {
Expand Down Expand Up @@ -98,3 +99,9 @@ func (n *IntegrationNetwork) GetEpochsClient() epochstypes.QueryClient {
epochstypes.RegisterQueryServer(queryHelper, n.app.EpochsKeeper)
return epochstypes.NewQueryClient(queryHelper)
}

func (n *IntegrationNetwork) GetVestingClient() vestingtypes.QueryClient {
queryHelper := getQueryHelper(n.GetContext())
vestingtypes.RegisterQueryServer(queryHelper, n.app.VestingKeeper)
return vestingtypes.NewQueryClient(queryHelper)
}

0 comments on commit 5f11136

Please sign in to comment.