diff --git a/baseapp/abci.go b/baseapp/abci.go index 001a81470..4f7d36913 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -227,7 +227,7 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - gInfo, result, _, priority, pendingTxChecker, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) + gInfo, result, _, priority, pendingTxChecker, expireTxHandler, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) if err != nil { res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err @@ -242,6 +242,7 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc res.IsPendingTransaction = true res.Checker = pendingTxChecker } + res.ExpireTxHandler = expireTxHandler return res, nil } @@ -271,7 +272,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) + gInfo, result, anteEvents, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index d5fc42d82..66c8f35f1 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -828,6 +828,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ anteEvents []abci.Event, priority int64, pendingTxChecker abci.PendingTxChecker, + expireHandler abci.ExpireTxHandler, err error, ) { defer telemetry.MeasureThroughputSinceWithLabels( @@ -863,7 +864,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // only run the tx if there is block gas remaining if mode == runTxModeDeliver && ctx.BlockGasMeter().IsOutOfGas() { - return gInfo, nil, nil, -1, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") + return gInfo, nil, nil, -1, nil, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") } defer func() { @@ -900,13 +901,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ } if tx == nil { - return sdk.GasInfo{}, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") + return sdk.GasInfo{}, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, nil, 0, nil, err + return sdk.GasInfo{}, nil, nil, 0, nil, nil, err } if app.anteHandler != nil { @@ -948,7 +949,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // GasMeter expected to be set in AnteHandler gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, nil, 0, nil, err + return gInfo, nil, nil, 0, nil, nil, err } // Dont need to validate in checkTx mode @@ -963,12 +964,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ op.EmitValidationFailMetrics() } errMessage := fmt.Sprintf("Invalid Concurrent Execution antehandler missing %d access operations", len(missingAccessOps)) - return gInfo, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) + return gInfo, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) } } priority = ctx.Priority() pendingTxChecker = ctx.PendingTxChecker() + expireHandler = ctx.ExpireTxHandler() msCache.Write() anteEvents = events.ToABCIEvents() anteSpan.End() @@ -998,7 +1000,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ if ctx.CheckTxCallback() != nil { ctx.CheckTxCallback()(err) } - return gInfo, result, anteEvents, priority, pendingTxChecker, err + return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, err } // runMsgs iterates through a list of messages and executes them with the provided diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index 7652b078e..1cc05327a 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -17,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) - gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) + gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected checkTx events to be empty") } @@ -31,7 +31,7 @@ func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { if err != nil { return sdk.GasInfo{}, nil, err } - gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) + gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected simulate events to be empty") } @@ -49,7 +49,7 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s if err != nil { return sdk.GasInfo{}, &sdk.Result{}, err } - gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) + gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) return gasInfo, result, err } diff --git a/types/context.go b/types/context.go index 527a2f210..6382df0d7 100644 --- a/types/context.go +++ b/types/context.go @@ -42,6 +42,7 @@ type Context struct { priority int64 // The tx priority, only relevant in CheckTx pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx checkTxCallback func(error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs` + expireTxHandler func() // callback that the mempool invokes when a tx is expired txBlockingChannels acltypes.MessageAccessOpsChannelMapping txCompletionChannels acltypes.MessageAccessOpsChannelMapping @@ -118,6 +119,10 @@ func (c Context) Priority() int64 { return c.priority } +func (c Context) ExpireTxHandler() abci.ExpireTxHandler { + return c.expireTxHandler +} + func (c Context) PendingTxChecker() abci.PendingTxChecker { return c.pendingTxChecker } @@ -369,6 +374,11 @@ func (c Context) WithCheckTxCallback(checkTxCallback func(error)) Context { return c } +func (c Context) WithExpireTxHandler(expireTxHandler func()) Context { + c.expireTxHandler = expireTxHandler + return c +} + // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil