github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/abci_test.go (about)

     1  package gov
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/require"
     9  
    10  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    11  
    12  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    13  	keep "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/keeper"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking"
    15  )
    16  
    17  func TestTickExpiredDepositPeriod(t *testing.T) {
    18  	input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
    19  
    20  	header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
    21  	input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
    22  
    23  	ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
    24  	govHandler := NewHandler(input.keeper)
    25  
    26  	inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    27  	require.False(t, inactiveQueue.Valid())
    28  	inactiveQueue.Close()
    29  
    30  	newProposalMsg := NewMsgSubmitProposal(
    31  		ContentFromProposalType("test", "test", ProposalTypeText),
    32  		sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
    33  		input.addrs[0],
    34  	)
    35  
    36  	res, err := govHandler(ctx, newProposalMsg)
    37  	require.NoError(t, err)
    38  	require.NotNil(t, res)
    39  
    40  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    41  	require.False(t, inactiveQueue.Valid())
    42  	inactiveQueue.Close()
    43  
    44  	newHeader := ctx.BlockHeader()
    45  	newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
    46  	ctx.SetBlockHeader(newHeader)
    47  
    48  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    49  	require.False(t, inactiveQueue.Valid())
    50  	inactiveQueue.Close()
    51  
    52  	newHeader = ctx.BlockHeader()
    53  	newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod)
    54  	ctx.SetBlockHeader(newHeader)
    55  
    56  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    57  	require.True(t, inactiveQueue.Valid())
    58  	inactiveQueue.Close()
    59  
    60  	EndBlocker(ctx, input.keeper)
    61  
    62  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    63  	require.False(t, inactiveQueue.Valid())
    64  	inactiveQueue.Close()
    65  }
    66  
    67  func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
    68  	input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
    69  
    70  	header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
    71  	input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
    72  
    73  	ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
    74  	govHandler := NewHandler(input.keeper)
    75  
    76  	inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    77  	require.False(t, inactiveQueue.Valid())
    78  	inactiveQueue.Close()
    79  
    80  	newProposalMsg := NewMsgSubmitProposal(
    81  		ContentFromProposalType("test", "test", ProposalTypeText),
    82  		sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
    83  		input.addrs[0],
    84  	)
    85  
    86  	res, err := govHandler(ctx, newProposalMsg)
    87  	require.NoError(t, err)
    88  	require.NotNil(t, res)
    89  
    90  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    91  	require.False(t, inactiveQueue.Valid())
    92  	inactiveQueue.Close()
    93  
    94  	newHeader := ctx.BlockHeader()
    95  	newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(2) * time.Second)
    96  	ctx.SetBlockHeader(newHeader)
    97  
    98  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
    99  	require.False(t, inactiveQueue.Valid())
   100  	inactiveQueue.Close()
   101  
   102  	newProposalMsg2 := NewMsgSubmitProposal(
   103  		ContentFromProposalType("test2", "test2", ProposalTypeText),
   104  		sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
   105  		input.addrs[0],
   106  	)
   107  
   108  	res, err = govHandler(ctx, newProposalMsg2)
   109  	require.NoError(t, err)
   110  	require.NotNil(t, res)
   111  
   112  	newHeader = ctx.BlockHeader()
   113  	newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
   114  	ctx.SetBlockHeader(newHeader)
   115  
   116  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   117  	require.True(t, inactiveQueue.Valid())
   118  	inactiveQueue.Close()
   119  	EndBlocker(ctx, input.keeper)
   120  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   121  	require.False(t, inactiveQueue.Valid())
   122  	inactiveQueue.Close()
   123  
   124  	newHeader = ctx.BlockHeader()
   125  	newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(5) * time.Second)
   126  	ctx.SetBlockHeader(newHeader)
   127  
   128  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   129  	require.True(t, inactiveQueue.Valid())
   130  	inactiveQueue.Close()
   131  	EndBlocker(ctx, input.keeper)
   132  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   133  	require.False(t, inactiveQueue.Valid())
   134  	inactiveQueue.Close()
   135  }
   136  
   137  func TestTickPassedDepositPeriod(t *testing.T) {
   138  	input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
   139  
   140  	header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
   141  	input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
   142  
   143  	ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
   144  	govHandler := NewHandler(input.keeper)
   145  
   146  	inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   147  	require.False(t, inactiveQueue.Valid())
   148  	inactiveQueue.Close()
   149  	activeQueue := input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   150  	require.False(t, activeQueue.Valid())
   151  	activeQueue.Close()
   152  
   153  	newProposalMsg := NewMsgSubmitProposal(
   154  		ContentFromProposalType("test2", "test2", ProposalTypeText),
   155  		sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
   156  		input.addrs[0],
   157  	)
   158  
   159  	res, err := govHandler(ctx, newProposalMsg)
   160  	require.NoError(t, err)
   161  	require.NotNil(t, res)
   162  
   163  	proposalID := GetProposalIDFromBytes(res.Data)
   164  
   165  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   166  	require.False(t, inactiveQueue.Valid())
   167  	inactiveQueue.Close()
   168  
   169  	newHeader := ctx.BlockHeader()
   170  	newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
   171  	ctx.SetBlockHeader(newHeader)
   172  
   173  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   174  	require.False(t, inactiveQueue.Valid())
   175  	inactiveQueue.Close()
   176  
   177  	newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
   178  
   179  	res, err = govHandler(ctx, newDepositMsg)
   180  	require.NoError(t, err)
   181  	require.NotNil(t, res)
   182  
   183  	activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   184  	require.False(t, activeQueue.Valid())
   185  	activeQueue.Close()
   186  }
   187  
   188  func TestTickPassedVotingPeriod(t *testing.T) {
   189  	input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
   190  	SortAddresses(input.addrs)
   191  
   192  	header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
   193  	input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
   194  
   195  	ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
   196  	govHandler := NewHandler(input.keeper)
   197  
   198  	inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   199  	require.False(t, inactiveQueue.Valid())
   200  	inactiveQueue.Close()
   201  	activeQueue := input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   202  	require.False(t, activeQueue.Valid())
   203  	activeQueue.Close()
   204  
   205  	proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5))}
   206  	newProposalMsg := NewMsgSubmitProposal(keep.TestProposal, proposalCoins, input.addrs[0])
   207  
   208  	res, err := govHandler(ctx, newProposalMsg)
   209  	require.NoError(t, err)
   210  	require.NotNil(t, res)
   211  
   212  	proposalID := GetProposalIDFromBytes(res.Data)
   213  
   214  	newHeader := ctx.BlockHeader()
   215  	newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
   216  	ctx.SetBlockHeader(newHeader)
   217  
   218  	newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, proposalCoins)
   219  
   220  	res, err = govHandler(ctx, newDepositMsg)
   221  	require.NoError(t, err)
   222  	require.NotNil(t, res)
   223  
   224  	newHeader = ctx.BlockHeader()
   225  	newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
   226  	ctx.SetBlockHeader(newHeader)
   227  
   228  	inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   229  	require.False(t, inactiveQueue.Valid())
   230  	inactiveQueue.Close()
   231  
   232  	activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   233  	require.True(t, activeQueue.Valid())
   234  
   235  	activeProposalID := GetProposalIDFromBytes(activeQueue.Value())
   236  	proposal, ok := input.keeper.GetProposal(ctx, activeProposalID)
   237  	require.True(t, ok)
   238  	require.Equal(t, StatusVotingPeriod, proposal.Status)
   239  
   240  	activeQueue.Close()
   241  
   242  	EndBlocker(ctx, input.keeper)
   243  
   244  	activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
   245  	require.False(t, activeQueue.Valid())
   246  	activeQueue.Close()
   247  }
   248  
   249  func TestProposalPassedEndblocker(t *testing.T) {
   250  	input := getMockApp(t, 1, GenesisState{}, nil, ProposalHandler)
   251  	SortAddresses(input.addrs)
   252  
   253  	handler := NewHandler(input.keeper)
   254  	stakingHandler := staking.NewHandler(input.sk)
   255  
   256  	header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
   257  	input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
   258  	ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
   259  
   260  	valAddr := sdk.ValAddress(input.addrs[0])
   261  
   262  	createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
   263  	staking.EndBlocker(ctx, input.sk)
   264  
   265  	macc := input.keeper.GetGovernanceAccount(ctx)
   266  	require.NotNil(t, macc)
   267  	initialModuleAccCoins := macc.GetCoins()
   268  
   269  	proposal, err := input.keeper.SubmitProposal(ctx, keep.TestProposal)
   270  	require.NoError(t, err)
   271  
   272  	proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))}
   273  	newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
   274  
   275  	res, err := handler(ctx, newDepositMsg)
   276  	require.NoError(t, err)
   277  	require.NotNil(t, res)
   278  
   279  	macc = input.keeper.GetGovernanceAccount(ctx)
   280  	require.NotNil(t, macc)
   281  	moduleAccCoins := macc.GetCoins()
   282  
   283  	deposits := initialModuleAccCoins.Add(proposal.TotalDeposit...).Add(proposalCoins...)
   284  	require.True(t, moduleAccCoins.IsEqual(deposits))
   285  
   286  	err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
   287  	require.NoError(t, err)
   288  
   289  	newHeader := ctx.BlockHeader()
   290  	newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
   291  	ctx.SetBlockHeader(newHeader)
   292  
   293  	EndBlocker(ctx, input.keeper)
   294  
   295  	macc = input.keeper.GetGovernanceAccount(ctx)
   296  	require.NotNil(t, macc)
   297  	require.True(t, macc.GetCoins().IsEqual(initialModuleAccCoins))
   298  }
   299  
   300  func TestEndBlockerProposalHandlerFailed(t *testing.T) {
   301  	// hijack the router to one that will fail in a proposal's handler
   302  	input := getMockApp(t, 1, GenesisState{}, nil, badProposalHandler)
   303  	SortAddresses(input.addrs)
   304  
   305  	handler := NewHandler(input.keeper)
   306  	stakingHandler := staking.NewHandler(input.sk)
   307  
   308  	header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
   309  	input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
   310  	ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
   311  
   312  	valAddr := sdk.ValAddress(input.addrs[0])
   313  
   314  	createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
   315  	staking.EndBlocker(ctx, input.sk)
   316  
   317  	// Create a proposal where the handler will pass for the test proposal
   318  	// because the value of contextKeyBadProposal is true.
   319  	ctx.SetContext(context.WithValue(ctx.Context(), contextKeyBadProposal, true))
   320  	proposal, err := input.keeper.SubmitProposal(ctx, keep.TestProposal)
   321  	require.NoError(t, err)
   322  
   323  	proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)))
   324  	newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
   325  
   326  	res, err := handler(ctx, newDepositMsg)
   327  	require.NoError(t, err)
   328  	require.NotNil(t, res)
   329  
   330  	err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
   331  	require.NoError(t, err)
   332  
   333  	newHeader := ctx.BlockHeader()
   334  	newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
   335  	ctx.SetBlockHeader(newHeader)
   336  
   337  	// Set the contextKeyBadProposal value to false so that the handler will fail
   338  	// during the processing of the proposal in the EndBlocker.
   339  	ctx.SetContext(context.WithValue(ctx.Context(), contextKeyBadProposal, false))
   340  
   341  	// validate that the proposal fails/has been rejected
   342  	EndBlocker(ctx, input.keeper)
   343  }