diff --git a/store/CHANGELOG.md b/store/CHANGELOG.md index 39cfdacfa33a..b5e06dc3f03a 100644 --- a/store/CHANGELOG.md +++ b/store/CHANGELOG.md @@ -34,6 +34,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#242](https://github.com/crypto-org-chain/cosmos-sdk/pull/242) Init cache on cache lazily, save memory allocations. * [#243](https://github.com/crypto-org-chain/cosmos-sdk/pull/243) Support `RunAtomic` API to use new CoW cache store. * [#244](https://github.com/crypto-org-chain/cosmos-sdk/pull/244) Add `Discard` method to CacheWrap to discard the write buffer. +* [#258](https://github.com/crypto-org-chain/cosmos-sdk/pull/258) Add `NewFromParent` API to cachemulti store to create a new store from block-stm multiversion data structure. ## v1.1.0 (March 20, 2024) diff --git a/store/cachemulti/store.go b/store/cachemulti/store.go index a78a4b92dd12..96aafd41e656 100644 --- a/store/cachemulti/store.go +++ b/store/cachemulti/store.go @@ -24,7 +24,7 @@ type Store struct { traceWriter io.Writer traceContext types.TraceContext - parentStore func(types.StoreKey) types.CacheWrap + parentStore func(types.StoreKey) types.CacheWrapper branched bool } @@ -60,12 +60,17 @@ func NewStore( return NewFromKVStore(stores, traceWriter, traceContext) } -func newCacheMultiStoreFromCMS(cms Store) Store { +// NewFromParent constructs a cache multistore with a parent store lazily, +// the parent is usually another cache multistore or the block-stm multiversion store. +func NewFromParent( + parentStore func(types.StoreKey) types.CacheWrapper, + traceWriter io.Writer, traceContext types.TraceContext, +) Store { return Store{ stores: make(map[types.StoreKey]types.CacheWrap), - traceWriter: cms.traceWriter, - traceContext: cms.traceContext, - parentStore: cms.getCacheWrap, + traceWriter: traceWriter, + traceContext: traceContext, + parentStore: parentStore, } } @@ -141,10 +146,10 @@ func (cms Store) CacheWrap() types.CacheWrap { // Implements MultiStore. func (cms Store) CacheMultiStore() types.CacheMultiStore { - return newCacheMultiStoreFromCMS(cms) + return NewFromParent(cms.getCacheWrapper, cms.traceWriter, cms.traceContext) } -func (cms Store) getCacheWrap(key types.StoreKey) types.CacheWrap { +func (cms Store) getCacheWrapper(key types.StoreKey) types.CacheWrapper { store, ok := cms.stores[key] if !ok && cms.parentStore != nil { // load on demand @@ -158,7 +163,7 @@ func (cms Store) getCacheWrap(key types.StoreKey) types.CacheWrap { // GetStore returns an underlying Store by key. func (cms Store) GetStore(key types.StoreKey) types.Store { - store, ok := cms.getCacheWrap(key).(types.Store) + store, ok := cms.getCacheWrapper(key).(types.Store) if !ok { panic(fmt.Sprintf("store with key %v is not Store", key)) } @@ -167,7 +172,7 @@ func (cms Store) GetStore(key types.StoreKey) types.Store { // GetKVStore returns an underlying KVStore by key. func (cms Store) GetKVStore(key types.StoreKey) types.KVStore { - store, ok := cms.getCacheWrap(key).(types.KVStore) + store, ok := cms.getCacheWrapper(key).(types.KVStore) if !ok { panic(fmt.Sprintf("store with key %v is not KVStore", key)) } @@ -176,7 +181,7 @@ func (cms Store) GetKVStore(key types.StoreKey) types.KVStore { // GetObjKVStore returns an underlying KVStore by key. func (cms Store) GetObjKVStore(key types.StoreKey) types.ObjKVStore { - store, ok := cms.getCacheWrap(key).(types.ObjKVStore) + store, ok := cms.getCacheWrapper(key).(types.ObjKVStore) if !ok { panic(fmt.Sprintf("store with key %v is not ObjKVStore", key)) } diff --git a/store/cachemulti/store_test.go b/store/cachemulti/store_test.go index 01c7a810bf91..38d1182cdf7a 100644 --- a/store/cachemulti/store_test.go +++ b/store/cachemulti/store_test.go @@ -43,7 +43,7 @@ func TestRunAtomic(t *testing.T) { keys["obj"]: objStore.CacheWrap(), }} - s := Store{stores: map[types.StoreKey]types.CacheWrap{}, parentStore: parent.getCacheWrap} + s := Store{stores: map[types.StoreKey]types.CacheWrap{}, parentStore: parent.getCacheWrapper} s.RunAtomic(func(ms types.CacheMultiStore) error { ms.GetKVStore(keys["abc"]).Set([]byte("key"), []byte("value")) ms.GetObjKVStore(keys["obj"]).Set([]byte("key"), "value") @@ -77,7 +77,7 @@ func TestBranchStore(t *testing.T) { keys["obj"]: objStore.CacheWrap(), }} - s := Store{stores: map[types.StoreKey]types.CacheWrap{}, parentStore: parent.getCacheWrap} + s := Store{stores: map[types.StoreKey]types.CacheWrap{}, parentStore: parent.getCacheWrapper} s.GetKVStore(keys["abc"]).Set([]byte("key"), []byte("value")) snapshot := s.Clone() s.GetKVStore(keys["abc"]).Set([]byte("key"), []byte("value2"))