From 0745f288d1f27bd4273dc8dbb381ef21c2803cc3 Mon Sep 17 00:00:00 2001 From: yys Date: Wed, 1 Dec 2021 16:42:32 +0800 Subject: [PATCH] fix: emit ante events even for the failed txs (#10631) * emit ante events even for the failed txs * apply comment * add changelog --- baseapp/abci.go | 8 ++++---- baseapp/baseapp.go | 20 ++++++++++---------- baseapp/baseapp_test.go | 3 ++- baseapp/test_helpers.go | 9 ++++++--- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index b7011932742b..965969918fd9 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -239,9 +239,9 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) } - gInfo, result, err := app.runTx(mode, req.Tx) + gInfo, result, anteEvents, err := app.runTx(mode, req.Tx) if err != nil { - return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) + return sdkerrors.ResponseCheckTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, anteEvents, app.trace) } return abci.ResponseCheckTx{ @@ -271,10 +271,10 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, err := app.runTx(runTxModeDeliver, req.Tx) + gInfo, result, anteEvents, err := app.runTx(runTxModeDeliver, req.Tx) if err != nil { resultStr = "failed" - return sdkerrors.ResponseDeliverTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) + return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, anteEvents, app.trace) } return abci.ResponseDeliverTx{ diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 0ced2a02901f..18b7e4a659bb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -562,7 +562,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context // Note, gas execution info is always returned. A reference to a Result is // returned if the tx does not run out of gas and if all the messages are valid // and execute successfully. An error is returned otherwise. -func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, err error) { +func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is // determined by the GasMeter. We need access to the context to get the gas // meter so we initialize upfront. @@ -574,7 +574,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re // only run the tx if there is block gas remaining if mode == runTxModeDeliver && ctx.BlockGasMeter().IsOutOfGas() { gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()} - return gInfo, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") + return gInfo, nil, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") } defer func() { @@ -609,15 +609,14 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re tx, err := app.txDecoder(txBytes) if err != nil { - return sdk.GasInfo{}, nil, err + return sdk.GasInfo{}, nil, nil, err } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, err + return sdk.GasInfo{}, nil, nil, err } - var events sdk.Events if app.anteHandler != nil { var ( anteCtx sdk.Context @@ -645,16 +644,17 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re ctx = newCtx.WithMultiStore(ms) } - events = ctx.EventManager().Events() + events := ctx.EventManager().Events() // GasMeter expected to be set in AnteHandler gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, err + return gInfo, nil, nil, err } msCache.Write() + anteEvents = events.ToABCIEvents() } // Create a new Context based off of the existing Context with a MultiStore branch @@ -672,13 +672,13 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re msCache.Write() - if len(events) > 0 { + if len(anteEvents) > 0 { // append the events in the order of occurrence - result.Events = append(events.ToABCIEvents(), result.Events...) + result.Events = append(anteEvents, result.Events...) } } - return gInfo, result, err + return gInfo, result, anteEvents, err } // runMsgs iterates through a list of messages and executes them with the provided diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 63c79d1374d5..9b0a4db496b9 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -1543,7 +1543,8 @@ func TestBaseAppAnteHandler(t *testing.T) { require.NoError(t, err) res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) - require.Empty(t, res.Events) + // should emit ante event + require.NotEmpty(t, res.Events) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) ctx = app.getState(runTxModeDeliver).ctx diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index b96c923616ca..4d5ef1b75bc5 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -15,11 +15,13 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk if err != nil { return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - return app.runTx(runTxModeCheck, bz) + gasInfo, result, _, err := app.runTx(runTxModeCheck, bz) + return gasInfo, result, err } func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { - return app.runTx(runTxModeSimulate, txBytes) + gasInfo, result, _, err := app.runTx(runTxModeSimulate, txBytes) + return gasInfo, result, err } func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) { @@ -28,7 +30,8 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s if err != nil { return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - return app.runTx(runTxModeDeliver, bz) + gasInfo, result, _, err := app.runTx(runTxModeDeliver, bz) + return gasInfo, result, err } // Context with current {check, deliver}State of the app used by tests.