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