Skip to content

Commit

Permalink
Add QMS for IAVL migration query multistore (#542)
Browse files Browse the repository at this point in the history
## Describe your changes and provide context
This PR add an extra QMS used for serving online migration query
fallback. When the request height is lower than the migration height, we
will fall back to read from IAVL store, otherwise, it will use the
default CMS

## Testing performed to validate your change
  • Loading branch information
yzang2019 authored Sep 25, 2024
1 parent 56ccf6a commit e618491
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 15 deletions.
44 changes: 32 additions & 12 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ import (
"time"

"github.com/armon/go-metrics"
"github.com/gogo/protobuf/proto"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"

"github.com/cosmos/cosmos-sdk/codec"
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
"github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/tasks"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/legacytm"
"github.com/cosmos/cosmos-sdk/utils"
"github.com/gogo/protobuf/proto"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"
)

// InitChain implements the ABCI interface. It runs the initialization logic
Expand Down Expand Up @@ -708,7 +708,8 @@ func checkNegativeHeight(height int64) error {
// CreateQueryContext creates a new sdk.Context for a query, taking as args
// the block height and whether the query needs a proof or not.
func (app *BaseApp) CreateQueryContext(height int64, prove bool) (sdk.Context, error) {
if err := checkNegativeHeight(height); err != nil {
err := checkNegativeHeight(height)
if err != nil {
return sdk.Context{}, err
}

Expand All @@ -734,7 +735,13 @@ func (app *BaseApp) CreateQueryContext(height int64, prove bool) (sdk.Context, e
)
}

cacheMS, err := app.cms.CacheMultiStoreWithVersion(height)
var cacheMS types.CacheMultiStore
if height < app.migrationHeight && app.qms != nil {
cacheMS, err = app.qms.CacheMultiStoreWithVersion(height)

Check warning on line 740 in baseapp/abci.go

View check run for this annotation

Codecov / codecov/patch

baseapp/abci.go#L740

Added line #L740 was not covered by tests
} else {
cacheMS, err = app.cms.CacheMultiStoreWithVersion(height)
}

if err != nil {
return sdk.Context{},
sdkerrors.Wrapf(
Expand Down Expand Up @@ -905,12 +912,25 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
}

func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery {
// "/store" prefix for store queries
queryable, ok := app.cms.(sdk.Queryable)
if !ok {
return sdkerrors.QueryResultWithDebug(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"), app.trace)

var (
queryable sdk.Queryable
ok bool
)
// Check if online migration is enabled for fallback read
if req.Height < app.migrationHeight && app.qms != nil {
queryable, ok = app.qms.(sdk.Queryable)
if !ok {
return sdkerrors.QueryResultWithDebug(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"), app.trace)
}

Check warning on line 925 in baseapp/abci.go

View check run for this annotation

Codecov / codecov/patch

baseapp/abci.go#L922-L925

Added lines #L922 - L925 were not covered by tests
} else {
queryable, ok = app.cms.(sdk.Queryable)
if !ok {
return sdkerrors.QueryResultWithDebug(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"), app.trace)
}

Check warning on line 930 in baseapp/abci.go

View check run for this annotation

Codecov / codecov/patch

baseapp/abci.go#L929-L930

Added lines #L929 - L930 were not covered by tests
}

// "/store" prefix for store queries
req.Path = "/" + strings.Join(path[1:], "/")

if req.Height <= 1 && req.Prove {
Expand Down
8 changes: 5 additions & 3 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,11 @@ type BaseApp struct { //nolint: maligned
}

type appStore struct {
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
storeLoader StoreLoader // function to handle store loading, may be overridden with SetStoreLoader()
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
qms sdk.MultiStore // Query multistore used for migration only
migrationHeight int64
storeLoader StoreLoader // function to handle store loading, may be overridden with SetStoreLoader()

// an inter-block write-through cache provided to the context during deliverState
interBlockCache sdk.MultiStorePersistentCache
Expand Down
10 changes: 10 additions & 0 deletions baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,13 @@ func (app *BaseApp) SetStreamingService(s StreamingService) {
// BaseApp will pass BeginBlock, DeliverTx, and EndBlock requests and responses to the streaming services to update their ABCI context
app.abciListeners = append(app.abciListeners, s)
}

// SetQueryMultiStore set a alternative MultiStore implementation to support online migration fallback read.
func (app *BaseApp) SetQueryMultiStore(ms sdk.MultiStore) {
app.qms = ms

Check warning on line 367 in baseapp/options.go

View check run for this annotation

Codecov / codecov/patch

baseapp/options.go#L366-L367

Added lines #L366 - L367 were not covered by tests
}

// SetMigrationHeight set the migration height for online migration so that query below this height will still be served from IAVL.
func (app *BaseApp) SetMigrationHeight(height int64) {
app.migrationHeight = height

Check warning on line 372 in baseapp/options.go

View check run for this annotation

Codecov / codecov/patch

baseapp/options.go#L371-L372

Added lines #L371 - L372 were not covered by tests
}

0 comments on commit e618491

Please sign in to comment.