Skip to content

Commit

Permalink
add mutex for different state
Browse files Browse the repository at this point in the history
  • Loading branch information
pythonberg1997 committed Jul 8, 2023
1 parent c0ecdc3 commit ae8e001
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 15 deletions.
35 changes: 24 additions & 11 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC
}

// initialize states with a correct header
app.setQueryState(initHeader)
app.setState(runTxModeDeliver, initHeader)
app.setState(runTxModeCheck, initHeader)

Expand Down Expand Up @@ -194,6 +195,16 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
WithBlockHeight(req.Header.Height)
}

if app.queryState == nil {
app.setQueryState(req.Header)
} else {
// In the first block, app.queryState.ctx will already be initialized
// by InitChain. Context is now updated with Header information.
app.queryState.ctx = app.queryState.ctx.
WithBlockHeader(req.Header).
WithBlockHeight(req.Header.Height)
}

gasMeter := app.getBlockGasMeter(app.deliverState.ctx)

app.deliverState.ctx = app.deliverState.ctx.
Expand Down Expand Up @@ -736,11 +747,12 @@ func (app *BaseApp) handleQueryGRPC(handler GRPCQueryHandler, req abci.RequestQu
}

func (app *BaseApp) handleEthQuery(handler EthQueryHandler, req cmtrpctypes.RPCRequest) abci.ResponseEthQuery {
// use custom query multistore if provided
qms := app.qms
if qms == nil {
qms = app.cms.(storetypes.MultiStore)
// use custom query state if provided
qs := app.getQueryState()
if qs == nil {
return sdkerrors.EthQueryResult(fmt.Errorf("queryState is nil"), app.trace)
}
qms := qs.ms.(sdk.MultiStore)

height := qms.LatestVersion()
if height == 0 {
Expand All @@ -758,7 +770,7 @@ func (app *BaseApp) handleEthQuery(handler EthQueryHandler, req cmtrpctypes.RPCR
}

// branch the commit-multistore for safety
ctx := sdk.NewContext(cacheMS, app.checkState.ctx.BlockHeader(), true, app.upgradeChecker, app.logger).
ctx := sdk.NewContext(cacheMS, qs.ctx.BlockHeader(), true, app.upgradeChecker, app.logger).
WithBlockHeight(height)

res, err := handler(ctx, req)
Expand Down Expand Up @@ -808,11 +820,12 @@ func (app *BaseApp) CreateQueryContext(height int64, prove bool, path ...string)
return sdk.Context{}, err
}

// use custom query multistore if provided
qms := app.qms
if qms == nil {
qms = app.cms.(sdk.MultiStore)
// use custom query state if provided
qs := app.getQueryState()
if qs == nil {
return sdk.Context{}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "queryState is nil")
}
qms := app.getQueryState().ms.(sdk.MultiStore)

lastBlockHeight := qms.LatestVersion()
if lastBlockHeight == 0 {
Expand Down Expand Up @@ -845,7 +858,7 @@ func (app *BaseApp) CreateQueryContext(height int64, prove bool, path ...string)
if len(path) == 1 && path[0] == "/cosmos.auth.v1beta1.Query/Account" {
// use checkState for account queries
// we could get the newest account info to send multi txs in one block
cacheMS, err = app.checkState.ms.(sdk.MultiStore).CacheMultiStoreWithVersion(height)
cacheMS, err = app.getState(runTxModeCheck).ms.(sdk.MultiStore).CacheMultiStoreWithVersion(height)
} else {
cacheMS, err = qms.CacheMultiStoreWithVersion(height)
}
Expand All @@ -858,7 +871,7 @@ func (app *BaseApp) CreateQueryContext(height int64, prove bool, path ...string)
}

// branch the commit-multistore for safety
ctx := sdk.NewContext(cacheMS, app.checkState.ctx.BlockHeader(), true, app.upgradeChecker, app.logger).
ctx := sdk.NewContext(cacheMS, qs.ctx.BlockHeader(), true, app.upgradeChecker, app.logger).
WithMinGasPrices(app.minGasPrices).
WithBlockHeight(height)

Expand Down
42 changes: 41 additions & 1 deletion baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"sort"
"strings"
"sync"

dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
Expand Down Expand Up @@ -52,7 +53,6 @@ type BaseApp struct { // nolint: maligned
name string // application name from abci.Info
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
qms sdk.MultiStore // Optional alternative multistore for querying only.
storeLoader StoreLoader // function to handle store loading, may be overridden with SetStoreLoader()
grpcQueryRouter *GRPCQueryRouter // router for redirecting gRPC query calls
ethQueryRouter *EthQueryRouter // router for redirecting eth query calls
Expand Down Expand Up @@ -80,11 +80,16 @@ type BaseApp struct { // nolint: maligned
//
// checkState is set on InitChain and reset on Commit
// deliverState is set on InitChain and BeginBlock and set to nil on Commit
// queryState is set on InitChain and BeginBlock
queryState *state // optional alternative multistore for querying only.
checkState *state // for CheckTx
deliverState *state // for DeliverTx
processProposalState *state // for ProcessProposal
prepareProposalState *state // for PrepareProposal

queryStateMtx *sync.RWMutex // mutex for queryState
checkStateMtx *sync.RWMutex // mutex for checkState

// an inter-block write-through cache provided to the context during deliverState
interBlockCache sdk.MultiStorePersistentCache

Expand Down Expand Up @@ -179,6 +184,16 @@ func NewBaseApp(
app.SetMempool(mempool.NoOpMempool{})
}

if app.queryStateMtx == nil {
mtx := new(sync.RWMutex)
app.queryStateMtx = mtx
}

if app.checkStateMtx == nil {
mtx := new(sync.RWMutex)
app.checkStateMtx = mtx
}

abciProposalHandler := NewDefaultProposalHandler(app.mempool, app)

if app.prepareProposal == nil {
Expand Down Expand Up @@ -441,6 +456,8 @@ func (app *BaseApp) setState(mode runTxMode, header tmproto.Header) {

switch mode {
case runTxModeCheck:
app.checkStateMtx.Lock()
defer app.checkStateMtx.Unlock()
// Minimum gas prices are also set. It is set on InitChain and reset on Commit.
baseState.ctx = baseState.ctx.WithIsCheckTx(true).WithMinGasPrices(app.minGasPrices)
app.checkState = baseState
Expand All @@ -458,6 +475,19 @@ func (app *BaseApp) setState(mode runTxMode, header tmproto.Header) {
}
}

func (app *BaseApp) setQueryState(header tmproto.Header) {
app.queryStateMtx.Lock()
defer app.queryStateMtx.Unlock()

ms := app.cms.CacheMultiStore()
baseState := &state{
ms: ms,
ctx: sdk.NewContext(ms, header, false, app.upgradeChecker, app.logger),
}

app.queryState = baseState
}

// GetConsensusParams returns the current consensus parameters from the BaseApp's
// ParamStore. If the BaseApp has no ParamStore defined, nil is returned.
func (app *BaseApp) GetConsensusParams(ctx sdk.Context) *tmproto.ConsensusParams {
Expand Down Expand Up @@ -578,10 +608,20 @@ func (app *BaseApp) getState(mode runTxMode) *state {
return app.processProposalState

default:
app.queryStateMtx.RLock()
defer app.queryStateMtx.RUnlock()

return app.checkState
}
}

func (app *BaseApp) getQueryState() *state {
app.queryStateMtx.RLock()
defer app.queryStateMtx.RUnlock()

return app.queryState
}

func (app *BaseApp) getBlockGasMeter(ctx sdk.Context) storetypes.GasMeter {
if maxGas := app.GetMaximumBlockGas(ctx); maxGas > 0 {
return storetypes.NewGasMeter(maxGas)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ replace (
// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.23.0
github.com/cometbft/cometbft => github.com/Pythonberg1997/greenfield-cometbft v0.0.0-20230707013815-11540a027260
github.com/cometbft/cometbft => github.com/Pythonberg1997/greenfield-cometbft v0.0.0-20230708021401-da08119f78a0
// Downgraded to avoid bugs in following commits which caused simulations to fail.
// dgrijalva/jwt-go is deprecated and doesn't receive security updates.
// TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Pythonberg1997/greenfield-cometbft v0.0.0-20230707013815-11540a027260 h1:MpCoAIomvZ//W9W9QDtW++nxyEgGVfuMlxZgGzj8XXY=
github.com/Pythonberg1997/greenfield-cometbft v0.0.0-20230707013815-11540a027260/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs=
github.com/Pythonberg1997/greenfield-cometbft v0.0.0-20230708021401-da08119f78a0 h1:/Uxruh7STp2BMry76vVkSnN7RghlyAC37uucEcNI+zU=
github.com/Pythonberg1997/greenfield-cometbft v0.0.0-20230708021401-da08119f78a0/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
Expand Down

0 comments on commit ae8e001

Please sign in to comment.