feat!: Ensure InitGenesis returns with non-empty validator set (#9697)

<!--
The default pull request template is for types feat, fix, or refactor.
For other templates, add one of the following parameters to the url:
- template=docs.md
- template=other.md
-->

## 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).

<!-- Add a description of the changes that this PR introduces and the files that
are the most critical to review. -->

---

### 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)
This commit is contained in:
MD Aleem 2021-10-05 17:32:51 +05:30 committed by GitHub
parent 0b6f3b98a4
commit 9094794478
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 425 additions and 210 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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,
}

View File

@ -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{

View File

@ -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})
},
},
}

View File

@ -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)
}

View File

@ -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)
}
})
}

View File

@ -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,
},
}

View File

@ -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() {

View File

@ -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)
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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))

View File

@ -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]

View File

@ -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)
}

View File

@ -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)

View File

@ -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 {

View File

@ -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,
},
}

View File

@ -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,
)

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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))
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)

View File

@ -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)

View File

@ -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)
}

View File

@ -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,

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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 {