diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index f4cf422f9..d5fc42d82 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -154,8 +154,9 @@ type BaseApp struct { //nolint: maligned ChainID string - votesInfoLock sync.RWMutex - commitLock *sync.Mutex + votesInfoLock sync.RWMutex + commitLock *sync.Mutex + checkTxStateLock *sync.RWMutex compactionInterval uint64 @@ -265,7 +266,8 @@ func NewBaseApp( TracingInfo: &tracing.Info{ Tracer: &tr, }, - commitLock: &sync.Mutex{}, + commitLock: &sync.Mutex{}, + checkTxStateLock: &sync.RWMutex{}, } app.TracingInfo.SetContext(context.Background()) @@ -500,6 +502,8 @@ func (app *BaseApp) IsSealed() bool { return app.sealed } func (app *BaseApp) setCheckState(header tmproto.Header) { ms := app.cms.CacheMultiStore() ctx := sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices) + app.checkTxStateLock.Lock() + defer app.checkTxStateLock.Unlock() if app.checkState == nil { app.checkState = &state{ ms: ms, @@ -991,6 +995,9 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // append the events in the order of occurrence result.Events = append(anteEvents, result.Events...) } + if ctx.CheckTxCallback() != nil { + ctx.CheckTxCallback()(err) + } return gInfo, result, anteEvents, priority, pendingTxChecker, err } @@ -1177,5 +1184,7 @@ func (app *BaseApp) ReloadDB() error { } func (app *BaseApp) GetCheckCtx() sdk.Context { + app.checkTxStateLock.RLock() + defer app.checkTxStateLock.RUnlock() return app.checkState.ctx } diff --git a/types/context.go b/types/context.go index 39b341a4f..527a2f210 100644 --- a/types/context.go +++ b/types/context.go @@ -41,6 +41,7 @@ type Context struct { eventManager *EventManager 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` txBlockingChannels acltypes.MessageAccessOpsChannelMapping txCompletionChannels acltypes.MessageAccessOpsChannelMapping @@ -121,6 +122,10 @@ func (c Context) PendingTxChecker() abci.PendingTxChecker { return c.pendingTxChecker } +func (c Context) CheckTxCallback() func(error) { + return c.checkTxCallback +} + func (c Context) TxCompletionChannels() acltypes.MessageAccessOpsChannelMapping { return c.txCompletionChannels } @@ -359,6 +364,11 @@ func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context { return c } +func (c Context) WithCheckTxCallback(checkTxCallback func(error)) Context { + c.checkTxCallback = checkTxCallback + return c +} + // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil