Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions sei-cosmos/storev2/rootmulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,21 +244,25 @@
rs.mtx.RLock()
defer rs.mtx.RUnlock()
stores := make(map[types.StoreKey]types.CacheWrapper)
// add the transient/mem stores registered in current app.
for k, store := range rs.ckvStores {
if store.GetStoreType() != types.StoreTypeIAVL {
stores[k] = store
}
}
// TODO: May need to add historical SC store as well for nodes that doesn't enable ss but still need historical queries

// add SS stores for historical queries
// Serve from SS stores for ALL historical queries
if rs.ssStore != nil {
if version <= 0 {
version = rs.ssStore.GetLatestVersion()
}
// add the transient/mem stores registered in current app.
for k, store := range rs.ckvStores {
if store.GetStoreType() != types.StoreTypeIAVL {
stores[k] = store
}
}
Comment on lines +253 to +257

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism
for k, store := range rs.ckvStores {
if store.GetStoreType() == types.StoreTypeIAVL {
stores[k] = state.NewStore(rs.ssStore, k, version)
}
}
} else if version <= 0 || (rs.lastCommitInfo != nil && version == rs.lastCommitInfo.Version) {
// Only serve from SC when query latest version and SS not enabled
return rs.CacheMultiStore(), nil
}

return cachemulti.NewStore(nil, stores, rs.storeKeys, nil, nil, nil), nil
Expand Down
97 changes: 97 additions & 0 deletions sei-cosmos/storev2/rootmulti/store_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rootmulti

import (
"github.com/cosmos/cosmos-sdk/storev2/state"
"testing"

"time"
Expand Down Expand Up @@ -93,3 +94,99 @@ func TestSCSS_WriteAndHistoricalRead(t *testing.T) {
require.EqualValues(t, 0, resp.Code)
require.Equal(t, valV1, resp.Value)
}

// TestCacheMultiStoreWithVersion_OnlyUsesSSStores verifies that CacheMultiStoreWithVersion
// serves SS stores when enabled, and falls back to SC when SS is disabled, for
// height=0 (latest) and explicit latest height.
func TestCacheMultiStoreWithVersion_OnlyUsesSSStores(t *testing.T) {
testCases := []struct {
name string
ssEnabled bool
}{
{"ss-enabled", true},
{"ss-disabled", false},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
home := t.TempDir()
scCfg := config.DefaultStateCommitConfig()
scCfg.Enable = true
scCfg.AsyncCommitBuffer = 0
ssCfg := config.DefaultStateStoreConfig()
ssCfg.Enable = tc.ssEnabled
ssCfg.AsyncWriteBuffer = 0

store := NewStore(home, log.NewNopLogger(), scCfg, ssCfg, false, []string{})
defer func() { _ = store.Close() }()

iavlKey1 := types.NewKVStoreKey("iavl_store1")
iavlKey2 := types.NewKVStoreKey("iavl_store2")
transientKey := types.NewTransientStoreKey("transient_store")
memKey := types.NewMemoryStoreKey("mem_store")

store.MountStoreWithDB(iavlKey1, types.StoreTypeIAVL, nil)
store.MountStoreWithDB(iavlKey2, types.StoreTypeIAVL, nil)
store.MountStoreWithDB(transientKey, types.StoreTypeTransient, nil)
store.MountStoreWithDB(memKey, types.StoreTypeMemory, nil)
require.NoError(t, store.LoadLatestVersion())

iavl1KV := store.GetStoreByName("iavl_store1").(types.KVStore)
iavl2KV := store.GetStoreByName("iavl_store2").(types.KVStore)
iavl1KV.Set([]byte("k1"), []byte("v1"))
iavl2KV.Set([]byte("k2"), []byte("v2"))
c1 := store.Commit(true)
require.Equal(t, int64(1), c1.Version)

iavl1KV = store.GetStoreByName("iavl_store1").(types.KVStore)
iavl2KV = store.GetStoreByName("iavl_store2").(types.KVStore)
iavl1KV.Set([]byte("k1"), []byte("v1_updated"))
iavl2KV.Set([]byte("k2"), []byte("v2_updated"))
c2 := store.Commit(true)
require.Equal(t, int64(2), c2.Version)

if tc.ssEnabled {
waitUntilSSVersion(t, store, c2.Version)
}

queryVersions := []int64{0, c2.Version}
for _, v := range queryVersions {
cms, err := store.CacheMultiStoreWithVersion(v)
require.NoError(t, err)

iavl1Store := cms.GetKVStore(iavlKey1)
iavl2Store := cms.GetKVStore(iavlKey2)
require.NotNil(t, iavl1Store)
require.NotNil(t, iavl2Store)

if tc.ssEnabled {
require.Equal(t, types.StoreType(state.StoreTypeSSStore), iavl1Store.GetStoreType())
require.Equal(t, types.StoreType(state.StoreTypeSSStore), iavl2Store.GetStoreType())
} else {
require.Equal(t, types.StoreTypeIAVL, iavl1Store.GetStoreType())
require.Equal(t, types.StoreTypeIAVL, iavl2Store.GetStoreType())
}

transientStore := cms.GetKVStore(transientKey)
memStore := cms.GetKVStore(memKey)
require.NotNil(t, transientStore)
require.NotNil(t, memStore)
require.Equal(t, types.StoreTypeTransient, transientStore.GetStoreType())
require.Equal(t, types.StoreTypeMemory, memStore.GetStoreType())

if v != 0 {
require.Equal(t, []byte("v1_updated"), iavl1Store.Get([]byte("k1")))
require.Equal(t, []byte("v2_updated"), iavl2Store.Get([]byte("k2")))
}
}

if !tc.ssEnabled {
cmsHistorical, err := store.CacheMultiStoreWithVersion(c1.Version)
require.NoError(t, err)
require.Panics(t, func() { _ = cmsHistorical.GetKVStore(iavlKey1) })
require.Panics(t, func() { _ = cmsHistorical.GetKVStore(iavlKey2) })
}
})
}
}
Loading