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