cosmos-sdk/x/gov/abci_test.go

342 lines
12 KiB
Go

package gov
import (
"testing"
"time"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
keep "github.com/cosmos/cosmos-sdk/x/gov/keeper"
"github.com/cosmos/cosmos-sdk/x/staking"
)
func TestTickExpiredDepositPeriod(t *testing.T) {
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
govHandler := NewHandler(input.keeper)
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newProposalMsg := NewMsgSubmitProposal(
ContentFromProposalType("test", "test", ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
input.addrs[0],
)
res, err := govHandler(ctx, newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
inactiveQueue = input.keeper.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 = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, inactiveQueue.Valid())
inactiveQueue.Close()
EndBlocker(ctx, input.keeper)
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
}
func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
govHandler := NewHandler(input.keeper)
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newProposalMsg := NewMsgSubmitProposal(
ContentFromProposalType("test", "test", ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
input.addrs[0],
)
res, err := govHandler(ctx, newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
inactiveQueue = input.keeper.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 = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newProposalMsg2 := NewMsgSubmitProposal(
ContentFromProposalType("test2", "test2", ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
input.addrs[0],
)
res, err = govHandler(ctx, newProposalMsg2)
require.NoError(t, err)
require.NotNil(t, res)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, inactiveQueue.Valid())
inactiveQueue.Close()
EndBlocker(ctx, input.keeper)
inactiveQueue = input.keeper.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 = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, inactiveQueue.Valid())
inactiveQueue.Close()
EndBlocker(ctx, input.keeper)
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
}
func TestTickPassedDepositPeriod(t *testing.T) {
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
govHandler := NewHandler(input.keeper)
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
activeQueue := input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
newProposalMsg := NewMsgSubmitProposal(
ContentFromProposalType("test2", "test2", ProposalTypeText),
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
input.addrs[0],
)
res, err := govHandler(ctx, newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
proposalID := GetProposalIDFromBytes(res.Data)
inactiveQueue = input.keeper.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 = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
res, err = govHandler(ctx, newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
}
func TestTickPassedVotingPeriod(t *testing.T) {
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
SortAddresses(input.addrs)
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
govHandler := NewHandler(input.keeper)
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
activeQueue := input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5))}
newProposalMsg := NewMsgSubmitProposal(keep.TestProposal, proposalCoins, input.addrs[0])
res, err := govHandler(ctx, newProposalMsg)
require.NoError(t, err)
require.NotNil(t, res)
proposalID := GetProposalIDFromBytes(res.Data)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, proposalCoins)
res, err = govHandler(ctx, newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, inactiveQueue.Valid())
inactiveQueue.Close()
activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.True(t, activeQueue.Valid())
activeProposalID := GetProposalIDFromBytes(activeQueue.Value())
proposal, ok := input.keeper.GetProposal(ctx, activeProposalID)
require.True(t, ok)
require.Equal(t, StatusVotingPeriod, proposal.Status)
activeQueue.Close()
EndBlocker(ctx, input.keeper)
activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
require.False(t, activeQueue.Valid())
activeQueue.Close()
}
func TestProposalPassedEndblocker(t *testing.T) {
input := getMockApp(t, 1, GenesisState{}, nil, ProposalHandler)
SortAddresses(input.addrs)
handler := NewHandler(input.keeper)
stakingHandler := staking.NewHandler(input.sk)
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
valAddr := sdk.ValAddress(input.addrs[0])
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
staking.EndBlocker(ctx, input.sk)
macc := input.keeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
initialModuleAccCoins := input.bk.GetAllBalances(ctx, macc.GetAddress())
proposal, err := input.keeper.SubmitProposal(ctx, keep.TestProposal)
require.NoError(t, err)
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))}
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
res, err := handler(ctx, newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
macc = input.keeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
moduleAccCoins := input.bk.GetAllBalances(ctx, macc.GetAddress())
deposits := initialModuleAccCoins.Add(proposal.TotalDeposit...).Add(proposalCoins...)
require.True(t, moduleAccCoins.IsEqual(deposits))
err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
require.NoError(t, err)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
EndBlocker(ctx, input.keeper)
macc = input.keeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
require.True(t, input.bk.GetAllBalances(ctx, macc.GetAddress()).IsEqual(initialModuleAccCoins))
}
func TestEndBlockerProposalHandlerFailed(t *testing.T) {
// hijack the router to one that will fail in a proposal's handler
input := getMockApp(t, 1, GenesisState{}, nil, badProposalHandler)
SortAddresses(input.addrs)
handler := NewHandler(input.keeper)
stakingHandler := staking.NewHandler(input.sk)
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
valAddr := sdk.ValAddress(input.addrs[0])
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
staking.EndBlocker(ctx, input.sk)
// 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 := input.keeper.SubmitProposal(ctx, keep.TestProposal)
require.NoError(t, err)
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)))
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
res, err := handler(ctx, newDepositMsg)
require.NoError(t, err)
require.NotNil(t, res)
err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
require.NoError(t, err)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.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
EndBlocker(ctx, input.keeper)
}