diff --git a/PENDING.md b/PENDING.md index 8b442d065..a49d8771f 100644 --- a/PENDING.md +++ b/PENDING.md @@ -21,7 +21,7 @@ BREAKING CHANGES * [\#3176](https://github.com/cosmos/cosmos-sdk/issues/3176) `tx/sign` endpoint now expects `BaseReq` fields as nested object. * SDK - * [stake] \#2513 Validator power type from Dec -> Int + * [stake] \#2513 Validator power type from Dec -> Int * [stake] \#3233 key and value now contain duplicate fields to simplify code * [\#3064](https://github.com/cosmos/cosmos-sdk/issues/3064) Sanitize `sdk.Coin` denom. Coins denoms are now case insensitive, i.e. 100fooToken equals to 100FOOTOKEN. @@ -86,12 +86,13 @@ BUG FIXES * Gaia CLI (`gaiacli`) * \#3141 Fix the bug in GetAccount when `len(res) == 0` and `err == nil` - + * Gaia * \#3148 Fix `gaiad export` by adding a boolean to `NewGaiaApp` determining whether or not to load the latest version * \#3181 Correctly reset total accum update height and jailed-validator bond height / unbonding height on export-for-zero-height * [\#3172](https://github.com/cosmos/cosmos-sdk/pull/3172) Fix parsing `gaiad.toml` when it already exists. + * \#3223 Fix unset governance proposal queues when importing state from old chain * [#3187](https://github.com/cosmos/cosmos-sdk/issues/3187) Fix `gaiad export` by resetting each validator's slashing period. diff --git a/x/gov/endblocker_test.go b/x/gov/endblocker_test.go index 622d0968f..d9035e718 100644 --- a/x/gov/endblocker_test.go +++ b/x/gov/endblocker_test.go @@ -13,7 +13,7 @@ import ( ) func TestTickExpiredDepositPeriod(t *testing.T) { - mapp, keeper, _, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) govHandler := NewHandler(keeper) @@ -55,7 +55,7 @@ func TestTickExpiredDepositPeriod(t *testing.T) { } func TestTickMultipleExpiredDepositPeriod(t *testing.T) { - mapp, keeper, _, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) govHandler := NewHandler(keeper) @@ -111,7 +111,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { } func TestTickPassedDepositPeriod(t *testing.T) { - mapp, keeper, _, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) govHandler := NewHandler(keeper) @@ -152,7 +152,7 @@ func TestTickPassedDepositPeriod(t *testing.T) { } func TestTickPassedVotingPeriod(t *testing.T) { - mapp, keeper, _, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) SortAddresses(addrs) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) diff --git a/x/gov/genesis.go b/x/gov/genesis.go index 7a8fab0b6..6430de254 100644 --- a/x/gov/genesis.go +++ b/x/gov/genesis.go @@ -60,6 +60,58 @@ func DefaultGenesisState() GenesisState { } } +// Checks whether 2 GenesisState structs are equivalent. +func (data GenesisState) Equal(data2 GenesisState) bool { + if data.StartingProposalID != data.StartingProposalID || + !data.DepositParams.Equal(data2.DepositParams) || + data.VotingParams != data2.VotingParams || + data.TallyParams != data2.TallyParams { + return false + } + + if len(data.Deposits) != len(data2.Deposits) { + return false + } + for i := range data.Deposits { + deposit1 := data.Deposits[i] + deposit2 := data2.Deposits[i] + if deposit1.ProposalID != deposit2.ProposalID || + !deposit1.Deposit.Equals(deposit2.Deposit) { + return false + } + } + + if len(data.Votes) != len(data2.Votes) { + return false + } + for i := range data.Votes { + vote1 := data.Votes[i] + vote2 := data2.Votes[i] + if vote1.ProposalID != vote2.ProposalID || + !vote1.Vote.Equals(vote2.Vote) { + return false + } + } + + if len(data.Proposals) != len(data2.Proposals) { + return false + } + for i := range data.Proposals { + if data.Proposals[i] != data.Proposals[i] { + return false + } + } + + return true + +} + +// Returns if a GenesisState is empty or has data in it +func (data GenesisState) IsEmpty() bool { + emptyGenState := GenesisState{} + return data.Equal(emptyGenState) +} + // ValidateGenesis TODO https://github.com/cosmos/cosmos-sdk/issues/3007 func ValidateGenesis(data GenesisState) error { threshold := data.TallyParams.Threshold @@ -110,6 +162,12 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setVote(ctx, vote.ProposalID, vote.Vote.Voter, vote.Vote) } for _, proposal := range data.Proposals { + switch proposal.GetStatus() { + case StatusDepositPeriod: + k.InsertInactiveProposalQueue(ctx, proposal.GetDepositEndTime(), proposal.GetProposalID()) + case StatusVotingPeriod: + k.InsertActiveProposalQueue(ctx, proposal.GetVotingEndTime(), proposal.GetProposalID()) + } k.SetProposal(ctx, proposal) } } diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go new file mode 100644 index 000000000..ab3810068 --- /dev/null +++ b/x/gov/genesis_test.go @@ -0,0 +1,54 @@ +package gov + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/tendermint/abci/types" +) + +func TestImportExportQueues(t *testing.T) { + + // Generate mock app and keepers + mapp, keeper, _, addrs, _, _ := getMockApp(t, 2, GenesisState{}, nil) + SortAddresses(addrs) + mapp.BeginBlock(abci.RequestBeginBlock{}) + ctx := mapp.BaseApp.NewContext(false, abci.Header{}) + + // Create two proposals, put the second into the voting period + proposal1 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) + proposalID1 := proposal1.GetProposalID() + + proposal2 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) + proposalID2 := proposal2.GetProposalID() + + _, votingStarted := keeper.AddDeposit(ctx, proposalID2, addrs[0], keeper.GetDepositParams(ctx).MinDeposit) + require.True(t, votingStarted) + + require.True(t, keeper.GetProposal(ctx, proposalID1).GetStatus() == StatusDepositPeriod) + require.True(t, keeper.GetProposal(ctx, proposalID2).GetStatus() == StatusVotingPeriod) + + genAccs := mock.GetAllAccounts(mapp.AccountKeeper, ctx) + + // Export the state and import it into a new Mock App + genState := ExportGenesis(ctx, keeper) + mapp2, keeper2, _, _, _, _ := getMockApp(t, 2, genState, genAccs) + + mapp2.BeginBlock(abci.RequestBeginBlock{}) + ctx2 := mapp2.BaseApp.NewContext(false, abci.Header{}) + + // Jump the time forward past the DepositPeriod and VotingPeriod + ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(keeper2.GetDepositParams(ctx2).MaxDepositPeriod).Add(keeper2.GetVotingParams(ctx2).VotingPeriod)) + + // Make sure that they are still in the DepositPeriod and VotingPeriod respectively + require.True(t, keeper2.GetProposal(ctx2, proposalID1).GetStatus() == StatusDepositPeriod) + require.True(t, keeper2.GetProposal(ctx2, proposalID2).GetStatus() == StatusVotingPeriod) + + // Run the endblocker. Check to make sure that proposal1 is removed from state, and proposal2 is finished VotingPeriod. + EndBlocker(ctx2, keeper2) + + require.Nil(t, keeper2.GetProposal(ctx2, proposalID1)) + require.True(t, keeper2.GetProposal(ctx2, proposalID2).GetStatus() == StatusRejected) +} diff --git a/x/gov/keeper_test.go b/x/gov/keeper_test.go index 83702920e..4fffce43a 100644 --- a/x/gov/keeper_test.go +++ b/x/gov/keeper_test.go @@ -13,7 +13,7 @@ import ( ) func TestGetSetProposal(t *testing.T) { - mapp, keeper, _, _, _, _ := getMockApp(t, 0) + mapp, keeper, _, _, _, _ := getMockApp(t, 0, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) @@ -26,7 +26,7 @@ func TestGetSetProposal(t *testing.T) { } func TestIncrementProposalNumber(t *testing.T) { - mapp, keeper, _, _, _, _ := getMockApp(t, 0) + mapp, keeper, _, _, _, _ := getMockApp(t, 0, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) @@ -41,7 +41,7 @@ func TestIncrementProposalNumber(t *testing.T) { } func TestActivateVotingPeriod(t *testing.T) { - mapp, keeper, _, _, _, _ := getMockApp(t, 0) + mapp, keeper, _, _, _, _ := getMockApp(t, 0, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) @@ -62,7 +62,7 @@ func TestActivateVotingPeriod(t *testing.T) { } func TestDeposits(t *testing.T) { - mapp, keeper, _, addrs, _, _ := getMockApp(t, 2) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 2, GenesisState{}, nil) SortAddresses(addrs) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) @@ -149,7 +149,7 @@ func TestDeposits(t *testing.T) { } func TestVotes(t *testing.T) { - mapp, keeper, _, addrs, _, _ := getMockApp(t, 2) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 2, GenesisState{}, nil) SortAddresses(addrs) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) @@ -205,7 +205,7 @@ func TestVotes(t *testing.T) { } func TestProposalQueues(t *testing.T) { - mapp, keeper, _, _, _, _ := getMockApp(t, 0) + mapp, keeper, _, _, _, _ := getMockApp(t, 0, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) mapp.InitChainer(ctx, abci.RequestInitChain{}) diff --git a/x/gov/params.go b/x/gov/params.go index 01da184d5..20cf2f839 100644 --- a/x/gov/params.go +++ b/x/gov/params.go @@ -12,6 +12,11 @@ type DepositParams struct { MaxDepositPeriod time.Duration `json:"max_deposit_period"` // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months } +// Checks equality of DepositParams +func (dp DepositParams) Equal(dp2 DepositParams) bool { + return dp.MinDeposit.IsEqual(dp2.MinDeposit) && dp.MaxDepositPeriod == dp2.MaxDepositPeriod +} + // Param around Tallying votes in governance type TallyParams struct { Quorum sdk.Dec `json:"quorum"` // Minimum percentage of total stake needed to vote for a result to be considered valid diff --git a/x/gov/querier_test.go b/x/gov/querier_test.go index b64a1b9b2..25e8220b5 100644 --- a/x/gov/querier_test.go +++ b/x/gov/querier_test.go @@ -170,7 +170,7 @@ func getQueriedTally(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sd func testQueryParams(t *testing.T) { cdc := codec.New() - mapp, keeper, _, _, _, _ := getMockApp(t, 1000) + mapp, keeper, _, _, _, _ := getMockApp(t, 1000, GenesisState{}, nil) querier := NewQuerier(keeper) ctx := mapp.NewContext(false, abci.Header{}) @@ -179,7 +179,7 @@ func testQueryParams(t *testing.T) { func testQueries(t *testing.T) { cdc := codec.New() - mapp, keeper, _, addrs, _, _ := getMockApp(t, 1000) + mapp, keeper, _, addrs, _, _ := getMockApp(t, 1000, GenesisState{}, nil) querier := NewQuerier(keeper) handler := NewHandler(keeper) ctx := mapp.NewContext(false, abci.Header{}) diff --git a/x/gov/tally_test.go b/x/gov/tally_test.go index fc5cac910..3c9018304 100644 --- a/x/gov/tally_test.go +++ b/x/gov/tally_test.go @@ -36,7 +36,7 @@ func createValidators(t *testing.T, stakeHandler sdk.Handler, ctx sdk.Context, a } func TestTallyNoOneVotes(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -61,7 +61,7 @@ func TestTallyNoOneVotes(t *testing.T) { } func TestTallyNoQuorum(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -87,7 +87,7 @@ func TestTallyNoQuorum(t *testing.T) { } func TestTallyOnlyValidatorsAllYes(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -117,7 +117,7 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) { } func TestTallyOnlyValidators51No(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -146,7 +146,7 @@ func TestTallyOnlyValidators51No(t *testing.T) { } func TestTallyOnlyValidators51Yes(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -178,7 +178,7 @@ func TestTallyOnlyValidators51Yes(t *testing.T) { } func TestTallyOnlyValidatorsVetoed(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -210,7 +210,7 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) { } func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -242,7 +242,7 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) { } func TestTallyOnlyValidatorsAbstainFails(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -274,7 +274,7 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) { } func TestTallyOnlyValidatorsNonVoter(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -304,7 +304,7 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) { } func TestTallyDelgatorOverride(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -341,7 +341,7 @@ func TestTallyDelgatorOverride(t *testing.T) { } func TestTallyDelgatorInherit(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -376,7 +376,7 @@ func TestTallyDelgatorInherit(t *testing.T) { } func TestTallyDelgatorMultipleOverride(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -415,7 +415,7 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) { } func TestTallyDelgatorMultipleInherit(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) @@ -462,7 +462,7 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) { } func TestTallyJailedValidator(t *testing.T) { - mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10, GenesisState{}, nil) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) stakeHandler := stake.NewHandler(sk) diff --git a/x/gov/test_common.go b/x/gov/test_common.go index ce326aa6b..8e91c416f 100644 --- a/x/gov/test_common.go +++ b/x/gov/test_common.go @@ -12,6 +12,7 @@ import ( "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/cosmos/cosmos-sdk/x/stake" @@ -19,8 +20,8 @@ import ( ) // initialize the mock application for this module -func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper, []sdk.AccAddress, []crypto.PubKey, []crypto.PrivKey) { - mapp := mock.NewApp() +func getMockApp(t *testing.T, numGenAccs int, genState GenesisState, genAccs []auth.Account) (mapp *mock.App, keeper Keeper, sk stake.Keeper, addrs []sdk.AccAddress, pubKeys []crypto.PubKey, privKeys []crypto.PrivKey) { + mapp = mock.NewApp() stake.RegisterCodec(mapp.Cdc) RegisterCodec(mapp.Cdc) @@ -31,18 +32,20 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper, pk := mapp.ParamsKeeper ck := bank.NewBaseKeeper(mapp.AccountKeeper) - sk := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace) - keeper := NewKeeper(mapp.Cdc, keyGov, pk, pk.Subspace("testgov"), ck, sk, DefaultCodespace) + sk = stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace) + keeper = NewKeeper(mapp.Cdc, keyGov, pk, pk.Subspace("testgov"), ck, sk, DefaultCodespace) mapp.Router().AddRoute(RouterKey, NewHandler(keeper)) mapp.QueryRouter().AddRoute(QuerierRoute, NewQuerier(keeper)) mapp.SetEndBlocker(getEndBlocker(keeper)) - mapp.SetInitChainer(getInitChainer(mapp, keeper, sk)) + mapp.SetInitChainer(getInitChainer(mapp, keeper, sk, genState)) require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keyGov)) - genAccs, addrs, pubKeys, privKeys := mock.CreateGenAccounts(numGenAccs, sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 42)}) + if genAccs == nil || len(genAccs) == 0 { + genAccs, addrs, pubKeys, privKeys = mock.CreateGenAccounts(numGenAccs, sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 42)}) + } mock.SetGenesis(mapp, genAccs) @@ -60,7 +63,7 @@ func getEndBlocker(keeper Keeper) sdk.EndBlocker { } // gov and stake initchainer -func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk.InitChainer { +func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper, genState GenesisState) sdk.InitChainer { return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { mapp.InitChainer(ctx, req) @@ -71,7 +74,11 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk if err != nil { panic(err) } - InitGenesis(ctx, keeper, DefaultGenesisState()) + if genState.IsEmpty() { + InitGenesis(ctx, keeper, DefaultGenesisState()) + } else { + InitGenesis(ctx, keeper, genState) + } return abci.ResponseInitChain{ Validators: validators, }