feat(store/v2): Fallback to SC on queries (#19090)
This commit is contained in:
+24
-9
@@ -105,13 +105,13 @@ func (s *Store) StateLatest() (uint64, store.ReadOnlyRootStore, error) {
|
||||
}
|
||||
|
||||
func (s *Store) StateAt(v uint64) (store.ReadOnlyRootStore, error) {
|
||||
// TODO(bez): Ensure the version <v> exists. We can utilize the GetCommitInfo()
|
||||
// SC method once available.
|
||||
// TODO(bez): We may want to avoid relying on the SC metadata here. Instead,
|
||||
// we should add a VersionExists() method to the VersionedDatabase interface.
|
||||
//
|
||||
// Ref: https://github.com/cosmos/cosmos-sdk/pull/18736
|
||||
// if err := s.stateCommitment.GetCommitInfo(v); err != nil {
|
||||
// return nil, fmt.Errorf("failed to get commit info for version %d: %w", v, err)
|
||||
// }
|
||||
// Ref: https://github.com/cosmos/cosmos-sdk/issues/19091
|
||||
if cInfo, err := s.stateCommitment.GetCommitInfo(v); err != nil || cInfo == nil {
|
||||
return nil, fmt.Errorf("failed to get commit info for version %d: %w", v, err)
|
||||
}
|
||||
|
||||
return NewReadOnlyAdapter(v, s), nil
|
||||
}
|
||||
@@ -174,8 +174,23 @@ func (s *Store) Query(storeKey string, version uint64, key []byte, prove bool) (
|
||||
}
|
||||
|
||||
val, err := s.stateStore.Get(storeKey, version, key)
|
||||
if err != nil {
|
||||
return store.QueryResult{}, err
|
||||
if err != nil || val == nil {
|
||||
// fallback to querying SC backend if not found in SS backend
|
||||
//
|
||||
// Note, this should only used during migration, i.e. while SS and IAVL v2
|
||||
// are being asynchronously synced.
|
||||
if val == nil {
|
||||
bz, scErr := s.stateCommitment.Get(storeKey, version, key)
|
||||
if scErr != nil {
|
||||
return store.QueryResult{}, fmt.Errorf("failed to query SC store: %w", scErr)
|
||||
}
|
||||
|
||||
val = bz
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return store.QueryResult{}, fmt.Errorf("failed to query SS store: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
result := store.QueryResult{
|
||||
@@ -187,7 +202,7 @@ func (s *Store) Query(storeKey string, version uint64, key []byte, prove bool) (
|
||||
if prove {
|
||||
result.ProofOps, err = s.stateCommitment.GetProof(storeKey, version, key)
|
||||
if err != nil {
|
||||
return store.QueryResult{}, err
|
||||
return store.QueryResult{}, fmt.Errorf("failed to get SC store proof: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,31 @@ func (s *RootStoreTestSuite) TestQuery() {
|
||||
s.Require().Equal([]byte("foo"), result.ProofOps[0].Key)
|
||||
}
|
||||
|
||||
func (s *RootStoreTestSuite) TestGetFallback() {
|
||||
sc := s.rootStore.GetStateCommitment()
|
||||
|
||||
// create a changeset and commit it to SC ONLY
|
||||
cs := store.NewChangeset()
|
||||
cs.Add(testStoreKey, []byte("foo"), []byte("bar"))
|
||||
|
||||
err := sc.WriteBatch(cs)
|
||||
s.Require().NoError(err)
|
||||
|
||||
ci := sc.WorkingCommitInfo(1)
|
||||
_, err = sc.Commit(ci.Version)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// ensure we can query for the key, which should fallback to SC
|
||||
qResult, err := s.rootStore.Query(testStoreKey, 1, []byte("foo"), false)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([]byte("bar"), qResult.Value)
|
||||
|
||||
// non-existent key
|
||||
qResult, err = s.rootStore.Query(testStoreKey, 1, []byte("non_existent_key"), false)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Nil(qResult.Value)
|
||||
}
|
||||
|
||||
func (s *RootStoreTestSuite) TestQueryProof() {
|
||||
cs := store.NewChangeset()
|
||||
// testStoreKey
|
||||
|
||||
Reference in New Issue
Block a user