baseapp: introduce checkState and deliverState to wrap their ms and ctx
This commit is contained in:
parent
0a87bfa26f
commit
2cefcf9e6c
|
@ -41,18 +41,16 @@ type BaseApp struct {
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
// Volatile
|
// Volatile
|
||||||
// .msCheck and .ctxCheck are set on initialization and reset on Commit.
|
// checkState is set on initialization and reset on Commit.
|
||||||
// .msDeliver and .ctxDeliver are (re-)set on BeginBlock.
|
// deliverState is set in InitChain and BeginBlock and cleared on Commit.
|
||||||
|
// See methods setCheckState and setDeliverState.
|
||||||
// .valUpdates accumulate in DeliverTx and are reset in BeginBlock.
|
// .valUpdates accumulate in DeliverTx and are reset in BeginBlock.
|
||||||
// QUESTION: should we put valUpdates in the ctxDeliver?
|
// QUESTION: should we put valUpdates in the deliverState.ctx?
|
||||||
msCheck sdk.CacheMultiStore // CheckTx state, a cache-wrap of `.cms`
|
checkState *state // for CheckTx
|
||||||
msDeliver sdk.CacheMultiStore // DeliverTx state, a cache-wrap of `.cms`
|
deliverState *state // for DeliverTx
|
||||||
ctxCheck sdk.Context // CheckTx context
|
valUpdates []abci.Validator // cached validator changes from DeliverTx
|
||||||
ctxDeliver sdk.Context // DeliverTx context
|
|
||||||
valUpdates []abci.Validator // cached validator changes from DeliverTx
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ abci.Application = &BaseApp{}
|
|
||||||
var _ abci.Application = (*BaseApp)(nil)
|
var _ abci.Application = (*BaseApp)(nil)
|
||||||
|
|
||||||
// Create and name new BaseApp
|
// Create and name new BaseApp
|
||||||
|
@ -165,8 +163,7 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// initialize Check state
|
// initialize Check state
|
||||||
app.msCheck = app.cms.CacheMultiStore()
|
app.setCheckState(abci.Header{})
|
||||||
app.ctxCheck = app.NewContext(true, abci.Header{})
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -174,9 +171,34 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
|
||||||
// NewContext returns a new Context with the correct store, the given header, and nil txBytes.
|
// NewContext returns a new Context with the correct store, the given header, and nil txBytes.
|
||||||
func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context {
|
func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context {
|
||||||
if isCheckTx {
|
if isCheckTx {
|
||||||
return sdk.NewContext(app.msCheck, header, true, nil)
|
return sdk.NewContext(app.checkState.ms, header, true, nil)
|
||||||
|
}
|
||||||
|
return sdk.NewContext(app.deliverState.ms, header, false, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type state struct {
|
||||||
|
ms sdk.CacheMultiStore
|
||||||
|
ctx sdk.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *state) CacheMultiStore() sdk.CacheMultiStore {
|
||||||
|
return st.ms.CacheMultiStore()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *BaseApp) setCheckState(header abci.Header) {
|
||||||
|
ms := app.cms.CacheMultiStore()
|
||||||
|
app.checkState = &state{
|
||||||
|
ms: ms,
|
||||||
|
ctx: sdk.NewContext(ms, header, true, nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *BaseApp) setDeliverState(header abci.Header) {
|
||||||
|
ms := app.cms.CacheMultiStore()
|
||||||
|
app.deliverState = &state{
|
||||||
|
ms: ms,
|
||||||
|
ctx: sdk.NewContext(ms, header, false, nil),
|
||||||
}
|
}
|
||||||
return sdk.NewContext(app.msDeliver, header, false, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
@ -207,14 +229,12 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the deliver state
|
// Initialize the deliver state and run initChain
|
||||||
app.msDeliver = app.cms.CacheMultiStore()
|
app.setDeliverState(abci.Header{})
|
||||||
app.ctxDeliver = app.NewContext(false, abci.Header{})
|
app.initChainer(app.deliverState.ctx, req) // no error
|
||||||
|
|
||||||
app.initChainer(app.ctxDeliver, req) // no error
|
|
||||||
|
|
||||||
// NOTE: we don't commit, but BeginBlock for block 1
|
// NOTE: we don't commit, but BeginBlock for block 1
|
||||||
// starts from this state
|
// starts from this deliverState
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -233,16 +253,15 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||||
// Implements ABCI
|
// Implements ABCI
|
||||||
func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) {
|
func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) {
|
||||||
// Initialize the DeliverTx state.
|
// Initialize the DeliverTx state.
|
||||||
// If this is the first block, it was already
|
// If this is the first block, it should already
|
||||||
// initialized in InitChain. If we're testing,
|
// be initialized in InitChain. It may also be nil
|
||||||
// then we may not have run InitChain and these could be nil
|
// if this is a test and InitChain was never called.
|
||||||
if req.Header.Height > 1 || app.msDeliver == nil {
|
if app.deliverState == nil {
|
||||||
app.msDeliver = app.cms.CacheMultiStore()
|
app.setDeliverState(req.Header)
|
||||||
app.ctxDeliver = app.NewContext(false, req.Header)
|
|
||||||
}
|
}
|
||||||
app.valUpdates = nil
|
app.valUpdates = nil
|
||||||
if app.beginBlocker != nil {
|
if app.beginBlocker != nil {
|
||||||
res = app.beginBlocker(app.ctxDeliver, req)
|
res = app.beginBlocker(app.deliverState.ctx, req)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -336,9 +355,9 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||||
// Get the context
|
// Get the context
|
||||||
var ctx sdk.Context
|
var ctx sdk.Context
|
||||||
if isCheckTx {
|
if isCheckTx {
|
||||||
ctx = app.ctxCheck.WithTxBytes(txBytes)
|
ctx = app.checkState.ctx.WithTxBytes(txBytes)
|
||||||
} else {
|
} else {
|
||||||
ctx = app.ctxDeliver.WithTxBytes(txBytes)
|
ctx = app.deliverState.ctx.WithTxBytes(txBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the ante handler.
|
// Run the ante handler.
|
||||||
|
@ -353,12 +372,12 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||||
// Get the correct cache
|
// Get the correct cache
|
||||||
var msCache sdk.CacheMultiStore
|
var msCache sdk.CacheMultiStore
|
||||||
if isCheckTx == true {
|
if isCheckTx == true {
|
||||||
// CacheWrap app.msCheck in case it fails.
|
// CacheWrap app.checkState.ms in case it fails.
|
||||||
msCache = app.msCheck.CacheMultiStore()
|
msCache = app.checkState.CacheMultiStore()
|
||||||
ctx = ctx.WithMultiStore(msCache)
|
ctx = ctx.WithMultiStore(msCache)
|
||||||
} else {
|
} else {
|
||||||
// CacheWrap app.msDeliver in case it fails.
|
// CacheWrap app.deliverState.ms in case it fails.
|
||||||
msCache = app.msDeliver.CacheMultiStore()
|
msCache = app.deliverState.CacheMultiStore()
|
||||||
ctx = ctx.WithMultiStore(msCache)
|
ctx = ctx.WithMultiStore(msCache)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -368,7 +387,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||||
handler := app.router.Route(msgType)
|
handler := app.router.Route(msgType)
|
||||||
result = handler(ctx, msg)
|
result = handler(ctx, msg)
|
||||||
|
|
||||||
// If result was successful, write to app.msDeliver or app.msCheck.
|
// If result was successful, write to app.checkState.ms or app.deliverState.ms
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
msCache.Write()
|
msCache.Write()
|
||||||
}
|
}
|
||||||
|
@ -379,7 +398,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||||
// Implements ABCI
|
// Implements ABCI
|
||||||
func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) {
|
func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) {
|
||||||
if app.endBlocker != nil {
|
if app.endBlocker != nil {
|
||||||
res = app.endBlocker(app.ctxDeliver, req)
|
res = app.endBlocker(app.deliverState.ctx, req)
|
||||||
} else {
|
} else {
|
||||||
res.ValidatorUpdates = app.valUpdates
|
res.ValidatorUpdates = app.valUpdates
|
||||||
}
|
}
|
||||||
|
@ -388,7 +407,7 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc
|
||||||
|
|
||||||
// Implements ABCI
|
// Implements ABCI
|
||||||
func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||||
header := app.ctxDeliver.BlockHeader()
|
header := app.deliverState.ctx.BlockHeader()
|
||||||
/*
|
/*
|
||||||
// Write the latest Header to the store
|
// Write the latest Header to the store
|
||||||
headerBytes, err := proto.Marshal(&header)
|
headerBytes, err := proto.Marshal(&header)
|
||||||
|
@ -399,17 +418,19 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Write the Deliver state and commit the MultiStore
|
// Write the Deliver state and commit the MultiStore
|
||||||
app.msDeliver.Write()
|
app.deliverState.ms.Write()
|
||||||
commitID := app.cms.Commit()
|
commitID := app.cms.Commit()
|
||||||
app.logger.Debug("Commit synced",
|
app.logger.Debug("Commit synced",
|
||||||
"commit", commitID,
|
"commit", commitID,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reset the Check state
|
// Reset the Check state to the latest committed
|
||||||
// NOTE: safe because Tendermint holds a lock on the mempool for Commit.
|
// NOTE: safe because Tendermint holds a lock on the mempool for Commit.
|
||||||
// Use the header from this latest block.
|
// Use the header from this latest block.
|
||||||
app.msCheck = app.cms.CacheMultiStore()
|
app.setCheckState(header)
|
||||||
app.ctxCheck = app.NewContext(true, header)
|
|
||||||
|
// Emtpy the Deliver state
|
||||||
|
app.deliverState = nil
|
||||||
|
|
||||||
return abci.ResponseCommit{
|
return abci.ResponseCommit{
|
||||||
Data: commitID.Hash,
|
Data: commitID.Hash,
|
||||||
|
|
Loading…
Reference in New Issue