From c05c9c61c90e0ff8770d52f531c4ff3bf47840a7 Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 27 Oct 2023 15:41:19 +0800 Subject: [PATCH] Problem: versiondb multistore can't query mem store state (#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 +-- integration_tests/test_ica_precompile.py | 2 +- store/rootmulti/store.go | 4 +-- versiondb/multistore.go | 27 ++++++++++--------- 7 files changed, 38 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 905bf90c07..be98e9c1f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [#1215](https://github.com/crypto-org-chain/cronos/pull/1215) Update ethermint to fix of concurrent write in fee history. - [#1217](https://github.com/crypto-org-chain/cronos/pull/1217) Use the default chain-id behavour in sdk. +- [#1230](https://github.com/crypto-org-chain/cronos/pull/1230) Fix mem store in versiondb multistore. *October 17, 2023* diff --git a/app/app.go b/app/app.go index b764b33675..e589267c39 100644 --- a/app/app.go +++ b/app/app.go @@ -402,23 +402,6 @@ func New( keys, memKeys, tkeys := StoreKeys(skipGravity) - // load state streaming if enabled - if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, logger, 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, @@ -868,6 +851,23 @@ func New( app.MountTransientStores(tkeys) app.MountMemoryStores(memKeys) + // load state streaming if enabled + if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, logger, 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.SetPreBlocker(app.PreBlocker) 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/integration_tests/test_ica_precompile.py b/integration_tests/test_ica_precompile.py index a5899f2245..52c39e14c7 100644 --- a/integration_tests/test_ica_precompile.py +++ b/integration_tests/test_ica_precompile.py @@ -131,7 +131,7 @@ def test_call(ibc): name = "signer2" addr = ADDRS[name] contract = w3.eth.contract(address=CONTRACT, abi=contract_info) - data = {"from": ADDRS[name], "gas": 400000} + data = {"from": ADDRS[name]} ica_address = register_acc( cli_controller, w3, diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index aa7fdb42fe..a916449c79 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -227,12 +227,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{}{} } }