github.com/Finschia/finschia-sdk@v0.48.1/x/gov/abci.go (about)

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