cosmos-sdk/x/gov/abci_test.go

383 lines
14 KiB
Go

package gov_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
"github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestTickExpiredDepositPeriod(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newProposalMsg, err := v1beta1.NewMsgSubmitProposal(
v1beta1.ContentFromProposalType("test", "test", v1beta1.ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0],
)
require.NoError(t, err)
res, err := govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, inactiveQueue.Valid())
inactiveQueue.Close()
gov.EndBlocker(ctx, app.GovKeeper)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
}
func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newProposalMsg, err := v1beta1.NewMsgSubmitProposal(
v1beta1.ContentFromProposalType("test", "test", v1beta1.ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0],
)
require.NoError(t, err)
res, err := govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(2) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newProposalMsg2, err := v1beta1.NewMsgSubmitProposal(
v1beta1.ContentFromProposalType("test2", "test2", v1beta1.ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0],
)
require.NoError(t, err)
res, err = govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg2)
require.NoError(t, err)
require.NotNil(t, res)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, inactiveQueue.Valid())
inactiveQueue.Close()
gov.EndBlocker(ctx, app.GovKeeper)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(5) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, inactiveQueue.Valid())
inactiveQueue.Close()
gov.EndBlocker(ctx, app.GovKeeper)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
}
func TestTickPassedDepositPeriod(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
activeQueue := app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
newProposalMsg, err := v1beta1.NewMsgSubmitProposal(
v1beta1.ContentFromProposalType("test2", "test2", v1beta1.ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0],
)
require.NoError(t, err)
res, err := govMsgSvr.SubmitProposal(sdk.WrapSDKContext(ctx), newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
proposalID := res.ProposalId
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newDepositMsg := v1beta1.NewMsgDeposit(addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
res1, err := govMsgSvr.Deposit(sdk.WrapSDKContext(ctx), newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res1)
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
}
func TestTickPassedVotingPeriod(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
SortAddresses(addrs)
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
activeQueue := app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 5))}
newProposalMsg, err := v1beta1.NewMsgSubmitProposal(TestProposal, proposalCoins, addrs[0])
require.NoError(t, err)
wrapCtx := sdk.WrapSDKContext(ctx)
res, err := govMsgSvr.SubmitProposal(wrapCtx, newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
proposalID := res.ProposalId
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
newDepositMsg := v1beta1.NewMsgDeposit(addrs[1], proposalID, proposalCoins)
res1, err := govMsgSvr.Deposit(wrapCtx, newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res1)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, activeQueue.Valid())
activeProposalID := types.GetProposalIDFromBytes(activeQueue.Value())
proposal, ok := app.GovKeeper.GetProposal(ctx, activeProposalID)
require.True(t, ok)
require.Equal(t, v1beta1.StatusVotingPeriod, proposal.Status)
activeQueue.Close()
gov.EndBlocker(ctx, app.GovKeeper)
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
}
func TestProposalPassedEndblocker(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
SortAddresses(addrs)
govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
stakingMsgSvr := stakingkeeper.NewMsgServerImpl(app.StakingKeeper)
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
valAddr := sdk.ValAddress(addrs[0])
createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
staking.EndBlocker(ctx, app.StakingKeeper)
macc := app.GovKeeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
initialModuleAccCoins := app.BankKeeper.GetAllBalances(ctx, macc.GetAddress())
proposal, err := app.GovKeeper.SubmitProposal(ctx, TestProposal)
require.NoError(t, err)
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10))}
newDepositMsg := v1beta1.NewMsgDeposit(addrs[0], proposal.ProposalId, proposalCoins)
res, err := govMsgSvr.Deposit(sdk.WrapSDKContext(ctx), newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
macc = app.GovKeeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
moduleAccCoins := app.BankKeeper.GetAllBalances(ctx, macc.GetAddress())
deposits := initialModuleAccCoins.Add(proposal.TotalDeposit...).Add(proposalCoins...)
require.True(t, moduleAccCoins.IsEqual(deposits))
err = app.GovKeeper.AddVote(ctx, proposal.ProposalId, addrs[0], v1beta1.NewNonSplitVoteOption(v1beta1.OptionYes))
require.NoError(t, err)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
gov.EndBlocker(ctx, app.GovKeeper)
macc = app.GovKeeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
require.True(t, app.BankKeeper.GetAllBalances(ctx, macc.GetAddress()).IsEqual(initialModuleAccCoins))
}
func TestEndBlockerProposalHandlerFailed(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrs(app, ctx, 1, valTokens)
SortAddresses(addrs)
stakingMsgSvr := stakingkeeper.NewMsgServerImpl(app.StakingKeeper)
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
valAddr := sdk.ValAddress(addrs[0])
createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
staking.EndBlocker(ctx, app.StakingKeeper)
// Create a proposal where the handler will pass for the test proposal
// because the value of contextKeyBadProposal is true.
ctx = ctx.WithValue(contextKeyBadProposal, true)
proposal, err := app.GovKeeper.SubmitProposal(ctx, TestProposal)
require.NoError(t, err)
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10)))
newDepositMsg := v1beta1.NewMsgDeposit(addrs[0], proposal.ProposalId, proposalCoins)
govMsgSvr := keeper.NewMsgServerImpl(app.GovKeeper)
res, err := govMsgSvr.Deposit(sdk.WrapSDKContext(ctx), newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
err = app.GovKeeper.AddVote(ctx, proposal.ProposalId, addrs[0], v1beta1.NewNonSplitVoteOption(v1beta1.OptionYes))
require.NoError(t, err)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
// Set the contextKeyBadProposal value to false so that the handler will fail
// during the processing of the proposal in the EndBlocker.
ctx = ctx.WithValue(contextKeyBadProposal, false)
// validate that the proposal fails/has been rejected
gov.EndBlocker(ctx, app.GovKeeper)
}
func createValidators(t *testing.T, stakingMsgSvr stakingtypes.MsgServer, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")
for i := 0; i < len(addrs); i++ {
valTokens := sdk.TokensFromConsensusPower(powerAmt[i], sdk.DefaultPowerReduction)
valCreateMsg, err := stakingtypes.NewMsgCreateValidator(
addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
TestDescription, TestCommissionRates, sdk.OneInt(),
)
require.NoError(t, err)
res, err := stakingMsgSvr.CreateValidator(sdk.WrapSDKContext(ctx), valCreateMsg)
require.NoError(t, err)
require.NotNil(t, res)
}
}