From 9094794478d6a93b57237ea658c13f6fec70ae80 Mon Sep 17 00:00:00 2001 From: MD Aleem <72057206+aleem1314@users.noreply.github.com> Date: Tue, 5 Oct 2021 17:32:51 +0530 Subject: [PATCH] feat!: Ensure InitGenesis returns with non-empty validator set (#9697) ## Description Closes: #8961 SDK allows InitGenesis to return with an empty validator set. In practice, the error for an empty validator set gets thrown in tendermint. To fix this, * Add non-empty validator set check to the `mm.InitGenesis` function. This will break `simapp.Setup` because it relies on an empty validator set [#comment](https://github.com/cosmos/cosmos-sdk/pull/8909#issuecomment-804850834). * Update `simapp.Setup` to use a single validator. * Fix failing tests (Most of them are keeper tests). --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- CHANGELOG.md | 1 + server/export_test.go | 29 ++--- simapp/sim_test.go | 13 ++ simapp/test_helpers.go | 92 ++++++++------ types/module/module.go | 10 +- types/module/module_test.go | 3 +- x/auth/keeper/grpc_query_test.go | 8 +- x/auth/module_test.go | 15 ++- x/bank/keeper/genesis_test.go | 20 +++- x/bank/keeper/grpc_query_test.go | 21 ++-- x/bank/keeper/keeper_test.go | 17 ++- x/bank/keeper/querier_test.go | 10 +- x/distribution/keeper/allocation_test.go | 7 ++ x/distribution/keeper/delegation_test.go | 7 ++ x/distribution/keeper/grpc_query_test.go | 2 + x/distribution/keeper/keeper_test.go | 3 + x/distribution/keeper/querier_test.go | 3 + x/distribution/module_test.go | 15 ++- x/distribution/proposal_handler_test.go | 3 + x/distribution/simulation/operations_test.go | 30 +++-- x/feegrant/simulation/operations_test.go | 4 +- x/genutil/gentx_test.go | 2 +- x/gov/genesis_test.go | 7 ++ x/gov/module_test.go | 15 ++- x/mint/module_test.go | 15 ++- x/params/keeper/keeper_test.go | 5 +- x/slashing/keeper/keeper_test.go | 2 + x/slashing/simulation/operations_test.go | 66 ++++++---- x/staking/genesis_test.go | 14 ++- x/staking/keeper/delegation_test.go | 9 ++ x/staking/keeper/grpc_query_test.go | 6 +- x/staking/keeper/historical_info_test.go | 14 ++- x/staking/keeper/querier_test.go | 10 +- x/staking/keeper/validator_test.go | 20 +++- x/staking/module_test.go | 15 ++- x/staking/simulation/operations.go | 2 +- x/staking/simulation/operations_test.go | 120 ++++++++++--------- 37 files changed, 425 insertions(+), 210 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef4a2424e..556a4ac31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -122,6 +122,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls. * (rosetta) [\#10001](https://github.com/cosmos/cosmos-sdk/issues/10001) Add documentation for rosetta-cli dockerfile and rename folder for the rosetta-ci dockerfile * [\#9699](https://github.com/cosmos/cosmos-sdk/pull/9699) Add `:`, `.`, `-`, and `_` as allowed characters in the default denom regular expression. +* (genesis) [\#9697](https://github.com/cosmos/cosmos-sdk/pull/9697) Ensure `InitGenesis` returns with non-empty validator set. * [\#10262](https://github.com/cosmos/cosmos-sdk/pull/10262) Remove unnecessary logging in `x/feegrant` simulation. ### Bug Fixes diff --git a/server/export_test.go b/server/export_test.go index c41d60f02..32410a824 100644 --- a/server/export_test.go +++ b/server/export_test.go @@ -3,7 +3,6 @@ package server_test import ( "bytes" "context" - "encoding/json" "fmt" "io" "os" @@ -22,7 +21,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp" @@ -123,6 +121,8 @@ func TestExportCmd_Height(t *testing.T) { } func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *tmtypes.GenesisDoc, *cobra.Command) { + t.Helper() + if err := createConfigFolder(tempDir); err != nil { t.Fatalf("error creating config folder: %s", err) } @@ -132,11 +132,18 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t encCfg := simapp.MakeTestEncodingConfig() app := simapp.NewSimApp(logger, db, nil, true, map[int64]bool{}, tempDir, 0, encCfg, simapp.EmptyAppOptions{}) + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ") + require.NoError(t, err) + serverCtx := server.NewDefaultContext() serverCtx.Config.RootDir = tempDir clientCtx := client.Context{}.WithCodec(app.AppCodec()) - genDoc := newDefaultGenesisDoc(encCfg.Codec) + genDoc := &tmtypes.GenesisDoc{} + genDoc.ChainID = "theChainId" + genDoc.Validators = nil + genDoc.AppState = stateBytes require.NoError(t, saveGenesisFile(genDoc, serverCtx.Config.GenesisFile())) app.InitChain( @@ -177,22 +184,6 @@ func createConfigFolder(dir string) error { return os.Mkdir(path.Join(dir, "config"), 0700) } -func newDefaultGenesisDoc(cdc codec.Codec) *tmtypes.GenesisDoc { - genesisState := simapp.NewDefaultGenesisState(cdc) - - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - if err != nil { - panic(err) - } - - genDoc := &tmtypes.GenesisDoc{} - genDoc.ChainID = "theChainId" - genDoc.Validators = nil - genDoc.AppState = stateBytes - - return genDoc -} - func saveGenesisFile(genDoc *tmtypes.GenesisDoc, dir string) error { err := genutil.ExportGenesisFile(genDoc, dir) if err != nil { diff --git a/simapp/sim_test.go b/simapp/sim_test.go index 377c93790..26b125208 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -5,6 +5,8 @@ import ( "fmt" "math/rand" "os" + "runtime/debug" + "strings" "testing" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -153,6 +155,17 @@ func TestAppImportExport(t *testing.T) { err = json.Unmarshal(exported.AppState, &genesisState) require.NoError(t, err) + defer func() { + if r := recover(); r != nil { + err := fmt.Sprintf("%v", r) + if !strings.Contains(err, "validator set is empty after InitGenesis") { + panic(r) + } + logger.Info("Skipping simulation as all validators have been unbonded") + logger.Info("err", err, "stacktrace", string(debug.Stack())) + } + }() + ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 58e365aed..bf6476676 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -121,22 +121,24 @@ func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptio func Setup(t *testing.T, isCheckTx bool) *SimApp { t.Helper() - app, genesisState := setup(!isCheckTx, 5) - if !isCheckTx { - // init chain must be called to stop deliverState from being nil - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - require.NoError(t, err) + privVal := mock.NewPV() + pubKey, err := privVal.GetPubKey() + require.NoError(t, err) - // Initialize the chain - app.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) + // create validator set with single validator + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), } + app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) + return app } @@ -181,8 +183,13 @@ func genesisStateWithValSet(t *testing.T, totalSupply := sdk.NewCoins() for _, b := range balances { - // add genesis acc tokens and delegated tokens to total supply - totalSupply = totalSupply.Add(b.Coins.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt))...) + // add genesis acc tokens to total supply + totalSupply = totalSupply.Add(b.Coins...) + } + + for range delegations { + // add delegated tokens to total supply + totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) } // add bonded amount to bonded pool module account @@ -237,33 +244,44 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs func SetupWithGenesisAccounts(t *testing.T, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { t.Helper() - app, genesisState := setup(true, 0) - authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) - genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - - totalSupply := sdk.NewCoins() - for _, b := range balances { - totalSupply = totalSupply.Add(b.Coins...) - } - - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}) - genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) - - stateBytes, err := json.MarshalIndent(genesisState, "", " ") + privVal := mock.NewPV() + pubKey, err := privVal.GetPubKey() require.NoError(t, err) - app.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: DefaultConsensusParams, - AppStateBytes: stateBytes, + // create validator set with single validator + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + return SetupWithGenesisValSet(t, valSet, genAccs, balances...) +} + +// SetupWithGenesisValSet initializes GenesisState with a single validator and genesis accounts +// that also act as delegators. +func GenesisStateWithSingleValidator(t *testing.T, app *SimApp) GenesisState { + t.Helper() + + privVal := mock.NewPV() + pubKey, err := privVal.GetPubKey() + require.NoError(t, err) + + // create validator set with single validator + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balances := []banktypes.Balance{ + { + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), }, - ) + } - app.Commit() - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1}}) + genesisState := NewDefaultGenesisState(app.appCodec) + genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) - return app + return genesisState } type GenerateAccountStrategy func(int) []sdk.AccAddress diff --git a/types/module/module.go b/types/module/module.go index 7341edf8e..685a6dcd6 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -30,6 +30,7 @@ package module import ( "encoding/json" + "fmt" "sort" "github.com/gorilla/mux" @@ -296,7 +297,9 @@ func (m *Manager) RegisterServices(cfg Configurator) { } } -// InitGenesis performs init genesis functionality for modules +// InitGenesis performs init genesis functionality for modules. Exactly one +// module must return a non-empty validator set update to correctly initialize +// the chain. func (m *Manager) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage) abci.ResponseInitChain { var validatorUpdates []abci.ValidatorUpdate ctx.Logger().Info("initializing blockchain state from genesis.json") @@ -318,6 +321,11 @@ func (m *Manager) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData } } + // a chain must initialize with a non-empty validator set + if len(validatorUpdates) == 0 { + panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction)) + } + return abci.ResponseInitChain{ Validators: validatorUpdates, } diff --git a/types/module/module_test.go b/types/module/module_test.go index 49f6bf0ad..4dbb4a73c 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -206,8 +206,9 @@ func TestManager_InitGenesis(t *testing.T) { cdc := codec.NewProtoCodec(interfaceRegistry) genesisData := map[string]json.RawMessage{"module1": json.RawMessage(`{"key": "value"}`)} + // this should panic since the validator set is empty even after init genesis mockAppModule1.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(cdc), gomock.Eq(genesisData["module1"])).Times(1).Return(nil) - require.Equal(t, abci.ResponseInitChain{Validators: []abci.ValidatorUpdate(nil)}, mm.InitGenesis(ctx, cdc, genesisData)) + require.Panics(t, func() { mm.InitGenesis(ctx, cdc, genesisData) }) // test panic genesisData = map[string]json.RawMessage{ diff --git a/x/auth/keeper/grpc_query_test.go b/x/auth/keeper/grpc_query_test.go index 07d45e527..9052873d9 100644 --- a/x/auth/keeper/grpc_query_test.go +++ b/x/auth/keeper/grpc_query_test.go @@ -37,14 +37,14 @@ func (suite *KeeperTestSuite) TestGRPCQueryAccounts() { }, true, func(res *types.QueryAccountsResponse) { - for _, acc := range res.Accounts { + addresses := make([]sdk.AccAddress, len(res.Accounts)) + for i, acc := range res.Accounts { var account types.AccountI err := suite.app.InterfaceRegistry().UnpackAny(acc, &account) suite.Require().NoError(err) - - suite.Require().True( - first.Equals(account.GetAddress()) || second.Equals(account.GetAddress())) + addresses[i] = account.GetAddress() } + suite.Subset(addresses, []sdk.AccAddress{first, second}) }, }, } diff --git a/x/auth/module_test.go b/x/auth/module_test.go index 8e4c270d5..6f527c587 100644 --- a/x/auth/module_test.go +++ b/x/auth/module_test.go @@ -5,23 +5,32 @@ import ( "github.com/stretchr/testify/require" abcitypes "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(t, false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.Marshal(genesisState) + require.NoError(t, err) app.InitChain( abcitypes.RequestInitChain{ - AppStateBytes: []byte("{}"), + AppStateBytes: stateBytes, ChainId: "test-chain-id", }, ) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) acc := app.AccountKeeper.GetAccount(ctx, types.NewModuleAddress(types.FeeCollectorName)) require.NotNil(t, acc) } diff --git a/x/bank/keeper/genesis_test.go b/x/bank/keeper/genesis_test.go index 70d53b9f0..d8fd84d2e 100644 --- a/x/bank/keeper/genesis_test.go +++ b/x/bank/keeper/genesis_test.go @@ -11,7 +11,13 @@ func (suite *IntegrationTestSuite) TestExportGenesis() { app, ctx := suite.app, suite.ctx expectedMetadata := suite.getTestMetadata() - expectedBalances, totalSupply := suite.getTestBalancesAndSupply() + expectedBalances, expTotalSupply := suite.getTestBalancesAndSupply() + + // Adding genesis supply to the expTotalSupply + genesisSupply, _, err := suite.app.BankKeeper.GetPaginatedTotalSupply(suite.ctx, &query.PageRequest{Limit: query.MaxLimit}) + suite.Require().NoError(err) + expTotalSupply = expTotalSupply.Add(genesisSupply...) + for i := range []int{1, 2} { app.BankKeeper.SetDenomMetaData(ctx, expectedMetadata[i]) accAddr, err1 := sdk.AccAddressFromBech32(expectedBalances[i].Address) @@ -32,8 +38,8 @@ func (suite *IntegrationTestSuite) TestExportGenesis() { suite.Require().Len(exportGenesis.Params.SendEnabled, 0) suite.Require().Equal(types.DefaultParams().DefaultSendEnabled, exportGenesis.Params.DefaultSendEnabled) - suite.Require().Equal(totalSupply, exportGenesis.Supply) - suite.Require().Equal(expectedBalances, exportGenesis.Balances) + suite.Require().Equal(expTotalSupply, exportGenesis.Supply) + suite.Require().Subset(exportGenesis.Balances, expectedBalances) suite.Require().Equal(expectedMetadata, exportGenesis.DenomMetadata) } @@ -74,6 +80,9 @@ func (suite *IntegrationTestSuite) TestTotalSupply() { } totalSupply := sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(11)), sdk.NewCoin("barcoin", sdk.NewInt(21))) + genesisSupply, _, err := suite.app.BankKeeper.GetPaginatedTotalSupply(suite.ctx, &query.PageRequest{Limit: query.MaxLimit}) + suite.Require().NoError(err) + testcases := []struct { name string genesis *types.GenesisState @@ -107,7 +116,10 @@ func (suite *IntegrationTestSuite) TestTotalSupply() { suite.app.BankKeeper.InitGenesis(suite.ctx, tc.genesis) totalSupply, _, err := suite.app.BankKeeper.GetPaginatedTotalSupply(suite.ctx, &query.PageRequest{Limit: query.MaxLimit}) suite.Require().NoError(err) - suite.Require().Equal(tc.expSupply, totalSupply) + + // adding genesis supply to expected supply + expected := tc.expSupply.Add(genesisSupply...) + suite.Require().Equal(expected, totalSupply) } }) } diff --git a/x/bank/keeper/grpc_query_test.go b/x/bank/keeper/grpc_query_test.go index 50be8cea9..1f8a1de5e 100644 --- a/x/bank/keeper/grpc_query_test.go +++ b/x/bank/keeper/grpc_query_test.go @@ -81,22 +81,29 @@ func (suite *IntegrationTestSuite) TestQueryAllBalances() { } req = types.NewQueryAllBalancesRequest(addr, pageReq) res, err = queryClient.AllBalances(gocontext.Background(), req) + suite.Require().NoError(err) suite.Equal(res.Balances.Len(), 1) suite.Nil(res.Pagination.NextKey) } func (suite *IntegrationTestSuite) TestQueryTotalSupply() { app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient - expectedTotalSupply := sdk.NewCoins(sdk.NewInt64Coin("test", 400000000)) + res, err := queryClient.TotalSupply(gocontext.Background(), &types.QueryTotalSupplyRequest{}) + suite.Require().NoError(err) + genesisSupply := res.Supply + + testCoins := sdk.NewCoins(sdk.NewInt64Coin("test", 400000000)) suite. Require(). - NoError(app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, expectedTotalSupply)) + NoError(app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, testCoins)) - res, err := queryClient.TotalSupply(gocontext.Background(), &types.QueryTotalSupplyRequest{}) + res, err = queryClient.TotalSupply(gocontext.Background(), &types.QueryTotalSupplyRequest{}) suite.Require().NoError(err) suite.Require().NotNil(res) - suite.Require().Equal(expectedTotalSupply, res.Supply) + expectedTotalSupply := genesisSupply.Add(testCoins...) + suite.Require().Equal(2, len(res.Supply)) + suite.Require().Equal(res.Supply, expectedTotalSupply) } func (suite *IntegrationTestSuite) TestQueryTotalSupplyOf() { @@ -353,7 +360,7 @@ func (suite *IntegrationTestSuite) TestGRPCDenomOwners() { expPass: true, numAddrs: 6, hasNext: true, - total: 10, + total: 13, }, "valid request - page 2": { req: &types.QueryDenomOwnersRequest{ @@ -365,9 +372,9 @@ func (suite *IntegrationTestSuite) TestGRPCDenomOwners() { }, }, expPass: true, - numAddrs: 4, + numAddrs: 7, hasNext: false, - total: 10, + total: 13, }, } diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index 93de432cf..52d0dc133 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -117,26 +117,31 @@ func (suite *IntegrationTestSuite) TestSupply() { // add module accounts to supply keeper authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) + genesisSupply, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{}) + require.NoError(err) + initialPower := int64(100) initTokens := suite.app.StakingKeeper.TokensFromConsensusPower(ctx, initialPower) - totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) + initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) // set burnerAcc balance authKeeper.SetModuleAccount(ctx, burnerAcc) - require.NoError(keeper.MintCoins(ctx, authtypes.Minter, totalSupply)) - require.NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, burnerAcc.GetAddress(), totalSupply)) + require.NoError(keeper.MintCoins(ctx, authtypes.Minter, initCoins)) + require.NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, burnerAcc.GetAddress(), initCoins)) total, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{}) require.NoError(err) - require.Equal(totalSupply, total) + + expTotalSupply := initCoins.Add(genesisSupply...) + require.Equal(expTotalSupply, total) // burning all supplied tokens - err = keeper.BurnCoins(ctx, authtypes.Burner, totalSupply) + err = keeper.BurnCoins(ctx, authtypes.Burner, initCoins) require.NoError(err) total, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{}) require.NoError(err) - require.Equal(total.String(), "") + require.Equal(total, genesisSupply) } func (suite *IntegrationTestSuite) TestSendCoinsFromModuleToAccount_Blocklist() { diff --git a/x/bank/keeper/querier_test.go b/x/bank/keeper/querier_test.go index 8404ed360..7eba1f608 100644 --- a/x/bank/keeper/querier_test.go +++ b/x/bank/keeper/querier_test.go @@ -90,10 +90,14 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryAllBalances() { func (suite *IntegrationTestSuite) TestQuerier_QueryTotalSupply() { app, ctx := suite.app, suite.ctx legacyAmino := app.LegacyAmino() - expectedTotalSupply := sdk.NewCoins(sdk.NewInt64Coin("test", 400000000)) + + genesisSupply, _, err := suite.app.BankKeeper.GetPaginatedTotalSupply(suite.ctx, &query.PageRequest{Limit: query.MaxLimit}) + suite.Require().NoError(err) + + testCoins := sdk.NewCoins(sdk.NewInt64Coin("test", 400000000)) suite. Require(). - NoError(app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, expectedTotalSupply)) + NoError(app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, testCoins)) req := abci.RequestQuery{ Path: fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryTotalSupply), @@ -115,6 +119,8 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryTotalSupply() { var resp types.QueryTotalSupplyResponse suite.Require().NoError(legacyAmino.UnmarshalJSON(res, &resp)) + + expectedTotalSupply := genesisSupply.Add(testCoins...) suite.Require().Equal(expectedTotalSupply, resp.Supply) } diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index 2a4494198..d32b43690 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -11,6 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -48,6 +49,9 @@ func TestAllocateTokensToManyValidators(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + // reset fee pool + app.DistrKeeper.SetFeePool(ctx, disttypes.InitialFeePool()) + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.NewInt(1234)) valAddrs := simapp.ConvertAddrsToValAddrs(addrs) tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -119,6 +123,9 @@ func TestAllocateTokensTruncation(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + // reset fee pool + app.DistrKeeper.SetFeePool(ctx, disttypes.InitialFeePool()) + addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(1234)) valAddrs := simapp.ConvertAddrsToValAddrs(addrs) tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index aefe60c20..a1916913c 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -17,6 +17,9 @@ import ( func TestCalculateRewardsBasic(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + + app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) + tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) addr := simapp.AddTestAddrs(app, ctx, 2, sdk.NewInt(1000)) @@ -273,6 +276,8 @@ func TestWithdrawDelegationRewardsBasic(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) + balancePower := int64(1000) balanceTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, balancePower) addr := simapp.AddTestAddrs(app, ctx, 1, sdk.NewInt(1000000000)) @@ -486,6 +491,8 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) + tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) addr := simapp.AddTestAddrs(app, ctx, 2, sdk.NewInt(1000000000)) valAddrs := simapp.ConvertAddrsToValAddrs(addr) diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go index 1d80491fd..d51f4a28a 100644 --- a/x/distribution/keeper/grpc_query_test.go +++ b/x/distribution/keeper/grpc_query_test.go @@ -601,6 +601,8 @@ func (suite *KeeperTestSuite) TestGRPCDelegatorWithdrawAddress() { func (suite *KeeperTestSuite) TestGRPCCommunityPool() { app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs + // reset fee pool + app.DistrKeeper.SetFeePool(ctx, types.InitialFeePool()) var ( req *types.QueryCommunityPoolRequest diff --git a/x/distribution/keeper/keeper_test.go b/x/distribution/keeper/keeper_test.go index 1f9639838..9895e420b 100644 --- a/x/distribution/keeper/keeper_test.go +++ b/x/distribution/keeper/keeper_test.go @@ -112,6 +112,9 @@ func TestFundCommunityPool(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + // reset fee pool + app.DistrKeeper.SetFeePool(ctx, types.InitialFeePool()) + addr := simapp.AddTestAddrs(app, ctx, 2, sdk.ZeroInt()) amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) diff --git a/x/distribution/keeper/querier_test.go b/x/distribution/keeper/querier_test.go index 0ffb14bfb..9e1fe7ccc 100644 --- a/x/distribution/keeper/querier_test.go +++ b/x/distribution/keeper/querier_test.go @@ -119,6 +119,9 @@ func TestQueries(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + // reset fee pool + app.DistrKeeper.SetFeePool(ctx, types.InitialFeePool()) + addr := simapp.AddTestAddrs(app, ctx, 1, sdk.NewInt(1000000000)) valAddrs := simapp.ConvertAddrsToValAddrs(addr) valOpAddr1 := valAddrs[0] diff --git a/x/distribution/module_test.go b/x/distribution/module_test.go index 562621d00..70e2e50ea 100644 --- a/x/distribution/module_test.go +++ b/x/distribution/module_test.go @@ -5,7 +5,10 @@ import ( "github.com/stretchr/testify/require" abcitypes "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/simapp" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -13,16 +16,22 @@ import ( ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(t, false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.Marshal(genesisState) + require.NoError(t, err) app.InitChain( abcitypes.RequestInitChain{ - AppStateBytes: []byte("{}"), + AppStateBytes: stateBytes, ChainId: "test-chain-id", }, ) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) require.NotNil(t, acc) } diff --git a/x/distribution/proposal_handler_test.go b/x/distribution/proposal_handler_test.go index 5e109f5e9..24be6c98e 100644 --- a/x/distribution/proposal_handler_test.go +++ b/x/distribution/proposal_handler_test.go @@ -58,6 +58,9 @@ func TestProposalHandlerFailed(t *testing.T) { app := simapp.Setup(t, false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + // reset fee pool + app.DistrKeeper.SetFeePool(ctx, types.InitialFeePool()) + recipient := delAddr1 account := app.AccountKeeper.NewAccountWithAddress(ctx, recipient) diff --git a/x/distribution/simulation/operations_test.go b/x/distribution/simulation/operations_test.go index 1ef25858c..4d70aab2e 100644 --- a/x/distribution/simulation/operations_test.go +++ b/x/distribution/simulation/operations_test.go @@ -157,9 +157,11 @@ func (suite *SimTestSuite) testSimulateMsgWithdrawValidatorCommission(tokenName ) suite.app.DistrKeeper.SetValidatorOutstandingRewards(suite.ctx, validator0.GetOperator(), types.ValidatorOutstandingRewards{Rewards: valCommission}) + suite.app.DistrKeeper.SetValidatorOutstandingRewards(suite.ctx, suite.genesisVals[0].GetOperator(), types.ValidatorOutstandingRewards{Rewards: valCommission}) // setup validator accumulated commission suite.app.DistrKeeper.SetValidatorAccumulatedCommission(suite.ctx, validator0.GetOperator(), types.ValidatorAccumulatedCommission{Commission: valCommission}) + suite.app.DistrKeeper.SetValidatorAccumulatedCommission(suite.ctx, suite.genesisVals[0].GetOperator(), types.ValidatorAccumulatedCommission{Commission: valCommission}) // begin a new block suite.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}}) @@ -167,16 +169,20 @@ func (suite *SimTestSuite) testSimulateMsgWithdrawValidatorCommission(tokenName // execute operation op := simulation.SimulateMsgWithdrawValidatorCommission(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.DistrKeeper, suite.app.StakingKeeper) operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") - suite.Require().NoError(err) + if !operationMsg.OK { + suite.Require().Equal("could not find account", operationMsg.Comment) + } else { + suite.Require().NoError(err) - var msg types.MsgWithdrawValidatorCommission - types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) + var msg types.MsgWithdrawValidatorCommission + types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - suite.Require().True(operationMsg.OK) - suite.Require().Equal("cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) - suite.Require().Equal(types.TypeMsgWithdrawValidatorCommission, msg.Type()) - suite.Require().Equal(types.ModuleName, msg.Route()) - suite.Require().Len(futureOperations, 0) + suite.Require().True(operationMsg.OK) + suite.Require().Equal("cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) + suite.Require().Equal(types.TypeMsgWithdrawValidatorCommission, msg.Type()) + suite.Require().Equal(types.ModuleName, msg.Route()) + suite.Require().Len(futureOperations, 0) + } } // TestSimulateMsgFundCommunityPool tests the normal scenario of a valid message of type TypeMsgFundCommunityPool. @@ -209,8 +215,9 @@ func (suite *SimTestSuite) TestSimulateMsgFundCommunityPool() { type SimTestSuite struct { suite.Suite - ctx sdk.Context - app *simapp.SimApp + ctx sdk.Context + app *simapp.SimApp + genesisVals []stakingtypes.Validator } func (suite *SimTestSuite) SetupTest() { @@ -218,6 +225,9 @@ func (suite *SimTestSuite) SetupTest() { app := simapp.Setup(suite.T(), checkTx) suite.app = app suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{}) + genesisVals := app.StakingKeeper.GetAllValidators(suite.ctx) + suite.Require().Len(genesisVals, 1) + suite.genesisVals = genesisVals } func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Account { diff --git a/x/feegrant/simulation/operations_test.go b/x/feegrant/simulation/operations_test.go index 1d6135e72..59554125a 100644 --- a/x/feegrant/simulation/operations_test.go +++ b/x/feegrant/simulation/operations_test.go @@ -75,12 +75,12 @@ func (suite *SimTestSuite) TestWeightedOperations() { }{ { simappparams.DefaultWeightGrantAllowance, - feegrant.ModuleName, + feegrant.MsgGrantAllowance{}.Route(), simulation.TypeMsgGrantAllowance, }, { simappparams.DefaultWeightRevokeAllowance, - feegrant.ModuleName, + feegrant.MsgRevokeAllowance{}.Route(), simulation.TypeMsgRevokeAllowance, }, } diff --git a/x/genutil/gentx_test.go b/x/genutil/gentx_test.go index 55891a0b9..5d8289810 100644 --- a/x/genutil/gentx_test.go +++ b/x/genutil/gentx_test.go @@ -240,7 +240,7 @@ func (suite *GenTxTestSuite) TestDeliverGenTxs() { sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)}, helpers.DefaultGenTxGas, suite.ctx.ChainID(), - []uint64{0}, + []uint64{7}, []uint64{0}, priv1, ) diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go index d289af470..38750d7ed 100644 --- a/x/gov/genesis_test.go +++ b/x/gov/genesis_test.go @@ -15,8 +15,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/staking" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) func TestImportExportQueues(t *testing.T) { @@ -54,6 +57,8 @@ func TestImportExportQueues(t *testing.T) { authGenState := auth.ExportGenesis(ctx, app.AccountKeeper) bankGenState := app.BankKeeper.ExportGenesis(ctx) + stakingGenState := staking.ExportGenesis(ctx, app.StakingKeeper) + distributionGenState := app.DistrKeeper.ExportGenesis(ctx) // export the state and import it into a new app govGenState := gov.ExportGenesis(ctx, app.GovKeeper) @@ -62,6 +67,8 @@ func TestImportExportQueues(t *testing.T) { genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenState) genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenState) genesisState[types.ModuleName] = app.AppCodec().MustMarshalJSON(govGenState) + genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenState) + genesisState[distributiontypes.ModuleName] = app.AppCodec().MustMarshalJSON(distributionGenState) stateBytes, err := json.MarshalIndent(genesisState, "", " ") if err != nil { diff --git a/x/gov/module_test.go b/x/gov/module_test.go index fa07f9e30..c43f570db 100644 --- a/x/gov/module_test.go +++ b/x/gov/module_test.go @@ -5,7 +5,10 @@ import ( "github.com/stretchr/testify/require" abcitypes "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/simapp" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -13,16 +16,22 @@ import ( ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(t, false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.Marshal(genesisState) + require.NoError(t, err) app.InitChain( abcitypes.RequestInitChain{ - AppStateBytes: []byte("{}"), + AppStateBytes: stateBytes, ChainId: "test-chain-id", }, ) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) require.NotNil(t, acc) } diff --git a/x/mint/module_test.go b/x/mint/module_test.go index d35f2f824..ecf0a1511 100644 --- a/x/mint/module_test.go +++ b/x/mint/module_test.go @@ -5,7 +5,10 @@ import ( "github.com/stretchr/testify/require" abcitypes "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/simapp" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -13,16 +16,22 @@ import ( ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(t, false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.Marshal(genesisState) + require.NoError(t, err) app.InitChain( abcitypes.RequestInitChain{ - AppStateBytes: []byte("{}"), + AppStateBytes: stateBytes, ChainId: "test-chain-id", }, ) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) require.NotNil(t, acc) } diff --git a/x/params/keeper/keeper_test.go b/x/params/keeper/keeper_test.go index 043e715ca..92e2afb91 100644 --- a/x/params/keeper/keeper_test.go +++ b/x/params/keeper/keeper_test.go @@ -26,10 +26,9 @@ type KeeperTestSuite struct { } func (suite *KeeperTestSuite) SetupTest() { - app := simapp.Setup(suite.T(), true) - ctx := app.BaseApp.NewContext(true, tmproto.Header{}) + suite.app = simapp.Setup(suite.T(), false) + suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}) - suite.app, suite.ctx = app, ctx queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) proposal.RegisterQueryServer(queryHelper, suite.app.ParamsKeeper) suite.queryClient = proposal.NewQueryClient(queryHelper) diff --git a/x/slashing/keeper/keeper_test.go b/x/slashing/keeper/keeper_test.go index a5bdd4e0a..7385c1f4d 100644 --- a/x/slashing/keeper/keeper_test.go +++ b/x/slashing/keeper/keeper_test.go @@ -119,6 +119,8 @@ func TestHandleNewValidator(t *testing.T) { require.Equal(t, stakingtypes.Bonded, validator.GetStatus()) bondPool := app.StakingKeeper.GetBondedPool(ctx) expTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 100) + // adding genesis validator tokens + expTokens = expTokens.Add(app.StakingKeeper.TokensFromConsensusPower(ctx, 1)) require.True(t, expTokens.Equal(app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount)) } diff --git a/x/slashing/simulation/operations_test.go b/x/slashing/simulation/operations_test.go index fa7a6edf3..a0dbffb1f 100644 --- a/x/slashing/simulation/operations_test.go +++ b/x/slashing/simulation/operations_test.go @@ -8,12 +8,17 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/simapp" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/slashing/simulation" @@ -23,16 +28,14 @@ import ( // TestWeightedOperations tests the weights of the operations. func TestWeightedOperations(t *testing.T) { - app, ctx := createTestApp(t, false) + s := rand.NewSource(1) + r := rand.New(s) + app, ctx, accs := createTestApp(t, false, r, 3) ctx.WithChainID("test-chain") cdc := app.AppCodec() appParams := make(simtypes.AppParams) - s := rand.NewSource(1) - r := rand.New(s) - accs := simtypes.RandomAccounts(r, 3) - expected := []struct { weight int opMsgRoute string @@ -54,14 +57,15 @@ func TestWeightedOperations(t *testing.T) { // TestSimulateMsgUnjail tests the normal scenario of a valid message of type types.MsgUnjail. // Abonormal scenarios, where the message is created by an errors, are not tested here. func TestSimulateMsgUnjail(t *testing.T) { - app, ctx := createTestApp(t, false) + // setup 3 accounts + s := rand.NewSource(5) + r := rand.New(s) + app, ctx, accounts := createTestApp(t, false, r, 3) blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // setup 3 accounts - s := rand.NewSource(1) - r := rand.New(s) - accounts := getTestingAccounts(t, r, app, ctx, 3) + // remove genesis validator account + accounts = accounts[1:] // setup accounts[0] as validator0 validator0 := getTestingValidator0(t, app, ctx, accounts) @@ -99,35 +103,49 @@ func TestSimulateMsgUnjail(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, types.TypeMsgUnjail, msg.Type()) - require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddr) + require.Equal(t, "cosmosvaloper17s94pzwhsn4ah25tec27w70n65h5t2scgxzkv2", msg.ValidatorAddr) require.Len(t, futureOperations, 0) } // returns context and an app with updated mint keeper -func createTestApp(t *testing.T, isCheckTx bool) (*simapp.SimApp, sdk.Context) { - app := simapp.Setup(t, isCheckTx) +func createTestApp(t *testing.T, isCheckTx bool, r *rand.Rand, n int) (*simapp.SimApp, sdk.Context, []simtypes.Account) { + accounts := simtypes.RandomAccounts(r, n) + // create validator set with single validator + account := accounts[0] + tmPk, err := cryptocodec.ToTmPubKeyInterface(account.PubKey) + require.NoError(t, err) + validator := tmtypes.NewValidator(tmPk, 1) + + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), + } + + app := simapp.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) - app.MintKeeper.SetParams(ctx, minttypes.DefaultParams()) - app.MintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter()) - - return app, ctx -} - -func getTestingAccounts(t *testing.T, r *rand.Rand, app *simapp.SimApp, ctx sdk.Context, n int) []simtypes.Account { - accounts := simtypes.RandomAccounts(r, n) - initAmt := app.StakingKeeper.TokensFromConsensusPower(ctx, 200) initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) + // remove genesis validator account + accs := accounts[1:] + // add coins to the accounts - for _, account := range accounts { + for _, account := range accs { acc := app.AccountKeeper.NewAccountWithAddress(ctx, account.Address) app.AccountKeeper.SetAccount(ctx, acc) require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, account.Address, initCoins)) } - return accounts + app.MintKeeper.SetParams(ctx, minttypes.DefaultParams()) + app.MintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter()) + + return app, ctx, accounts } func getTestingValidator0(t *testing.T, app *simapp.SimApp, ctx sdk.Context, accounts []simtypes.Account) stakingtypes.Validator { diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index 587986870..df6120b04 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -34,6 +34,7 @@ func TestInitGenesis(t *testing.T) { params := app.StakingKeeper.GetParams(ctx) validators := app.StakingKeeper.GetAllValidators(ctx) + require.Len(t, validators, 1) var delegations []types.Delegation pk0, err := codectypes.NewAnyWithValue(PKs[0]) @@ -64,16 +65,20 @@ func TestInitGenesis(t *testing.T) { validators = append(validators, bondedVal1, bondedVal2) log.Printf("%#v", len(validators)) // mint coins in the bonded pool representing the validators coins + i2 := len(validators) - 1 // -1 to exclude genesis validator require.NoError(t, testutil.FundModuleAccount( app.BankKeeper, ctx, types.BondedPoolName, sdk.NewCoins( - sdk.NewCoin(params.BondDenom, valTokens.MulRaw((int64)(len(validators)))), + sdk.NewCoin(params.BondDenom, valTokens.MulRaw((int64)(i2))), ), ), ) + genesisDelegations := app.StakingKeeper.GetAllDelegations(ctx) + delegations = append(delegations, genesisDelegations...) + genesisState := types.NewGenesisState(params, validators, delegations) vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, genesisState) @@ -99,6 +104,8 @@ func TestInitGenesis(t *testing.T) { require.Equal(t, types.Bonded, resVal.Status) abcivals := make([]abci.ValidatorUpdate, len(vals)) + + validators = validators[1:] // remove genesis validator for i, val := range validators { abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)) } @@ -156,6 +163,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { require.True(t, size > 100) app, ctx, addrs := bootstrapGenesisTest(t, 200) + genesisValidators := app.StakingKeeper.GetAllValidators(ctx) params := app.StakingKeeper.GetParams(ctx) delegations := []types.Delegation{} @@ -179,6 +187,8 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { bondedPoolAmt = bondedPoolAmt.Add(tokens) } + validators = append(validators, genesisValidators...) + genesisState := types.NewGenesisState(params, validators, delegations) // mint coins in the bonded pool representing the validators coins @@ -198,6 +208,8 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { abcivals[i] = val.ABCIValidatorUpdate(app.StakingKeeper.PowerReduction(ctx)) } + // remove genesis validator + vals = vals[:100] require.Equal(t, abcivals, vals) } diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 395a32e61..2246345c2 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -19,6 +19,15 @@ import ( func TestDelegation(t *testing.T) { _, app, ctx := createTestInput(t) + // remove genesis validator delegations + delegations := app.StakingKeeper.GetAllDelegations(ctx) + require.Len(t, delegations, 1) + + app.StakingKeeper.RemoveDelegation(ctx, types.Delegation{ + ValidatorAddress: delegations[0].ValidatorAddress, + DelegatorAddress: delegations[0].DelegatorAddress, + }) + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) valAddrs := simapp.ConvertAddrsToValAddrs(addrDels) diff --git a/x/staking/keeper/grpc_query_test.go b/x/staking/keeper/grpc_query_test.go index 1b06f8588..8bb355571 100644 --- a/x/staking/keeper/grpc_query_test.go +++ b/x/staking/keeper/grpc_query_test.go @@ -32,7 +32,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidators() { }, true, - len(vals), + len(vals) + 1, // +1 validator from genesis state false, }, { @@ -41,7 +41,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidators() { req = &types.QueryValidatorsRequest{Status: ""} }, true, - len(vals), + len(vals) + 1, // +1 validator from genesis state false, }, { @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidators() { suite.NoError(err) suite.NotNil(valsResp) suite.Equal(tc.numVals, len(valsResp.Validators)) - suite.Equal(uint64(len(vals)), valsResp.Pagination.Total) + suite.Equal(uint64(len(vals))+1, valsResp.Pagination.Total) // +1 validator from genesis state if tc.hasNext { suite.NotNil(valsResp.Pagination.NextKey) diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index 6e7063a77..437269956 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -86,6 +86,10 @@ func TestTrackHistoricalInfo(t *testing.T) { require.True(t, found) require.Equal(t, hi5, recv) + // genesis validator + genesisVals := app.StakingKeeper.GetAllValidators(ctx) + require.Len(t, genesisVals, 1) + // Set bonded validators in keeper val1 := teststaking.NewValidator(t, addrVals[2], PKs[2]) val1.Status = types.Bonded // when not bonded, consensus power is Zero @@ -98,8 +102,8 @@ func TestTrackHistoricalInfo(t *testing.T) { app.StakingKeeper.SetValidator(ctx, val2) app.StakingKeeper.SetLastValidatorPower(ctx, val2.GetOperator(), 80) - vals := []types.Validator{val1, val2} - IsValSetSorted(vals, app.StakingKeeper.PowerReduction(ctx)) + vals := []types.Validator{val1, genesisVals[0], val2} + require.True(t, IsValSetSorted(vals, app.StakingKeeper.PowerReduction(ctx))) // Set Header for BeginBlock context header := tmproto.Header{ @@ -130,6 +134,10 @@ func TestTrackHistoricalInfo(t *testing.T) { func TestGetAllHistoricalInfo(t *testing.T) { _, app, ctx := createTestInput(t) + // clear historical info + infos := app.StakingKeeper.GetAllHistoricalInfo(ctx) + require.Len(t, infos, 1) + app.StakingKeeper.DeleteHistoricalInfo(ctx, infos[0].Header.Height) addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -153,6 +161,6 @@ func TestGetAllHistoricalInfo(t *testing.T) { app.StakingKeeper.SetHistoricalInfo(ctx, int64(10+i), &hi) } - infos := app.StakingKeeper.GetAllHistoricalInfo(ctx) + infos = app.StakingKeeper.GetAllHistoricalInfo(ctx) require.Equal(t, expHistInfos, infos) } diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 16755d5e1..f50e95a18 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -143,9 +143,9 @@ func TestQueryValidators(t *testing.T) { addrs := simapp.AddTestAddrs(app, ctx, 500, app.StakingKeeper.TokensFromConsensusPower(ctx, 10000)) // Create Validators - amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} - status := []types.BondStatus{types.Bonded, types.Unbonded, types.Unbonding} - var validators [3]types.Validator + amts := []sdk.Int{sdk.NewInt(8), sdk.NewInt(7)} + status := []types.BondStatus{types.Unbonded, types.Unbonding} + var validators [2]types.Validator for i, amt := range amts { validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i]) validators[i], _ = validators[i].AddTokensFromDel(amt) @@ -154,7 +154,6 @@ func TestQueryValidators(t *testing.T) { app.StakingKeeper.SetValidator(ctx, validators[0]) app.StakingKeeper.SetValidator(ctx, validators[1]) - app.StakingKeeper.SetValidator(ctx, validators[2]) // Query Validators queriedValidators := app.StakingKeeper.GetValidators(ctx, params.MaxValidators) @@ -305,6 +304,9 @@ func TestQueryDelegation(t *testing.T) { require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) // Query Delegator Delegations + bz, errRes = cdc.MarshalJSON(queryParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ Path: "/custom/staking/delegatorDelegations", Data: bz, diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 74aa03b49..282f64467 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" + "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -39,6 +40,17 @@ func bootstrapValidatorTest(t testing.TB, power int64, numAddrs int) (*simapp.Si require.NoError(t, testutil.FundModuleAccount(app.BankKeeper, ctx, notBondedPool.GetName(), totalSupply)) + // unbond genesis validator delegations + delegations := app.StakingKeeper.GetAllDelegations(ctx) + require.Len(t, delegations, 1) + delegation := delegations[0] + + _, err := app.StakingKeeper.Undelegate(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr(), delegation.Shares) + require.NoError(t, err) + + // end block to unbond genesis validator + staking.EndBlocker(ctx, app.StakingKeeper) + return app, ctx, addrDels, addrVals } @@ -97,14 +109,12 @@ func TestSetValidator(t *testing.T) { resVals = app.StakingKeeper.GetValidators(ctx, 1) require.Equal(t, 1, len(resVals)) - require.True(ValEq(t, validator, resVals[0])) resVals = app.StakingKeeper.GetValidators(ctx, 10) - require.Equal(t, 1, len(resVals)) - require.True(ValEq(t, validator, resVals[0])) + require.Equal(t, 2, len(resVals)) allVals := app.StakingKeeper.GetAllValidators(ctx) - require.Equal(t, 1, len(allVals)) + require.Equal(t, 2, len(allVals)) } func TestUpdateValidatorByPowerIndex(t *testing.T) { @@ -264,7 +274,7 @@ func TestValidatorBasics(t *testing.T) { require.Zero(t, len(resVals)) resVals = app.StakingKeeper.GetValidators(ctx, 2) - require.Zero(t, len(resVals)) + require.Len(t, resVals, 1) // set and retrieve a record validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) diff --git a/x/staking/module_test.go b/x/staking/module_test.go index a9ebb6d9a..878489363 100644 --- a/x/staking/module_test.go +++ b/x/staking/module_test.go @@ -5,7 +5,10 @@ import ( "github.com/stretchr/testify/require" abcitypes "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/simapp" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -13,16 +16,22 @@ import ( ) func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { - app := simapp.Setup(t, false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + genesisState := simapp.GenesisStateWithSingleValidator(t, app) + stateBytes, err := tmjson.Marshal(genesisState) + require.NoError(t, err) + app.InitChain( abcitypes.RequestInitChain{ - AppStateBytes: []byte("{}"), + AppStateBytes: stateBytes, ChainId: "test-chain-id", }, ) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.BondedPoolName)) require.NotNil(t, acc) diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index ce5ef3dc3..7b0b3411e 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -101,7 +101,7 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k k // ensure the validator doesn't exist already _, found := k.GetValidator(ctx, address) if found { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgCreateValidator, "unable to find validator"), nil, nil + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgCreateValidator, "validator already exists"), nil, nil } denom := k.GetParams(ctx).BondDenom diff --git a/x/staking/simulation/operations_test.go b/x/staking/simulation/operations_test.go index 0f3f2c730..8c1ee9ec1 100644 --- a/x/staking/simulation/operations_test.go +++ b/x/staking/simulation/operations_test.go @@ -1,19 +1,25 @@ package simulation_test import ( + "math/big" "math/rand" "testing" "time" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/simapp" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/staking/simulation" @@ -23,8 +29,9 @@ import ( // TestWeightedOperations tests the weights of the operations. func TestWeightedOperations(t *testing.T) { - - app, ctx := createTestApp(t, false) + s := rand.NewSource(1) + r := rand.New(s) + app, ctx, accs := createTestApp(t, false, r, 3) ctx.WithChainID("test-chain") @@ -35,10 +42,6 @@ func TestWeightedOperations(t *testing.T) { app.BankKeeper, app.StakingKeeper, ) - s := rand.NewSource(1) - r := rand.New(s) - accs := simtypes.RandomAccounts(r, 3) - expected := []struct { weight int opMsgRoute string @@ -64,12 +67,9 @@ func TestWeightedOperations(t *testing.T) { // TestSimulateMsgCreateValidator tests the normal scenario of a valid message of type TypeMsgCreateValidator. // Abonormal scenarios, where the message are created by an errors are not tested here. func TestSimulateMsgCreateValidator(t *testing.T) { - app, ctx := createTestApp(t, false) - - // setup 3 accounts s := rand.NewSource(1) r := rand.New(s) - accounts := getTestingAccounts(t, r, app, ctx, 3) + app, ctx, accounts := createTestApp(t, false, r, 3) // begin a new block app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash}}) @@ -96,14 +96,14 @@ func TestSimulateMsgCreateValidator(t *testing.T) { // TestSimulateMsgEditValidator tests the normal scenario of a valid message of type TypeMsgEditValidator. // Abonormal scenarios, where the message is created by an errors are not tested here. func TestSimulateMsgEditValidator(t *testing.T) { - app, ctx := createTestApp(t, false) + s := rand.NewSource(1) + r := rand.New(s) + app, ctx, accounts := createTestApp(t, false, r, 3) blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // setup 3 accounts - s := rand.NewSource(1) - r := rand.New(s) - accounts := getTestingAccounts(t, r, app, ctx, 3) + // remove genesis validator account + accounts = accounts[1:] // setup accounts[0] as validator _ = getTestingValidator0(t, app, ctx, accounts) @@ -126,28 +126,19 @@ func TestSimulateMsgEditValidator(t *testing.T) { require.Equal(t, "WeLrQKjLxz", msg.Description.Website) require.Equal(t, "rBqDOTtGTO", msg.Description.SecurityContact) require.Equal(t, types.TypeMsgEditValidator, msg.Type()) - require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) + require.Equal(t, "cosmosvaloper1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7epjs3u", msg.ValidatorAddress) require.Len(t, futureOperations, 0) } // TestSimulateMsgDelegate tests the normal scenario of a valid message of type TypeMsgDelegate. // Abonormal scenarios, where the message is created by an errors are not tested here. func TestSimulateMsgDelegate(t *testing.T) { - app, ctx := createTestApp(t, false) - blockTime := time.Now().UTC() - ctx = ctx.WithBlockTime(blockTime) - - // setup 3 accounts s := rand.NewSource(1) r := rand.New(s) - accounts := getTestingAccounts(t, r, app, ctx, 3) + app, ctx, accounts := createTestApp(t, false, r, 3) - // setup accounts[0] as validator - validator0 := getTestingValidator0(t, app, ctx, accounts) - setupValidatorRewards(app, ctx, validator0.GetOperator()) - - // begin a new block - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}}) + blockTime := time.Now().UTC() + ctx = ctx.WithBlockTime(blockTime) // execute operation op := simulation.SimulateMsgDelegate(app.AccountKeeper, app.BankKeeper, app.StakingKeeper) @@ -169,14 +160,15 @@ func TestSimulateMsgDelegate(t *testing.T) { // TestSimulateMsgUndelegate tests the normal scenario of a valid message of type TypeMsgUndelegate. // Abonormal scenarios, where the message is created by an errors are not tested here. func TestSimulateMsgUndelegate(t *testing.T) { - app, ctx := createTestApp(t, false) + s := rand.NewSource(1) + r := rand.New(s) + app, ctx, accounts := createTestApp(t, false, r, 3) + blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // setup 3 accounts - s := rand.NewSource(1) - r := rand.New(s) - accounts := getTestingAccounts(t, r, app, ctx, 3) + // remove genesis validator account + accounts = accounts[1:] // setup accounts[0] as validator validator0 := getTestingValidator0(t, app, ctx, accounts) @@ -203,26 +195,26 @@ func TestSimulateMsgUndelegate(t *testing.T) { types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) require.True(t, operationMsg.OK) - require.Equal(t, "cosmos1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7u4x9a0", msg.DelegatorAddress) + require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) require.Equal(t, "280623462081924937", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgUndelegate, msg.Type()) - require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) + require.Equal(t, "cosmosvaloper1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7epjs3u", msg.ValidatorAddress) require.Len(t, futureOperations, 0) - } // TestSimulateMsgBeginRedelegate tests the normal scenario of a valid message of type TypeMsgBeginRedelegate. // Abonormal scenarios, where the message is created by an errors, are not tested here. func TestSimulateMsgBeginRedelegate(t *testing.T) { - app, ctx := createTestApp(t, false) + s := rand.NewSource(12) + r := rand.New(s) + app, ctx, accounts := createTestApp(t, false, r, 4) + blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // setup 3 accounts - s := rand.NewSource(5) - r := rand.New(s) - accounts := getTestingAccounts(t, r, app, ctx, 3) + // remove genesis validator account + accounts = accounts[1:] // setup accounts[0] as validator0 and accounts[1] as validator1 validator0 := getTestingValidator0(t, app, ctx, accounts) @@ -252,42 +244,56 @@ func TestSimulateMsgBeginRedelegate(t *testing.T) { types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) require.True(t, operationMsg.OK) - require.Equal(t, "cosmos12gwd9jchc69wck8dhstxgwz3z8qs8yv67ps8mu", msg.DelegatorAddress) - require.Equal(t, "489348507626016866", msg.Amount.Amount.String()) + require.Equal(t, "cosmos1092v0qgulpejj8y8hs6dmlw82x9gv8f7jfc7jl", msg.DelegatorAddress) + require.Equal(t, "1883752832348281252", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgBeginRedelegate, msg.Type()) - require.Equal(t, "cosmosvaloper1h6a7shta7jyc72hyznkys683z98z36e0zdk8g9", msg.ValidatorDstAddress) - require.Equal(t, "cosmosvaloper17s94pzwhsn4ah25tec27w70n65h5t2scgxzkv2", msg.ValidatorSrcAddress) + require.Equal(t, "cosmosvaloper1gnkw3uqzflagcqn6ekjwpjanlne928qhruemah", msg.ValidatorDstAddress) + require.Equal(t, "cosmosvaloper1kk653svg7ksj9fmu85x9ygj4jzwlyrgs89nnn2", msg.ValidatorSrcAddress) require.Len(t, futureOperations, 0) - } // returns context and an app with updated mint keeper -func createTestApp(t *testing.T, isCheckTx bool) (*simapp.SimApp, sdk.Context) { - // sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) - app := simapp.Setup(t, isCheckTx) +func createTestApp(t *testing.T, isCheckTx bool, r *rand.Rand, n int) (*simapp.SimApp, sdk.Context, []simtypes.Account) { + sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) + + accounts := simtypes.RandomAccounts(r, n) + // create validator set with single validator + account := accounts[0] + tmPk, err := cryptocodec.ToTmPubKeyInterface(account.PubKey) + require.NoError(t, err) + validator := tmtypes.NewValidator(tmPk, 1) + + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), + } + + app := simapp.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) app.MintKeeper.SetParams(ctx, minttypes.DefaultParams()) app.MintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter()) - return app, ctx -} - -func getTestingAccounts(t *testing.T, r *rand.Rand, app *simapp.SimApp, ctx sdk.Context, n int) []simtypes.Account { - accounts := simtypes.RandomAccounts(r, n) - initAmt := app.StakingKeeper.TokensFromConsensusPower(ctx, 200) initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) + // remove genesis validator account + accs := accounts[1:] + // add coins to the accounts - for _, account := range accounts { + for _, account := range accs { acc := app.AccountKeeper.NewAccountWithAddress(ctx, account.Address) app.AccountKeeper.SetAccount(ctx, acc) require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, account.Address, initCoins)) } - return accounts + return app, ctx, accounts } func getTestingValidator0(t *testing.T, app *simapp.SimApp, ctx sdk.Context, accounts []simtypes.Account) types.Validator {