github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/abci.go (about) 1 package gov 2 3 import ( 4 "fmt" 5 6 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 7 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/types" 8 ) 9 10 // EndBlocker called every block, process inflation, update validator set. 11 func EndBlocker(ctx sdk.Context, keeper Keeper) { 12 logger := keeper.Logger(ctx) 13 14 // delete inactive proposal from store and its deposits 15 keeper.IterateInactiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal Proposal) bool { 16 keeper.DeleteProposal(ctx, proposal.ProposalID) 17 keeper.DeleteDeposits(ctx, proposal.ProposalID) 18 19 ctx.EventManager().EmitEvent( 20 sdk.NewEvent( 21 types.EventTypeInactiveProposal, 22 sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.ProposalID)), 23 sdk.NewAttribute(types.AttributeKeyProposalResult, types.AttributeValueProposalDropped), 24 ), 25 ) 26 27 logger.Info( 28 fmt.Sprintf("proposal %d (%s) didn't meet minimum deposit of %s (had only %s); deleted", 29 proposal.ProposalID, 30 proposal.GetTitle(), 31 keeper.GetDepositParams(ctx).MinDeposit, 32 proposal.TotalDeposit, 33 ), 34 ) 35 return false 36 }) 37 38 // fetch active proposals whose voting periods have ended (are passed the block time) 39 keeper.IterateActiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal Proposal) bool { 40 var tagValue, logMsg string 41 42 passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal) 43 44 if burnDeposits { 45 keeper.DeleteDeposits(ctx, proposal.ProposalID) 46 } else { 47 keeper.RefundDeposits(ctx, proposal.ProposalID) 48 } 49 50 if passes { 51 handler := keeper.Router().GetRoute(proposal.ProposalRoute()) 52 cacheCtx, writeCache := ctx.CacheContext() 53 54 // The proposal handler may execute state mutating logic depending 55 // on the proposal content. If the handler fails, no state mutation 56 // is written and the error message is logged. 57 err := handler(cacheCtx, proposal.Content) 58 if err == nil { 59 proposal.Status = StatusPassed 60 tagValue = types.AttributeValueProposalPassed 61 logMsg = "passed" 62 63 // The cached context is created with a new EventManager. However, since 64 // the proposal handler execution was successful, we want to track/keep 65 // any events emitted, so we re-emit to "merge" the events into the 66 // original Context's EventManager. 67 ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) 68 69 // write state to the underlying multi-store 70 writeCache() 71 } else { 72 proposal.Status = StatusFailed 73 tagValue = types.AttributeValueProposalFailed 74 logMsg = fmt.Sprintf("passed, but failed on execution: %s", err) 75 } 76 } else { 77 proposal.Status = StatusRejected 78 tagValue = types.AttributeValueProposalRejected 79 logMsg = "rejected" 80 } 81 82 proposal.FinalTallyResult = tallyResults 83 84 keeper.SetProposal(ctx, proposal) 85 keeper.RemoveFromActiveProposalQueue(ctx, proposal.ProposalID, proposal.VotingEndTime) 86 87 logger.Info( 88 fmt.Sprintf( 89 "proposal %d (%s) tallied; result: %s", 90 proposal.ProposalID, proposal.GetTitle(), logMsg, 91 ), 92 ) 93 94 ctx.EventManager().EmitEvent( 95 sdk.NewEvent( 96 types.EventTypeActiveProposal, 97 sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.ProposalID)), 98 sdk.NewAttribute(types.AttributeKeyProposalResult, tagValue), 99 ), 100 ) 101 return false 102 }) 103 }