From 6a5834ad81b5183e14a5fb394d70d15ec0acb555 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Mon, 11 Mar 2024 10:40:51 +0800 Subject: [PATCH] Problem: versiondb multistore can't query mem store state (backport #1230) * Problem: versiondb multistore can't query mem store state Closes: #1226 Solution: - share the mem store instance with the main store * fix * verify the fix * Update CHANGELOG.md Signed-off-by: yihuang * fix mem store * Update versiondb/multistore.go Co-authored-by: mmsqe Signed-off-by: yihuang --------- Signed-off-by: yihuang Co-authored-by: mmsqe --- CHANGELOG.md | 1 + app/app.go | 34 +++++++++++++++++----------------- app/versiondb.go | 6 ++---- app/versiondb_placeholder.go | 4 +--- store/rootmulti/store.go | 4 ++-- versiondb/multistore.go | 27 ++++++++++++++------------- 6 files changed, 37 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 483d097f12..8a6a353c2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#1241](https://github.com/crypto-org-chain/cronos/pull/1241) Improve parallelization of memiavl restoration. - [#1302](https://github.com/crypto-org-chain/cronos/pull/1302) Fix concurrent map access in rootmulti store. - [#1304](https://github.com/crypto-org-chain/cronos/pull/1304) Write versiondb with fsync, and relax the version requirement on startup. +- [#1230](https://github.com/crypto-org-chain/cronos/pull/1230) Fix mem store in versiondb multistore. ### State Machine Breaking diff --git a/app/app.go b/app/app.go index 170edc02a6..3157ab4f60 100644 --- a/app/app.go +++ b/app/app.go @@ -373,23 +373,6 @@ func New( keys, memKeys, tkeys := StoreKeys(skipGravity) - // load state streaming if enabled - if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, keys); err != nil { - fmt.Printf("failed to load state streaming: %s", err) - os.Exit(1) - } - - // wire up the versiondb's `StreamingService` and `MultiStore`. - streamers := cast.ToStringSlice(appOpts.Get("store.streamers")) - var qms sdk.MultiStore - if slices.Contains(streamers, "versiondb") { - var err error - qms, err = setupVersionDB(homePath, bApp, keys, tkeys, memKeys) - if err != nil { - panic(err) - } - } - app := &App{ BaseApp: bApp, cdc: cdc, @@ -781,6 +764,23 @@ func New( app.MountTransientStores(tkeys) app.MountMemoryStores(memKeys) + // load state streaming if enabled + if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, keys); err != nil { + fmt.Printf("failed to load state streaming: %s", err) + os.Exit(1) + } + + // wire up the versiondb's `StreamingService` and `MultiStore`. + streamers := cast.ToStringSlice(appOpts.Get("store.streamers")) + var qms sdk.MultiStore + if slices.Contains(streamers, "versiondb") { + var err error + qms, err = app.setupVersionDB(homePath, keys, tkeys, memKeys) + if err != nil { + panic(err) + } + } + // initialize BaseApp app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) diff --git a/app/versiondb.go b/app/versiondb.go index 752d17942c..10b0ad76ad 100644 --- a/app/versiondb.go +++ b/app/versiondb.go @@ -7,16 +7,14 @@ import ( "os" "path/filepath" - "github.com/cosmos/cosmos-sdk/baseapp" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/crypto-org-chain/cronos/versiondb" "github.com/crypto-org-chain/cronos/versiondb/tsrocksdb" ) -func setupVersionDB( +func (app *App) setupVersionDB( homePath string, - app *baseapp.BaseApp, keys map[string]*storetypes.KVStoreKey, tkeys map[string]*storetypes.TransientStoreKey, memKeys map[string]*storetypes.MemoryStoreKey, @@ -39,7 +37,7 @@ func setupVersionDB( service := versiondb.NewStreamingService(versionDB, exposeStoreKeys) app.SetStreamingService(service) - verDB := versiondb.NewMultiStore(versionDB, exposeStoreKeys) + verDB := versiondb.NewMultiStore(app.CommitMultiStore(), versionDB, exposeStoreKeys) verDB.MountTransientStores(tkeys) verDB.MountMemoryStores(memKeys) diff --git a/app/versiondb_placeholder.go b/app/versiondb_placeholder.go index 1c46fec500..1225c8e864 100644 --- a/app/versiondb_placeholder.go +++ b/app/versiondb_placeholder.go @@ -6,14 +6,12 @@ package app import ( "errors" - "github.com/cosmos/cosmos-sdk/baseapp" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" ) -func setupVersionDB( +func (app *App) setupVersionDB( homePath string, - app *baseapp.BaseApp, keys map[string]*storetypes.KVStoreKey, tkeys map[string]*storetypes.TransientStoreKey, memKeys map[string]*storetypes.MemoryStoreKey, diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 41406f2303..07bfe41e42 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -224,12 +224,12 @@ func (rs *Store) CacheMultiStoreWithVersion(version int64) (types.CacheMultiStor // Implements interface MultiStore func (rs *Store) GetStore(key types.StoreKey) types.Store { - panic("uncached KVStore is not supposed to be accessed directly") + return rs.stores[key] } // Implements interface MultiStore func (rs *Store) GetKVStore(key types.StoreKey) types.KVStore { - panic("uncached KVStore is not supposed to be accessed directly") + return rs.stores[key] } // Implements interface MultiStore diff --git a/versiondb/multistore.go b/versiondb/multistore.go index 423aec8496..878f6dd08e 100644 --- a/versiondb/multistore.go +++ b/versiondb/multistore.go @@ -5,8 +5,6 @@ import ( "sync" "github.com/cosmos/cosmos-sdk/store/cachemulti" - "github.com/cosmos/cosmos-sdk/store/mem" - "github.com/cosmos/cosmos-sdk/store/transient" "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -19,7 +17,10 @@ type MultiStore struct { storeKeys []types.StoreKey // transient or memory stores - transientStores map[types.StoreKey]types.KVStore + transientStores map[types.StoreKey]struct{} + + // proxy the calls for transient or mem stores to the parent + parent types.MultiStore traceWriter io.Writer traceContext types.TraceContext @@ -27,8 +28,8 @@ type MultiStore struct { } // NewMultiStore returns a new versiondb `MultiStore`. -func NewMultiStore(versionDB VersionStore, storeKeys []types.StoreKey) *MultiStore { - return &MultiStore{versionDB: versionDB, storeKeys: storeKeys, transientStores: make(map[types.StoreKey]types.KVStore)} +func NewMultiStore(parent types.MultiStore, versionDB VersionStore, storeKeys []types.StoreKey) *MultiStore { + return &MultiStore{versionDB: versionDB, storeKeys: storeKeys, parent: parent, transientStores: make(map[types.StoreKey]struct{})} } // GetStoreType implements `MultiStore` interface. @@ -39,8 +40,8 @@ func (s *MultiStore) GetStoreType() types.StoreType { // cacheMultiStore branch out the multistore. func (s *MultiStore) cacheMultiStore(version *int64) sdk.CacheMultiStore { stores := make(map[types.StoreKey]types.CacheWrapper, len(s.transientStores)+len(s.storeKeys)) - for k, v := range s.transientStores { - stores[k] = v + for k := range s.transientStores { + stores[k] = s.parent.GetKVStore(k).(types.CacheWrapper) } for _, k := range s.storeKeys { stores[k] = NewKVStore(s.versionDB, k, version) @@ -75,9 +76,8 @@ func (s *MultiStore) GetStore(storeKey types.StoreKey) sdk.Store { // GetKVStore implements `MultiStore` interface func (s *MultiStore) GetKVStore(storeKey types.StoreKey) sdk.KVStore { - store, ok := s.transientStores[storeKey] - if ok { - return store + if _, ok := s.transientStores[storeKey]; ok { + return s.parent.GetKVStore(storeKey) } return NewKVStore(s.versionDB, storeKey, nil) } @@ -85,14 +85,15 @@ func (s *MultiStore) GetKVStore(storeKey types.StoreKey) sdk.KVStore { // MountTransientStores simlates the same behavior as sdk to support grpc query service. func (s *MultiStore) MountTransientStores(keys map[string]*types.TransientStoreKey) { for _, key := range keys { - s.transientStores[key] = transient.NewStore() + s.transientStores[key] = struct{}{} } } -// MountMemoryStores simlates the same behavior as sdk to support grpc query service. +// MountMemoryStores simlates the same behavior as sdk to support grpc query service, +// it shares the existing mem store instance. func (s *MultiStore) MountMemoryStores(keys map[string]*types.MemoryStoreKey) { for _, key := range keys { - s.transientStores[key] = mem.NewStore() + s.transientStores[key] = struct{}{} } }