From e783a4122115666842320b0eec325f089215f7e9 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 27 Mar 2023 18:59:14 +0200 Subject: [PATCH] feat: carry `x/gov` proposal execution error message (#15554) Co-authored-by: Aleksandr Bezobchuk --- CHANGELOG.md | 1 + x/gov/abci.go | 28 +++++++++++++++++++--------- x/gov/abci_test.go | 6 ++++++ x/gov/types/events.go | 2 +- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6fec52e63c8..63d54ecae842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (x/gov) [#15554](https://github.com/cosmos/cosmos-sdk/pull/15554) Add proposal result log in `active_proposal` event. When a proposal passes but fails to execute, the proposal result is logged in the `active_proposal` event. * (mempool) [#15328](https://github.com/cosmos/cosmos-sdk/pull/15328) Improve the `PriorityNonceMempool` * Support generic transaction prioritization, instead of `ctx.Priority()` * Improve construction through the use of a single `PriorityNonceMempoolConfig` instead of option functions diff --git a/x/gov/abci.go b/x/gov/abci.go index 7ea7a748feee..934e770545a0 100644 --- a/x/gov/abci.go +++ b/x/gov/abci.go @@ -85,18 +85,25 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { // message is logged. cacheCtx, writeCache := ctx.CacheContext() messages, err := proposal.GetMsgs() - if err == nil { - for idx, msg = range messages { - handler := keeper.Router().Handler(msg) + if err != nil { + proposal.Status = v1.StatusFailed + tagValue = types.AttributeValueProposalFailed + logMsg = fmt.Sprintf("passed proposal (%v) failed to execute; msgs: %s", proposal, err) - var res *sdk.Result - res, err = handler(cacheCtx, msg) - if err != nil { - break - } + break + } - events = append(events, res.GetEvents()...) + // execute all messages + for idx, msg = range messages { + handler := keeper.Router().Handler(msg) + + var res *sdk.Result + res, err = handler(cacheCtx, msg) + if err != nil { + break } + + events = append(events, res.GetEvents()...) } // `err == nil` when all handlers passed. @@ -146,6 +153,7 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { logger.Info( "proposal tallied", "proposal", proposal.Id, + "status", proposal.Status.String(), "expedited", proposal.Expedited, "title", proposal.Title, "results", logMsg, @@ -156,8 +164,10 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { types.EventTypeActiveProposal, sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.Id)), sdk.NewAttribute(types.AttributeKeyProposalResult, tagValue), + sdk.NewAttribute(types.AttributeKeyProposalLog, logMsg), ), ) + return false }) } diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index 93df9fc4809d..f5850027e542 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -440,6 +440,12 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) { // validate that the proposal fails/has been rejected gov.EndBlocker(ctx, suite.GovKeeper) + // check proposal events + events := ctx.EventManager().Events() + attr, eventOk := events.GetAttributes(types.AttributeKeyProposalLog) + require.True(t, eventOk) + require.Contains(t, attr[0].Value, "failed on execution") + proposal, ok := suite.GovKeeper.GetProposal(ctx, proposal.Id) require.True(t, ok) require.Equal(t, v1.StatusFailed, proposal.Status) diff --git a/x/gov/types/events.go b/x/gov/types/events.go index 179f51e33a83..c7f895234f0b 100644 --- a/x/gov/types/events.go +++ b/x/gov/types/events.go @@ -7,7 +7,6 @@ const ( EventTypeProposalVote = "proposal_vote" EventTypeInactiveProposal = "inactive_proposal" EventTypeActiveProposal = "active_proposal" - EventTypeSignalProposal = "signal_proposal" EventTypeCancelProposal = "cancel_proposal" AttributeKeyProposalResult = "proposal_result" @@ -15,6 +14,7 @@ const ( AttributeKeyProposalID = "proposal_id" AttributeKeyProposalMessages = "proposal_messages" // Msg type_urls in the proposal AttributeKeyVotingPeriodStart = "voting_period_start" + AttributeKeyProposalLog = "proposal_log" // log of proposal execution AttributeValueProposalDropped = "proposal_dropped" // didn't meet min deposit AttributeValueProposalPassed = "proposal_passed" // met vote quorum AttributeValueProposalRejected = "proposal_rejected" // didn't meet vote quorum