From f41289978b3782e79841162ec8d318b489872a8e Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Mon, 30 Jun 2025 15:32:02 +0700 Subject: [PATCH 1/8] fix(state): Change StorageState.TrieState() to expect a block hash Before, it expected a state root hash. This also fixes notifications for the state_subscribeStorage RPC call. --- dot/core/messages.go | 5 +-- dot/core/messages_test.go | 11 ++++--- dot/core/mock_state_test.go | 8 ++--- dot/core/service.go | 25 ++------------- dot/core/service_integration_test.go | 3 +- dot/core/service_test.go | 33 ------------------- dot/state/inmemory_storage.go | 39 ++++++++++++++++------- dot/state/inmemory_storage_test.go | 36 +++------------------ dot/state/storage_notify.go | 17 ++++++---- dot/state/storage_notify_test.go | 5 ++- dot/state/storage_state.go | 2 +- dot/sync/block_importer.go | 6 ++-- internal/client/adapter/client_adapter.go | 13 ++++++-- lib/babe/babe.go | 6 ++-- lib/babe/mock_storage_state_test.go | 8 ++--- 15 files changed, 84 insertions(+), 133 deletions(-) diff --git a/dot/core/messages.go b/dot/core/messages.go index b8e907899f..83f30ba390 100644 --- a/dot/core/messages.go +++ b/dot/core/messages.go @@ -19,10 +19,11 @@ func (s *Service) validateTransaction(head *types.Header, rt runtime.Instance, tx types.Extrinsic) (validity *transaction.Validity, err error) { s.storageState.Lock() - ts, err := s.storageState.TrieState(&head.StateRoot) + bhash := head.Hash() + ts, err := s.storageState.TrieState(&bhash) s.storageState.Unlock() if err != nil { - return nil, fmt.Errorf("cannot get trie state from storage for root %s: %w", head.StateRoot, err) + return nil, fmt.Errorf("cannot get trie state from storage for block hash %s: %w", bhash.String(), err) } rt.SetContextStorage(ts) diff --git a/dot/core/messages_test.go b/dot/core/messages_test.go index 77f92e929c..111a0b68ee 100644 --- a/dot/core/messages_test.go +++ b/dot/core/messages_test.go @@ -114,6 +114,7 @@ func TestService_TransactionsCount(t *testing.T) { func TestServiceHandleTransactionMessage(t *testing.T) { testEmptyHeader := types.NewEmptyHeader() + headerHash := testEmptyHeader.Hash() testExtrinsic := []types.Extrinsic{{1, 2, 3}} ctrl := gomock.NewController(t) @@ -222,7 +223,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { }, }, mockStorageState: &mockStorageState{ - input: &common.Hash{}, + input: &headerHash, err: errDummyErr, }, args: args{ @@ -232,8 +233,8 @@ func TestServiceHandleTransactionMessage(t *testing.T) { }, }, expErr: errDummyErr, - expErrMsg: "validating transaction from peerID D1KeRhQ: cannot get trie state from storage" + - " for root 0x0000000000000000000000000000000000000000000000000000000000000000: dummy error for testing", + expErrMsg: "validating transaction from peerID D1KeRhQ: cannot get trie state from storage for block " + + "hash 0xdcdd89927d8a348e00257e1ecc8617f45edb5118efff3ea2f9961b2ad9b7690a: dummy error for testing", }, { name: "runtime.ErrInvalidTransaction", @@ -257,7 +258,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { callsBestBlockHash: true, }, mockStorageState: &mockStorageState{ - input: &common.Hash{}, + input: &headerHash, trieState: &storage.InMemoryTrieState{}, }, mockRuntime: &mockRuntime{ @@ -301,7 +302,7 @@ func TestServiceHandleTransactionMessage(t *testing.T) { callsBestBlockHash: true, }, mockStorageState: &mockStorageState{ - input: &common.Hash{}, + input: &headerHash, trieState: &storage.InMemoryTrieState{}, }, mockTxnState: &mockTxnState{ diff --git a/dot/core/mock_state_test.go b/dot/core/mock_state_test.go index b09a7e0d37..020af0cb28 100644 --- a/dot/core/mock_state_test.go +++ b/dot/core/mock_state_test.go @@ -1130,18 +1130,18 @@ func (mr *MockStorageStateMockRecorder) StoreTrie(arg0, arg1 any) *gomock.Call { } // TrieState mocks base method. -func (m *MockStorageState) TrieState(root *common.Hash) (storage0.TrieState, error) { +func (m *MockStorageState) TrieState(bhash *common.Hash) (storage0.TrieState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TrieState", root) + ret := m.ctrl.Call(m, "TrieState", bhash) ret0, _ := ret[0].(storage0.TrieState) ret1, _ := ret[1].(error) return ret0, ret1 } // TrieState indicates an expected call of TrieState. -func (mr *MockStorageStateMockRecorder) TrieState(root any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) TrieState(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrieState", reflect.TypeOf((*MockStorageState)(nil).TrieState), root) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrieState", reflect.TypeOf((*MockStorageState)(nil).TrieState), bhash) } // Unlock mocks base method. diff --git a/dot/core/service.go b/dot/core/service.go index 018953b984..53e0c69063 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -487,13 +487,7 @@ func (s *Service) maintainTransactionPool(block *types.Block, bestBlockHash comm s.transactionState.RemoveExtrinsic(ext) } - stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) - if err != nil { - logger.Errorf("could not get state root from block %s: %w", bestBlockHash, err) - return err - } - - ts, err := s.storageState.TrieState(stateRoot) + ts, err := s.storageState.TrieState(&bestBlockHash) if err != nil { logger.Errorf(err.Error()) return err @@ -586,12 +580,7 @@ func (s *Service) HandleSubmittedExtrinsic(ext types.Extrinsic) error { bestBlockHash := s.blockState.BestBlockHash() - stateRoot, err := s.storageState.GetStateRootFromBlock(&bestBlockHash) - if err != nil { - return fmt.Errorf("could not get state root from block %s: %w", bestBlockHash, err) - } - - ts, err := s.storageState.TrieState(stateRoot) + ts, err := s.storageState.TrieState(&bestBlockHash) if err != nil { return err } @@ -679,15 +668,7 @@ func (s *Service) buildExternalTransaction(rt runtime.Instance, ext types.Extrin func prepareRuntime(blockHash *common.Hash, storageState state.StorageState, blockState state.BlockState) (instance runtime.Instance, err error) { - var stateRootHash *common.Hash - if blockHash != nil { - stateRootHash, err = storageState.GetStateRootFromBlock(blockHash) - if err != nil { - return nil, fmt.Errorf("getting state root from block hash: %w", err) - } - } - - trieState, err := storageState.TrieState(stateRootHash) + trieState, err := storageState.TrieState(blockHash) if err != nil { return nil, fmt.Errorf("getting trie state: %w", err) } diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index f235df7085..fbb9adcfd1 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -589,9 +589,8 @@ func TestService_HandleRuntimeChanges(t *testing.T) { require.NoError(t, err) genesisBlockHash := genesisHeader.Hash() - genesisStateRoot := genesisHeader.StateRoot - ts, err := s.storageState.TrieState(&genesisStateRoot) // Pass genesis root + ts, err := s.storageState.TrieState(&genesisBlockHash) require.NoError(t, err) firstBlockHash := createBlockUsingOldRuntime(t, genesisBlockHash, ts, s.blockState) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 7065e250bd..81c8b2da03 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -651,7 +651,6 @@ func Test_Service_maintainTransactionPool(t *testing.T) { mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{1}).Return(&rtstorage.InMemoryTrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{1}).Return(&common.Hash{1}, nil) service := &Service{ transactionState: mockTxnState, blockState: mockBlockState, @@ -718,7 +717,6 @@ func Test_Service_maintainTransactionPool(t *testing.T) { mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{1}).Return(&rtstorage.InMemoryTrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{1}).Return(&common.Hash{1}, nil) service := &Service{ transactionState: mockTxnState, blockState: mockBlockStateOk, @@ -1158,23 +1156,10 @@ func TestServiceGetRuntimeVersion(t *testing.T) { assert.Equal(t, exp, res) } - t.Run("get_state_root_err", func(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(nil, errDummyErr) - service := &Service{ - storageState: mockStorageState, - } - const expectedErrMessage = "setting up runtime: getting state root from block hash: dummy error for testing" - execTest(t, service, &common.Hash{}, runtime.Version{}, errDummyErr, expectedErrMessage) - }) - t.Run("trie_state_err", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(nil, errDummyErr) service := &Service{ storageState: mockStorageState, @@ -1187,7 +1172,6 @@ func TestServiceGetRuntimeVersion(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(ts, nil).MaxTimes(2) mockBlockState := NewMockBlockState(ctrl) @@ -1204,7 +1188,6 @@ func TestServiceGetRuntimeVersion(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil).MaxTimes(2) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(ts, nil).MaxTimes(2) runtimeMock := NewMockInstance(ctrl) @@ -1248,7 +1231,6 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { ctrl := gomock.NewController(t) mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(nil, errDummyErr) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) mockBlockState := NewMockBlockState(ctrl) mockBlockState.EXPECT().BestBlockHash().Return(common.Hash{}) @@ -1273,7 +1255,6 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.InMemoryTrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) mockTxnState := NewMockTransactionState(ctrl) mockTxnState.EXPECT().Exists(nil).MaxTimes(2) @@ -1297,7 +1278,6 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.InMemoryTrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) mockTxnState := NewMockTransactionState(ctrl) mockTxnState.EXPECT().Exists(types.Extrinsic{}) @@ -1354,7 +1334,6 @@ func TestServiceHandleSubmittedExtrinsic(t *testing.T) { mockStorageState := NewMockStorageState(ctrl) mockStorageState.EXPECT().TrieState(&common.Hash{}).Return(&rtstorage.InMemoryTrieState{}, nil) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(&common.Hash{}, nil) mockTxnState := NewMockTransactionState(ctrl) mockTxnState.EXPECT().Exists(types.Extrinsic{}).MaxTimes(2) @@ -1383,18 +1362,6 @@ func TestServiceGetMetadata(t *testing.T) { assert.Equal(t, exp, res) } - t.Run("get_state_root_error", func(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - mockStorageState := NewMockStorageState(ctrl) - mockStorageState.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(nil, errDummyErr) - service := &Service{ - storageState: mockStorageState, - } - const expectedErrMessage = "setting up runtime: getting state root from block hash: dummy error for testing" - execTest(t, service, &common.Hash{}, nil, errDummyErr, expectedErrMessage) - }) - t.Run("trie_state_error", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index 86d205141a..8fb2bf4abd 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -23,7 +23,7 @@ var storagePrefix = "storage" var codeKey = common.CodeKey // ErrTrieDoesNotExist is returned when attempting to interact with a trie that is not stored in the StorageState -var ErrTrieDoesNotExist = errors.New("trie with given root does not exist") +var ErrTrieDoesNotExist = errors.New("trie for given state root does not exist") func errTrieDoesNotExist(hash common.Hash) error { return fmt.Errorf("%w: %s", ErrTrieDoesNotExist, hash) @@ -98,31 +98,46 @@ func (s *InmemoryStorageState) StoreTrie(ts storage.TrieState, header *types.Hea } } - go s.notifyAll(root) + var bhash *common.Hash + if header != nil { + h := header.Hash() + bhash = &h + } + + go s.notifyAll(root, bhash) return nil } -// TrieState returns the TrieState for a given state root. -// If no state root is provided, it returns the TrieState for the current chain head. -func (s *InmemoryStorageState) TrieState(root *common.Hash) (storage.TrieState, error) { - if root == nil { +// TrieState returns the TrieState for a given block hash. +// If no block hash is provided, it returns the TrieState for the current chain head. +func (s *InmemoryStorageState) TrieState(bhash *common.Hash) (storage.TrieState, error) { + if bhash == nil { header, err := s.blockState.BestBlockHeader() if err != nil { - return nil, fmt.Errorf("while getting best block state root: %w", err) + return nil, fmt.Errorf("while getting best block header: %w", err) } - root = &header.StateRoot + h := header.Hash() + bhash = &h } - t := s.tries.get(*root) + root, err := s.GetStateRootFromBlock(bhash) + if err != nil { + return nil, fmt.Errorf("getting state root for block hash %s: %w", bhash.String(), err) + } + return s.trieStateByRoot(*root) +} + +func (s *InmemoryStorageState) trieStateByRoot(root common.Hash) (storage.TrieState, error) { + t := s.tries.get(root) if t == nil { var err error - t, err = s.LoadFromDB(*root) + t, err = s.LoadFromDB(root) if err != nil { return nil, fmt.Errorf("while loading from database: %w", err) } - s.tries.softSet(*root, t) - } else if t.MustHash() != *root { + s.tries.softSet(root, t) + } else if t.MustHash() != root { panic("trie does not have expected root") } diff --git a/dot/state/inmemory_storage_test.go b/dot/state/inmemory_storage_test.go index 3972d3e80c..bc33f2b827 100644 --- a/dot/state/inmemory_storage_test.go +++ b/dot/state/inmemory_storage_test.go @@ -12,7 +12,6 @@ import ( "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" runtime "github.com/ChainSafe/gossamer/lib/runtime/storage" - "github.com/ChainSafe/gossamer/pkg/trie" "go.uber.org/mock/gomock" "github.com/stretchr/testify/require" @@ -31,7 +30,7 @@ func newTestStorageState(t *testing.T) *InmemoryStorageState { func TestStorage_StoreAndLoadTrie(t *testing.T) { storage := newTestStorageState(t) - ts, err := storage.TrieState(&trie.EmptyHash) + ts, err := storage.TrieState(nil) require.NoError(t, err) root, err := ts.Root() @@ -51,7 +50,7 @@ func TestStorage_StoreAndLoadTrie(t *testing.T) { func TestStorage_GetStorageByBlockHash(t *testing.T) { storage := newTestStorageState(t) - ts, err := storage.TrieState(&trie.EmptyHash) + ts, err := storage.TrieState(nil) require.NoError(t, err) key := []byte("testkey") @@ -84,36 +83,9 @@ func TestStorage_GetStorageByBlockHash(t *testing.T) { require.Equal(t, value, res) } -func TestStorage_TrieState(t *testing.T) { - storage := newTestStorageState(t) - ts, err := storage.TrieState(&trie.EmptyHash) - require.NoError(t, err) - ts.Put([]byte("noot"), []byte("washere")) - - root, err := ts.Root() - require.NoError(t, err) - err = storage.StoreTrie(ts, nil) - require.NoError(t, err) - - time.Sleep(time.Millisecond * 100) - - // get trie from db - storage.blockState.GetTries().delete(root) - ts3, err := storage.TrieState(&root) - require.NoError(t, err) - - tsRoot, err := ts.Root() - require.NoError(t, err) - - ts3Root, err := ts3.Root() - require.NoError(t, err) - - require.Equal(t, tsRoot, ts3Root) -} - func TestStorage_LoadFromDB(t *testing.T) { storage := newTestStorageState(t) - ts, err := storage.TrieState(&trie.EmptyHash) + ts, err := storage.TrieState(nil) require.NoError(t, err) trieKV := []struct { @@ -160,7 +132,7 @@ func TestStorage_LoadFromDB(t *testing.T) { func TestStorage_StoreTrie_NotSyncing(t *testing.T) { storage := newTestStorageState(t) - ts, err := storage.TrieState(&trie.EmptyHash) + ts, err := storage.TrieState(nil) require.NoError(t, err) key := []byte("testkey") diff --git a/dot/state/storage_notify.go b/dot/state/storage_notify.go index 142769dbbe..1f76d42981 100644 --- a/dot/state/storage_notify.go +++ b/dot/state/storage_notify.go @@ -58,7 +58,8 @@ func (s *InmemoryStorageState) RegisterStorageObserver(o Observer) { return } go func() { - if err := s.notifyObserver(header.StateRoot, o); err != nil { + bhash := header.Hash() + if err := s.notifyObserver(header.StateRoot, &bhash, o); err != nil { logger.Warnf("failed to notify storage subscriptions: %s", err) } }() @@ -72,19 +73,19 @@ func (s *InmemoryStorageState) UnregisterStorageObserver(o Observer) { s.observerList = s.removeFromSlice(s.observerList, o) } -func (s *InmemoryStorageState) notifyAll(root common.Hash) { +func (s *InmemoryStorageState) notifyAll(root common.Hash, bhash *common.Hash) { s.observerListMutex.RLock() defer s.observerListMutex.RUnlock() for _, observer := range s.observerList { - err := s.notifyObserver(root, observer) + err := s.notifyObserver(root, bhash, observer) if err != nil { logger.Warnf("failed to notify storage subscriptions: %s", err) } } } -func (s *InmemoryStorageState) notifyObserver(root common.Hash, o Observer) error { - t, err := s.TrieState(&root) +func (s *InmemoryStorageState) notifyObserver(root common.Hash, bhash *common.Hash, o Observer) error { + t, err := s.trieStateByRoot(root) if err != nil { return err } @@ -93,8 +94,12 @@ func (s *InmemoryStorageState) notifyObserver(root common.Hash, o Observer) erro return errTrieDoesNotExist(root) } + if bhash == nil { + bhash = &common.EmptyHash + } + subRes := &SubscriptionResult{ - Hash: root, + Hash: *bhash, } if len(o.GetFilter()) == 0 { // no filter, so send all changes diff --git a/dot/state/storage_notify_test.go b/dot/state/storage_notify_test.go index 1597a831d1..df62afaace 100644 --- a/dot/state/storage_notify_test.go +++ b/dot/state/storage_notify_test.go @@ -44,9 +44,8 @@ func TestStorageState_RegisterStorageObserver(t *testing.T) { ss.RegisterStorageObserver(mockobs) defer ss.UnregisterStorageObserver(mockobs) - ts.Put([]byte("mackcom"), []byte("wuz here")) - err = ss.StoreTrie(ts, nil) - require.NoError(t, err) + require.NoError(t, ts.Put([]byte("mackcom"), []byte("wuz here"))) + require.NoError(t, ss.StoreTrie(ts, nil)) // We need to wait since GetFilter and Update are called // in fire and forget goroutines. Not ideal, but it's out of scope diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index ef14dca0f3..bc6fdd3b9f 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -13,7 +13,7 @@ import ( ) type StorageState interface { - TrieState(root *common.Hash) (rtstorage.TrieState, error) + TrieState(bhash *common.Hash) (rtstorage.TrieState, error) StoreTrie(rtstorage.TrieState, *types.Header) error GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) diff --git a/dot/sync/block_importer.go b/dot/sync/block_importer.go index 63abc89279..a6c4ec8213 100644 --- a/dot/sync/block_importer.go +++ b/dot/sync/block_importer.go @@ -4,7 +4,6 @@ package sync import ( - "bytes" "encoding/json" "errors" "fmt" @@ -194,7 +193,8 @@ func (b *blockImporter) handleBlock(block *types.Block) error { b.storageState.Lock() defer b.storageState.Unlock() - ts, err := b.storageState.TrieState(&parent.StateRoot) + parentHash := parent.Hash() + ts, err := b.storageState.TrieState(&parentHash) if err != nil { return err } @@ -204,7 +204,7 @@ func (b *blockImporter) handleBlock(block *types.Block) error { return err } - if !bytes.Equal(parent.StateRoot[:], root[:]) { + if parent.StateRoot != root { panic("parent state root does not match snapshot state root") } diff --git a/internal/client/adapter/client_adapter.go b/internal/client/adapter/client_adapter.go index cfd4a93528..872c573bd8 100644 --- a/internal/client/adapter/client_adapter.go +++ b/internal/client/adapter/client_adapter.go @@ -614,8 +614,17 @@ func (ca *ClientAdapter[H, Hasher, N, E, Header]) Pause() error { panic("unimplemented") } -func (ca *ClientAdapter[H, Hasher, N, E, Header]) TrieState(root *common.Hash) (rtstorage.TrieState, error) { - stateAt, err := ca.getStateByStateRoot(root) +func (ca *ClientAdapter[H, Hasher, N, E, Header]) TrieState(bhash *common.Hash) (rtstorage.TrieState, error) { + var hash H + + if bhash == nil { + hash = ca.client.Info().BestHash + } else { + hasher := *new(Hasher) + hash = hasher.NewHash(bhash.ToBytes()) + } + + stateAt, err := ca.client.StateAt(hash) if err != nil { return nil, err } diff --git a/lib/babe/babe.go b/lib/babe/babe.go index 77fa395264..80f9c369bc 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -433,9 +433,11 @@ func (b *Service) handleSlot(epoch uint64, slot Slot, // set runtime trie before building block // if block building is successful, store the resulting trie in the storage state - ts, err := b.storageState.TrieState(&parent.StateRoot) + parentHash := parent.Hash() + ts, err := b.storageState.TrieState(&parentHash) if err != nil || ts == nil { - logger.Errorf("failed to get parent trie with parent state root %s: %s", parent.StateRoot, err) + err = fmt.Errorf("failed to get parent trie for block hash %s: %w", parentHash.String(), err) + logger.Error(err.Error()) return err } diff --git a/lib/babe/mock_storage_state_test.go b/lib/babe/mock_storage_state_test.go index 7af63f9ea1..caf2db330d 100644 --- a/lib/babe/mock_storage_state_test.go +++ b/lib/babe/mock_storage_state_test.go @@ -248,18 +248,18 @@ func (mr *MockStorageStateMockRecorder) StoreTrie(arg0, arg1 any) *gomock.Call { } // TrieState mocks base method. -func (m *MockStorageState) TrieState(root *common.Hash) (storage.TrieState, error) { +func (m *MockStorageState) TrieState(bhash *common.Hash) (storage.TrieState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TrieState", root) + ret := m.ctrl.Call(m, "TrieState", bhash) ret0, _ := ret[0].(storage.TrieState) ret1, _ := ret[1].(error) return ret0, ret1 } // TrieState indicates an expected call of TrieState. -func (mr *MockStorageStateMockRecorder) TrieState(root any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) TrieState(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrieState", reflect.TypeOf((*MockStorageState)(nil).TrieState), root) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrieState", reflect.TypeOf((*MockStorageState)(nil).TrieState), bhash) } // Unlock mocks base method. From 1b1c4d6c3c25e727fc42aa32586aeff578270161 Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Tue, 1 Jul 2025 19:23:15 +0700 Subject: [PATCH 2/8] fix(state): Change StorageState.GetStorage() to expect a block hash --- dot/core/mock_state_test.go | 23 ++----- dot/node.go | 2 +- dot/node_integration_test.go | 2 +- dot/rpc/interfaces.go | 3 +- dot/rpc/modules/api.go | 3 +- dot/rpc/modules/api_mocks.go | 2 - dot/rpc/modules/mocks/mocks.go | 23 ++----- dot/rpc/modules/mocks_test.go | 23 ++----- dot/rpc/modules/state.go | 70 ++++++------------- dot/rpc/modules/state_integration_test.go | 8 +-- dot/rpc/modules/state_test.go | 83 ++++++++++++----------- dot/state/initialize.go | 2 +- dot/state/inmemory_storage.go | 52 +++++--------- dot/state/inmemory_storage_test.go | 28 ++++++-- dot/state/storage_state.go | 3 +- lib/babe/mock_storage_state_test.go | 23 ++----- 16 files changed, 130 insertions(+), 220 deletions(-) diff --git a/dot/core/mock_state_test.go b/dot/core/mock_state_test.go index 020af0cb28..af18246221 100644 --- a/dot/core/mock_state_test.go +++ b/dot/core/mock_state_test.go @@ -987,33 +987,18 @@ func (mr *MockStorageStateMockRecorder) GetStateRootFromBlock(bhash any) *gomock } // GetStorage mocks base method. -func (m *MockStorageState) GetStorage(root *common.Hash, key []byte) ([]byte, error) { +func (m *MockStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorage", root, key) + ret := m.ctrl.Call(m, "GetStorage", bhash, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorage indicates an expected call of GetStorage. -func (mr *MockStorageStateMockRecorder) GetStorage(root, key any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetStorage(bhash, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageState)(nil).GetStorage), root, key) -} - -// GetStorageByBlockHash mocks base method. -func (m *MockStorageState) GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageByBlockHash", bhash, key) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStorageByBlockHash indicates an expected call of GetStorageByBlockHash. -func (mr *MockStorageStateMockRecorder) GetStorageByBlockHash(bhash, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageByBlockHash", reflect.TypeOf((*MockStorageState)(nil).GetStorageByBlockHash), bhash, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageState)(nil).GetStorage), bhash, key) } // GetStorageChild mocks base method. diff --git a/dot/node.go b/dot/node.go index d6ee8c4699..088edce771 100644 --- a/dot/node.go +++ b/dot/node.go @@ -525,7 +525,7 @@ func (nodeBuilder) loadRuntime(config *cfg.Config, ns *runtime.NodeStorage, runtimeCode := make(map[string]runtime.Instance) for i := range blocks { hash := &blocks[i] - code, err := stateSrvc.Storage.GetStorageByBlockHash(hash, []byte(":code")) + code, err := stateSrvc.Storage.GetStorage(hash, []byte(":code")) if err != nil { return err } diff --git a/dot/node_integration_test.go b/dot/node_integration_test.go index 39b0ea403a..7c9a497e39 100644 --- a/dot/node_integration_test.go +++ b/dot/node_integration_test.go @@ -197,7 +197,7 @@ func Test_nodeBuilder_loadRuntime(t *testing.T) { blocks := stateSrvc.Block.GetNonFinalisedBlocks() for i := range blocks { hash := &blocks[i] - code, err := stateSrvc.Storage.GetStorageByBlockHash(hash, []byte(":code")) + code, err := stateSrvc.Storage.GetStorage(hash, []byte(":code")) require.NoError(t, err) require.NotEmpty(t, code) } diff --git a/dot/rpc/interfaces.go b/dot/rpc/interfaces.go index cecffba680..6c3f8d802d 100644 --- a/dot/rpc/interfaces.go +++ b/dot/rpc/interfaces.go @@ -20,10 +20,9 @@ import ( // StorageAPI is the interface for the storage state type StorageAPI interface { - GetStorage(root *common.Hash, key []byte) ([]byte, error) + GetStorage(bhash *common.Hash, key []byte) ([]byte, error) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) - GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) Entries(root *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) diff --git a/dot/rpc/modules/api.go b/dot/rpc/modules/api.go index 9abc40a4d8..35c15ecabc 100644 --- a/dot/rpc/modules/api.go +++ b/dot/rpc/modules/api.go @@ -18,10 +18,9 @@ import ( // StorageAPI is the interface for the storage state type StorageAPI interface { - GetStorage(root *common.Hash, key []byte) ([]byte, error) + GetStorage(bhash *common.Hash, key []byte) ([]byte, error) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) - GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) Entries(root *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) diff --git a/dot/rpc/modules/api_mocks.go b/dot/rpc/modules/api_mocks.go index 931d14ec05..10908b3550 100644 --- a/dot/rpc/modules/api_mocks.go +++ b/dot/rpc/modules/api_mocks.go @@ -18,8 +18,6 @@ func NewMockAnyStorageAPI(ctrl *gomock.Controller) *modulesmocks.MockStorageAPI m.EXPECT().GetStorageFromChild(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil).AnyTimes() m.EXPECT().Entries(gomock.Any()).Return(nil, nil).AnyTimes() - m.EXPECT().GetStorageByBlockHash(gomock.Any(), gomock.Any()). - Return(nil, nil).AnyTimes() m.EXPECT().RegisterStorageObserver(gomock.Any()).AnyTimes() m.EXPECT().UnregisterStorageObserver(gomock.Any()).AnyTimes() m.EXPECT().GetStateRootFromBlock(gomock.Any()).Return(nil, nil).AnyTimes() diff --git a/dot/rpc/modules/mocks/mocks.go b/dot/rpc/modules/mocks/mocks.go index f951c97339..7e96919fa5 100644 --- a/dot/rpc/modules/mocks/mocks.go +++ b/dot/rpc/modules/mocks/mocks.go @@ -95,33 +95,18 @@ func (mr *MockStorageAPIMockRecorder) GetStateRootFromBlock(bhash any) *gomock.C } // GetStorage mocks base method. -func (m *MockStorageAPI) GetStorage(root *common.Hash, key []byte) ([]byte, error) { +func (m *MockStorageAPI) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorage", root, key) + ret := m.ctrl.Call(m, "GetStorage", bhash, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorage indicates an expected call of GetStorage. -func (mr *MockStorageAPIMockRecorder) GetStorage(root, key any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetStorage(bhash, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageAPI)(nil).GetStorage), root, key) -} - -// GetStorageByBlockHash mocks base method. -func (m *MockStorageAPI) GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageByBlockHash", bhash, key) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStorageByBlockHash indicates an expected call of GetStorageByBlockHash. -func (mr *MockStorageAPIMockRecorder) GetStorageByBlockHash(bhash, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageByBlockHash", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageByBlockHash), bhash, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageAPI)(nil).GetStorage), bhash, key) } // GetStorageChild mocks base method. diff --git a/dot/rpc/modules/mocks_test.go b/dot/rpc/modules/mocks_test.go index a7be064aba..fd4b73bf6a 100644 --- a/dot/rpc/modules/mocks_test.go +++ b/dot/rpc/modules/mocks_test.go @@ -91,33 +91,18 @@ func (mr *MockStorageAPIMockRecorder) GetStateRootFromBlock(bhash any) *gomock.C } // GetStorage mocks base method. -func (m *MockStorageAPI) GetStorage(root *common.Hash, key []byte) ([]byte, error) { +func (m *MockStorageAPI) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorage", root, key) + ret := m.ctrl.Call(m, "GetStorage", bhash, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorage indicates an expected call of GetStorage. -func (mr *MockStorageAPIMockRecorder) GetStorage(root, key any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetStorage(bhash, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageAPI)(nil).GetStorage), root, key) -} - -// GetStorageByBlockHash mocks base method. -func (m *MockStorageAPI) GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageByBlockHash", bhash, key) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStorageByBlockHash indicates an expected call of GetStorageByBlockHash. -func (mr *MockStorageAPIMockRecorder) GetStorageByBlockHash(bhash, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageByBlockHash", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageByBlockHash), bhash, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageAPI)(nil).GetStorage), bhash, key) } // GetStorageChild mocks base method. diff --git a/dot/rpc/modules/state.go b/dot/rpc/modules/state.go index 742b023f6f..58502ea10b 100644 --- a/dot/rpc/modules/state.go +++ b/dot/rpc/modules/state.go @@ -234,7 +234,7 @@ func (sm *StateModule) GetPairs(_ *http.Request, req *StatePairRequest, res *Sta *res = make([]interface{}, len(keys)) for i, key := range keys { - val, err := sm.storageAPI.GetStorage(stateRootHash, key) + val, err := sm.storageAPI.GetStorage(req.Bhash, key) if err != nil { return err } @@ -362,24 +362,15 @@ func (sm *StateModule) GetRuntimeVersion( // GetStorage Returns a storage entry at a specific block's state. // If not block hash is provided, the latest value is returned. func (sm *StateModule) GetStorage( - _ *http.Request, req *StateStorageRequest, res *StateStorageResponse) error { - var ( - item []byte - err error - ) - + _ *http.Request, + req *StateStorageRequest, + res *StateStorageResponse, +) error { reqBytes, _ := common.HexToBytes(req.Key) // no need to catch error here - if req.Bhash != nil { - item, err = sm.storageAPI.GetStorageByBlockHash(req.Bhash, reqBytes) - if err != nil { - return err - } - } else { - item, err = sm.storageAPI.GetStorage(nil, reqBytes) - if err != nil { - return err - } + item, err := sm.storageAPI.GetStorage(req.Bhash, reqBytes) + if err != nil { + return err } if len(item) > 0 { @@ -392,24 +383,15 @@ func (sm *StateModule) GetStorage( // GetStorageHash returns the blake2b hash of a storage entry at a block's state. // If no block hash is provided, the latest value is returned. func (sm *StateModule) GetStorageHash( - _ *http.Request, req *StateStorageHashRequest, res *StateStorageHashResponse) error { - var ( - item []byte - err error - ) - + _ *http.Request, + req *StateStorageHashRequest, + res *StateStorageHashResponse, +) error { reqBytes, _ := common.HexToBytes(req.Key) - if req.Bhash != nil { - item, err = sm.storageAPI.GetStorageByBlockHash(req.Bhash, reqBytes) - if err != nil { - return err - } - } else { - item, err = sm.storageAPI.GetStorage(nil, reqBytes) - if err != nil { - return err - } + item, err := sm.storageAPI.GetStorage(req.Bhash, reqBytes) + if err != nil { + return err } hash, err := common.Blake2bHash(item) @@ -425,23 +407,11 @@ func (sm *StateModule) GetStorageHash( // If no block hash is provided, the latest value is used. func (sm *StateModule) GetStorageSize( _ *http.Request, req *StateStorageSizeRequest, res *StateStorageSizeResponse) error { - var ( - item []byte - err error - ) - reqBytes, _ := common.HexToBytes(req.Key) - if req.Bhash != nil { - item, err = sm.storageAPI.GetStorageByBlockHash(req.Bhash, reqBytes) - if err != nil { - return err - } - } else { - item, err = sm.storageAPI.GetStorage(nil, reqBytes) - if err != nil { - return err - } + item, err := sm.storageAPI.GetStorage(req.Bhash, reqBytes) + if err != nil { + return err } if len(item) > 0 { @@ -487,7 +457,7 @@ func (sm *StateModule) QueryStorage( changes := make([][2]*string, 0, len(req.Keys)) for j, key := range req.Keys { - value, err := sm.storageAPI.GetStorageByBlockHash(&blockHash, common.MustHexToBytes(key)) + value, err := sm.storageAPI.GetStorage(&blockHash, common.MustHexToBytes(key)) if err != nil { return fmt.Errorf("getting value by block hash: %w", err) } @@ -531,7 +501,7 @@ func (sm *StateModule) QueryStorageAt( changes := make([][2]*string, len(request.Keys)) for i, key := range request.Keys { - value, err := sm.storageAPI.GetStorageByBlockHash(&atBlockHash, common.MustHexToBytes(key)) + value, err := sm.storageAPI.GetStorage(&atBlockHash, common.MustHexToBytes(key)) if err != nil { return fmt.Errorf("getting value by block hash: %w", err) } diff --git a/dot/rpc/modules/state_integration_test.go b/dot/rpc/modules/state_integration_test.go index ec023f0107..a6cc1c551e 100644 --- a/dot/rpc/modules/state_integration_test.go +++ b/dot/rpc/modules/state_integration_test.go @@ -379,11 +379,11 @@ func TestStateModule_QueryStorage(t *testing.T) { mockBlockAPI.EXPECT().GetHashByNumber(uint(4)).Return(common.Hash{3, 4}, nil) mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{1, 2}, []byte{144}).Return([]byte(`value`), nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{1, 2}, []byte{128}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{1, 2}, []byte{144}).Return([]byte(`value`), nil) + mockStorageAPI.EXPECT().GetStorage(&common.Hash{1, 2}, []byte{128}). Return([]byte(`another value`), nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{3, 4}, []byte{144}).Return([]byte(`value`), nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{3, 4}, []byte{128}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{3, 4}, []byte{144}).Return([]byte(`value`), nil) + mockStorageAPI.EXPECT().GetStorage(&common.Hash{3, 4}, []byte{128}). Return([]byte(`another value`), nil) module := new(StateModule) diff --git a/dot/rpc/modules/state_test.go b/dot/rpc/modules/state_test.go index 3d6a6764eb..e9aa490d9e 100644 --- a/dot/rpc/modules/state_test.go +++ b/dot/rpc/modules/state_test.go @@ -560,14 +560,16 @@ func TestStateModuleGetStorage(t *testing.T) { reqBytes := common.MustHexToBytes("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") mockStorageAPI := mocks.NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&hash, reqBytes).Return([]byte{21}, nil) - mockStorageAPI.EXPECT().GetStorage((*common.Hash)(nil), reqBytes).Return([]byte{21}, nil) + mockStorageAPI.EXPECT().GetStorage((*common.Hash)(nil), reqBytes).Return([]byte{21}, nil).AnyTimes() + mockStorageAPI.EXPECT().GetStorage(&hash, reqBytes).Return([]byte{21}, nil).AnyTimes() mockStorageAPIErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIErr.EXPECT().GetStorageByBlockHash(&hash, reqBytes). - Return(nil, errors.New("GetStorageByBlockHash Error")) mockStorageAPIErr.EXPECT().GetStorage((*common.Hash)(nil), reqBytes). - Return(nil, errors.New("GetStorage Error")) + Return(nil, errors.New("GetStorage Error")). + AnyTimes() + mockStorageAPIErr.EXPECT().GetStorage(&hash, reqBytes). + Return(nil, errors.New("GetStorage Error")). + AnyTimes() type fields struct { networkAPI NetworkAPI @@ -615,7 +617,7 @@ func TestStateModuleGetStorage(t *testing.T) { Bhash: &hash, }, }, - expErr: errors.New("GetStorageByBlockHash Error"), + expErr: errors.New("GetStorage Error"), }, { name: "bHash Nil Err", @@ -654,15 +656,16 @@ func TestStateModuleGetStorageHash(t *testing.T) { reqBytes := common.MustHexToBytes("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") mockStorageAPI := mocks.NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&hash, reqBytes).Return([]byte{21}, nil) - mockStorageAPI.EXPECT().GetStorage((*common.Hash)(nil), reqBytes). - Return([]byte{21}, nil) + mockStorageAPI.EXPECT().GetStorage((*common.Hash)(nil), reqBytes).Return([]byte{21}, nil).AnyTimes() + mockStorageAPI.EXPECT().GetStorage(&hash, reqBytes).Return([]byte{21}, nil).AnyTimes() mockStorageAPIErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIErr.EXPECT().GetStorageByBlockHash(&hash, reqBytes). - Return(nil, errors.New("GetStorageByBlockHash Error")) mockStorageAPIErr.EXPECT().GetStorage((*common.Hash)(nil), reqBytes). - Return(nil, errors.New("GetStorage Error")) + Return(nil, errors.New("GetStorage Error")). + AnyTimes() + mockStorageAPIErr.EXPECT().GetStorage(&hash, reqBytes). + Return(nil, errors.New("GetStorage Error")). + AnyTimes() type fields struct { networkAPI NetworkAPI @@ -710,7 +713,7 @@ func TestStateModuleGetStorageHash(t *testing.T) { Bhash: &hash, }, }, - expErr: errors.New("GetStorageByBlockHash Error"), + expErr: errors.New("GetStorage Error"), }, { name: "bHash Nil Err", @@ -749,14 +752,16 @@ func TestStateModuleGetStorageSize(t *testing.T) { reqBytes := common.MustHexToBytes("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") mockStorageAPI := mocks.NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&hash, reqBytes).Return([]byte{21}, nil) - mockStorageAPI.EXPECT().GetStorage((*common.Hash)(nil), reqBytes).Return([]byte{21}, nil) + mockStorageAPI.EXPECT().GetStorage((*common.Hash)(nil), reqBytes).Return([]byte{21}, nil).AnyTimes() + mockStorageAPI.EXPECT().GetStorage(&hash, reqBytes).Return([]byte{21}, nil).AnyTimes() mockStorageAPIErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIErr.EXPECT().GetStorageByBlockHash(&hash, reqBytes). - Return(nil, errors.New("GetStorageByBlockHash Error")) mockStorageAPIErr.EXPECT().GetStorage((*common.Hash)(nil), reqBytes). - Return(nil, errors.New("GetStorage Error")) + Return(nil, errors.New("GetStorage Error")). + AnyTimes() + mockStorageAPIErr.EXPECT().GetStorage(&hash, reqBytes). + Return(nil, errors.New("GetStorage Error")). + AnyTimes() type fields struct { networkAPI NetworkAPI @@ -804,7 +809,7 @@ func TestStateModuleGetStorageSize(t *testing.T) { Bhash: &hash, }, }, - expErr: errors.New("GetStorageByBlockHash Error"), + expErr: errors.New("GetStorage Error"), }, { name: "bHash Nil Err", @@ -893,17 +898,17 @@ func TestStateModuleQueryStorage(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) StorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 4}). Return([]byte{1, 1, 1}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{9, 9, 9}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{9, 9, 9}). Return([]byte{9, 9, 9, 9}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{3}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{3}, []byte{1, 2, 4}). Return([]byte{2, 2, 2}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{3}, []byte{9, 9, 9}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{3}, []byte{9, 9, 9}). Return([]byte{9, 9, 9, 9}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{4}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{4}, []byte{1, 2, 4}). Return([]byte{3, 3, 3}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{4}, []byte{9, 9, 9}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{4}, []byte{9, 9, 9}). Return([]byte{9, 9, 9, 9}, nil) return mockStorageAPI }, @@ -951,13 +956,13 @@ func TestStateModuleQueryStorage(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) StorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{1}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{1}, []byte{1, 2, 4}). Return([]byte{1, 1, 1}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 4}). Return([]byte(nil), nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{3}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{3}, []byte{1, 2, 4}). Return([]byte{}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{4}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{4}, []byte{1, 2, 4}). Return([]byte{3, 3, 3}, nil) return mockStorageAPI }, @@ -1011,9 +1016,9 @@ func TestStateModuleQueryStorage(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) StorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 4}). Return([]byte{1, 1, 1}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{3}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{3}, []byte{1, 2, 4}). Return([]byte{1, 1, 1}, nil) return mockStorageAPI }, @@ -1098,7 +1103,7 @@ func TestStateModuleQueryStorage(t *testing.T) { "start_block/end_block/error_get_storage_by_block_hash": { fields: fields{func(ctrl *gomock.Controller) StorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 4}).Return(nil, errTest) + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 4}).Return(nil, errTest) return mockStorageAPI }, func(ctrl *gomock.Controller) BlockAPI { @@ -1164,7 +1169,7 @@ func TestStateModuleQueryStorageAt(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) *MockStorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 3}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 3}). Return([]byte{1, 1, 1}, nil) return mockStorageAPI }, @@ -1189,7 +1194,7 @@ func TestStateModuleQueryStorageAt(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) *MockStorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{1}, []byte{1, 2, 3}).Return(nil, errTest) + mockStorageAPI.EXPECT().GetStorage(&common.Hash{1}, []byte{1, 2, 3}).Return(nil, errTest) return mockStorageAPI }, blockAPIBuilder: func(ctrl *gomock.Controller) *MockBlockAPI { @@ -1206,11 +1211,11 @@ func TestStateModuleQueryStorageAt(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) *MockStorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{8, 8, 8}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{8, 8, 8}). Return([]byte{8, 8, 8, 8}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 4}). Return([]byte{}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{9, 9, 9}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{9, 9, 9}). Return([]byte(nil), nil) return mockStorageAPI }, @@ -1236,9 +1241,9 @@ func TestStateModuleQueryStorageAt(t *testing.T) { fields: fields{ storageAPIBuilder: func(ctrl *gomock.Controller) *MockStorageAPI { mockStorageAPI := NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{1, 2, 4}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{1, 2, 4}). Return([]byte{1, 1, 1}, nil) - mockStorageAPI.EXPECT().GetStorageByBlockHash(&common.Hash{2}, []byte{9, 9, 9}). + mockStorageAPI.EXPECT().GetStorage(&common.Hash{2}, []byte{9, 9, 9}). Return([]byte{9, 9, 9, 9}, nil) return mockStorageAPI }, diff --git a/dot/state/initialize.go b/dot/state/initialize.go index 4760b37bd2..6a2369b724 100644 --- a/dot/state/initialize.go +++ b/dot/state/initialize.go @@ -108,7 +108,7 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t trie. return fmt.Errorf("failed to close database: %s", err) } - logger.Infof("block state hash genesis hash: %s", blockState.genesisHash) + logger.Infof("block state genesis hash: %s", blockState.genesisHash) return nil } diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index 8fb2bf4abd..96d1d19700 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -184,22 +184,28 @@ func (s *InmemoryStorageState) loadTrie(root *common.Hash) (trie.Trie, error) { return tr, nil } -// ExistsStorage check if the key exists in the storage trie with the given storage hash +// ExistsStorage check if the key exists in the storage trie for the given block hash // If no hash is provided, the current chain head is used -func (s *InmemoryStorageState) ExistsStorage(root *common.Hash, key []byte) (bool, error) { - val, err := s.GetStorage(root, key) +func (s *InmemoryStorageState) ExistsStorage(bhash *common.Hash, key []byte) (bool, error) { + val, err := s.GetStorage(bhash, key) return val != nil, err } -// GetStorage gets the object from the trie using the given key and storage hash +// GetStorage gets the object from the trie using the given key and block hash // If no hash is provided, the current chain head is used -func (s *InmemoryStorageState) GetStorage(root *common.Hash, key []byte) ([]byte, error) { - if root == nil { +func (s *InmemoryStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { + if bhash == nil { header, err := s.blockState.BestBlockHeader() if err != nil { return nil, err } - root = &header.StateRoot + h := header.Hash() + bhash = &h + } + + root, err := s.GetStateRootFromBlock(bhash) + if err != nil { + return nil, err } t := s.tries.get(*root) @@ -211,30 +217,6 @@ func (s *InmemoryStorageState) GetStorage(root *common.Hash, key []byte) ([]byte return inmemory_trie.GetFromDB(s.db, *root, key) } -// GetStorageByBlockHash returns the value at the given key at the given block hash -func (s *InmemoryStorageState) GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) { - var ( - root common.Hash - err error - ) - - if bhash != nil { - header, err := s.blockState.GetHeader(*bhash) - if err != nil { - return nil, err - } - - root = header.StateRoot - } else { - root, err = s.StorageRoot() - if err != nil { - return nil, err - } - } - - return s.GetStorage(&root, key) -} - // GetStateRootFromBlock returns the state root hash of a given block hash func (s *InmemoryStorageState) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { if bhash == nil { @@ -302,13 +284,13 @@ func (s *InmemoryStorageState) GetStorageFromChild(root *common.Hash, keyToChild } // LoadCode returns the runtime code (located at :code) -func (s *InmemoryStorageState) LoadCode(hash *common.Hash) ([]byte, error) { - return s.GetStorage(hash, codeKey) +func (s *InmemoryStorageState) LoadCode(bhash *common.Hash) ([]byte, error) { + return s.GetStorage(bhash, codeKey) } // LoadCodeHash returns the hash of the runtime code (located at :code) -func (s *InmemoryStorageState) LoadCodeHash(hash *common.Hash) (common.Hash, error) { - code, err := s.LoadCode(hash) +func (s *InmemoryStorageState) LoadCodeHash(bhash *common.Hash) (common.Hash, error) { + code, err := s.LoadCode(bhash) if err != nil { return common.NewHash([]byte{}), err } diff --git a/dot/state/inmemory_storage_test.go b/dot/state/inmemory_storage_test.go index bc33f2b827..2656eb5543 100644 --- a/dot/state/inmemory_storage_test.go +++ b/dot/state/inmemory_storage_test.go @@ -48,14 +48,14 @@ func TestStorage_StoreAndLoadTrie(t *testing.T) { require.Equal(t, trie.MustHash(), ts2Root) } -func TestStorage_GetStorageByBlockHash(t *testing.T) { +func TestStorage_GetStorage(t *testing.T) { storage := newTestStorageState(t) ts, err := storage.TrieState(nil) require.NoError(t, err) key := []byte("testkey") value := []byte("testvalue") - ts.Put(key, value) + require.NoError(t, ts.Put(key, value)) root, err := ts.Root() require.NoError(t, err) @@ -78,7 +78,7 @@ func TestStorage_GetStorageByBlockHash(t *testing.T) { require.NoError(t, err) hash := block.Header.Hash() - res, err := storage.GetStorageByBlockHash(&hash, key) + res, err := storage.GetStorage(&hash, key) require.NoError(t, err) require.Equal(t, value, res) } @@ -106,14 +106,32 @@ func TestStorage_LoadFromDB(t *testing.T) { root, err := ts.Root() require.NoError(t, err) + // Create a block associated with the trie. + body, err := types.NewBodyFromBytes([]byte{}) + require.NoError(t, err) + + block := &types.Block{ + Header: types.Header{ + ParentHash: testGenesisHeader.Hash(), + Number: 1, + StateRoot: root, + Digest: createPrimaryBABEDigest(t), + }, + Body: *body, + } + // Write trie to disk. - err = storage.StoreTrie(ts, nil) + err = storage.StoreTrie(ts, &block.Header) require.NoError(t, err) + // Add the block to allow lookup by block hash. + require.NoError(t, storage.blockState.AddBlock(block, nil, nil)) + // Clear trie from cache and fetch data from disk. storage.blockState.GetTries().delete(root) - data, err := storage.GetStorage(&root, trieKV[0].key) + hash := block.Header.Hash() + data, err := storage.GetStorage(&hash, trieKV[0].key) require.NoError(t, err) require.Equal(t, trieKV[0].value, data) diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index bc6fdd3b9f..923c58f071 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -18,8 +18,7 @@ type StorageState interface { GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GenerateTrieProof(stateRoot common.Hash, keys [][]byte) ([][]byte, error) - GetStorage(root *common.Hash, key []byte) ([]byte, error) - GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) + GetStorage(bhash *common.Hash, key []byte) ([]byte, error) StorageRoot() (common.Hash, error) Entries(root *common.Hash) (map[string][]byte, error) // should be overhauled to iterate GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) diff --git a/lib/babe/mock_storage_state_test.go b/lib/babe/mock_storage_state_test.go index caf2db330d..58a0e542d4 100644 --- a/lib/babe/mock_storage_state_test.go +++ b/lib/babe/mock_storage_state_test.go @@ -105,33 +105,18 @@ func (mr *MockStorageStateMockRecorder) GetStateRootFromBlock(bhash any) *gomock } // GetStorage mocks base method. -func (m *MockStorageState) GetStorage(root *common.Hash, key []byte) ([]byte, error) { +func (m *MockStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorage", root, key) + ret := m.ctrl.Call(m, "GetStorage", bhash, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorage indicates an expected call of GetStorage. -func (mr *MockStorageStateMockRecorder) GetStorage(root, key any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetStorage(bhash, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageState)(nil).GetStorage), root, key) -} - -// GetStorageByBlockHash mocks base method. -func (m *MockStorageState) GetStorageByBlockHash(bhash *common.Hash, key []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageByBlockHash", bhash, key) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStorageByBlockHash indicates an expected call of GetStorageByBlockHash. -func (mr *MockStorageStateMockRecorder) GetStorageByBlockHash(bhash, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageByBlockHash", reflect.TypeOf((*MockStorageState)(nil).GetStorageByBlockHash), bhash, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorage", reflect.TypeOf((*MockStorageState)(nil).GetStorage), bhash, key) } // GetStorageChild mocks base method. From f6b34578f9a25110c7ff195b9c2b14bf7f881b44 Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Tue, 1 Jul 2025 20:57:11 +0700 Subject: [PATCH 3/8] fix(state): Change StorageState.Entries() to expect a block hash --- dot/core/mock_state_test.go | 8 ++++---- dot/rpc/interfaces.go | 2 +- dot/rpc/modules/api.go | 2 +- dot/rpc/modules/mocks/mocks.go | 8 ++++---- dot/rpc/modules/mocks_test.go | 8 ++++---- dot/rpc/modules/state.go | 2 +- dot/state/inmemory_storage.go | 14 ++++++++++++-- dot/state/inmemory_storage_test.go | 2 +- dot/state/storage_state.go | 2 +- lib/babe/mock_storage_state_test.go | 8 ++++---- 10 files changed, 33 insertions(+), 23 deletions(-) diff --git a/dot/core/mock_state_test.go b/dot/core/mock_state_test.go index af18246221..12b550e877 100644 --- a/dot/core/mock_state_test.go +++ b/dot/core/mock_state_test.go @@ -927,18 +927,18 @@ func (m *MockStorageState) EXPECT() *MockStorageStateMockRecorder { } // Entries mocks base method. -func (m *MockStorageState) Entries(root *common.Hash) (map[string][]byte, error) { +func (m *MockStorageState) Entries(bhash *common.Hash) (map[string][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Entries", root) + ret := m.ctrl.Call(m, "Entries", bhash) ret0, _ := ret[0].(map[string][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Entries indicates an expected call of Entries. -func (mr *MockStorageStateMockRecorder) Entries(root any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) Entries(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageState)(nil).Entries), root) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageState)(nil).Entries), bhash) } // GenerateTrieProof mocks base method. diff --git a/dot/rpc/interfaces.go b/dot/rpc/interfaces.go index 6c3f8d802d..1926da3463 100644 --- a/dot/rpc/interfaces.go +++ b/dot/rpc/interfaces.go @@ -23,7 +23,7 @@ type StorageAPI interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) - Entries(root *common.Hash) (map[string][]byte, error) + Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) RegisterStorageObserver(observer state.Observer) diff --git a/dot/rpc/modules/api.go b/dot/rpc/modules/api.go index 35c15ecabc..57080edb6b 100644 --- a/dot/rpc/modules/api.go +++ b/dot/rpc/modules/api.go @@ -21,7 +21,7 @@ type StorageAPI interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) - Entries(root *common.Hash) (map[string][]byte, error) + Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) RegisterStorageObserver(observer state.Observer) diff --git a/dot/rpc/modules/mocks/mocks.go b/dot/rpc/modules/mocks/mocks.go index 7e96919fa5..99a9cf9447 100644 --- a/dot/rpc/modules/mocks/mocks.go +++ b/dot/rpc/modules/mocks/mocks.go @@ -50,18 +50,18 @@ func (m *MockStorageAPI) EXPECT() *MockStorageAPIMockRecorder { } // Entries mocks base method. -func (m *MockStorageAPI) Entries(root *common.Hash) (map[string][]byte, error) { +func (m *MockStorageAPI) Entries(bhash *common.Hash) (map[string][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Entries", root) + ret := m.ctrl.Call(m, "Entries", bhash) ret0, _ := ret[0].(map[string][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Entries indicates an expected call of Entries. -func (mr *MockStorageAPIMockRecorder) Entries(root any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) Entries(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageAPI)(nil).Entries), root) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageAPI)(nil).Entries), bhash) } // GetKeysWithPrefix mocks base method. diff --git a/dot/rpc/modules/mocks_test.go b/dot/rpc/modules/mocks_test.go index fd4b73bf6a..9464db8265 100644 --- a/dot/rpc/modules/mocks_test.go +++ b/dot/rpc/modules/mocks_test.go @@ -46,18 +46,18 @@ func (m *MockStorageAPI) EXPECT() *MockStorageAPIMockRecorder { } // Entries mocks base method. -func (m *MockStorageAPI) Entries(root *common.Hash) (map[string][]byte, error) { +func (m *MockStorageAPI) Entries(bhash *common.Hash) (map[string][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Entries", root) + ret := m.ctrl.Call(m, "Entries", bhash) ret0, _ := ret[0].(map[string][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Entries indicates an expected call of Entries. -func (mr *MockStorageAPIMockRecorder) Entries(root any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) Entries(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageAPI)(nil).Entries), root) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageAPI)(nil).Entries), bhash) } // GetKeysWithPrefix mocks base method. diff --git a/dot/rpc/modules/state.go b/dot/rpc/modules/state.go index 58502ea10b..e2d967a587 100644 --- a/dot/rpc/modules/state.go +++ b/dot/rpc/modules/state.go @@ -207,7 +207,7 @@ func (sm *StateModule) GetPairs(_ *http.Request, req *StatePairRequest, res *Sta } if req.Prefix == nil || *req.Prefix == "" || *req.Prefix == "0x" { - pairs, err := sm.storageAPI.Entries(stateRootHash) + pairs, err := sm.storageAPI.Entries(req.Bhash) if err != nil { return err } diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index 96d1d19700..87db887505 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -242,8 +242,18 @@ func (s *InmemoryStorageState) StorageRoot() (common.Hash, error) { return header.StateRoot, nil } -// Entries returns Entries from the trie with the given state root -func (s *InmemoryStorageState) Entries(root *common.Hash) (map[string][]byte, error) { +// Entries returns Entries from the trie for the given block hash +func (s *InmemoryStorageState) Entries(bhash *common.Hash) (map[string][]byte, error) { + if bhash == nil { + b := s.blockState.BestBlockHash() + bhash = &b + } + + root, err := s.GetStateRootFromBlock(bhash) + if err != nil { + return nil, err + } + tr, err := s.loadTrie(root) if err != nil { return nil, err diff --git a/dot/state/inmemory_storage_test.go b/dot/state/inmemory_storage_test.go index 2656eb5543..81aed66785 100644 --- a/dot/state/inmemory_storage_test.go +++ b/dot/state/inmemory_storage_test.go @@ -143,7 +143,7 @@ func TestStorage_LoadFromDB(t *testing.T) { storage.blockState.GetTries().delete(root) - entries, err := storage.Entries(&root) + entries, err := storage.Entries(&hash) require.NoError(t, err) require.Equal(t, 5, len(entries)) } diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index 923c58f071..a2760a529f 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -20,7 +20,7 @@ type StorageState interface { GenerateTrieProof(stateRoot common.Hash, keys [][]byte) ([][]byte, error) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) StorageRoot() (common.Hash, error) - Entries(root *common.Hash) (map[string][]byte, error) // should be overhauled to iterate + Entries(bhash *common.Hash) (map[string][]byte, error) // should be overhauled to iterate GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) diff --git a/lib/babe/mock_storage_state_test.go b/lib/babe/mock_storage_state_test.go index 58a0e542d4..bc49af6bc0 100644 --- a/lib/babe/mock_storage_state_test.go +++ b/lib/babe/mock_storage_state_test.go @@ -45,18 +45,18 @@ func (m *MockStorageState) EXPECT() *MockStorageStateMockRecorder { } // Entries mocks base method. -func (m *MockStorageState) Entries(root *common.Hash) (map[string][]byte, error) { +func (m *MockStorageState) Entries(bhash *common.Hash) (map[string][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Entries", root) + ret := m.ctrl.Call(m, "Entries", bhash) ret0, _ := ret[0].(map[string][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Entries indicates an expected call of Entries. -func (mr *MockStorageStateMockRecorder) Entries(root any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) Entries(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageState)(nil).Entries), root) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Entries", reflect.TypeOf((*MockStorageState)(nil).Entries), bhash) } // GenerateTrieProof mocks base method. From 6e2b5909dac7e8ced3108ae46ff4dfbbf47a1541 Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Wed, 2 Jul 2025 11:42:07 +0700 Subject: [PATCH 4/8] fix(state): Change StorageState.GetKeysWithPrefix() to expect a block hash --- dot/rpc/interfaces.go | 2 +- dot/rpc/modules/api.go | 2 +- dot/rpc/modules/mocks/mocks.go | 8 ++++---- dot/rpc/modules/mocks_test.go | 8 ++++---- dot/rpc/modules/state.go | 14 +------------- dot/rpc/modules/state_integration_test.go | 20 ++++++++++---------- dot/rpc/modules/state_test.go | 19 ------------------- dot/state/inmemory_storage.go | 18 ++++++++++++++++-- dot/state/inmemory_storage_test.go | 2 +- dot/state/storage_state.go | 2 +- 10 files changed, 39 insertions(+), 56 deletions(-) diff --git a/dot/rpc/interfaces.go b/dot/rpc/interfaces.go index 1926da3463..f2650ba5cb 100644 --- a/dot/rpc/interfaces.go +++ b/dot/rpc/interfaces.go @@ -25,7 +25,7 @@ type StorageAPI interface { GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) - GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) + GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) RegisterStorageObserver(observer state.Observer) UnregisterStorageObserver(observer state.Observer) } diff --git a/dot/rpc/modules/api.go b/dot/rpc/modules/api.go index 57080edb6b..4c7cf2d1d0 100644 --- a/dot/rpc/modules/api.go +++ b/dot/rpc/modules/api.go @@ -23,7 +23,7 @@ type StorageAPI interface { GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) - GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) + GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) RegisterStorageObserver(observer state.Observer) UnregisterStorageObserver(observer state.Observer) } diff --git a/dot/rpc/modules/mocks/mocks.go b/dot/rpc/modules/mocks/mocks.go index 99a9cf9447..d3853e7ee4 100644 --- a/dot/rpc/modules/mocks/mocks.go +++ b/dot/rpc/modules/mocks/mocks.go @@ -65,18 +65,18 @@ func (mr *MockStorageAPIMockRecorder) Entries(bhash any) *gomock.Call { } // GetKeysWithPrefix mocks base method. -func (m *MockStorageAPI) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { +func (m *MockStorageAPI) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetKeysWithPrefix", root, prefix) + ret := m.ctrl.Call(m, "GetKeysWithPrefix", bhash, prefix) ret0, _ := ret[0].([][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetKeysWithPrefix indicates an expected call of GetKeysWithPrefix. -func (mr *MockStorageAPIMockRecorder) GetKeysWithPrefix(root, prefix any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetKeysWithPrefix(bhash, prefix any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageAPI)(nil).GetKeysWithPrefix), root, prefix) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageAPI)(nil).GetKeysWithPrefix), bhash, prefix) } // GetStateRootFromBlock mocks base method. diff --git a/dot/rpc/modules/mocks_test.go b/dot/rpc/modules/mocks_test.go index 9464db8265..e98234d83c 100644 --- a/dot/rpc/modules/mocks_test.go +++ b/dot/rpc/modules/mocks_test.go @@ -61,18 +61,18 @@ func (mr *MockStorageAPIMockRecorder) Entries(bhash any) *gomock.Call { } // GetKeysWithPrefix mocks base method. -func (m *MockStorageAPI) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { +func (m *MockStorageAPI) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetKeysWithPrefix", root, prefix) + ret := m.ctrl.Call(m, "GetKeysWithPrefix", bhash, prefix) ret0, _ := ret[0].([][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetKeysWithPrefix indicates an expected call of GetKeysWithPrefix. -func (mr *MockStorageAPIMockRecorder) GetKeysWithPrefix(root, prefix any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetKeysWithPrefix(bhash, prefix any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageAPI)(nil).GetKeysWithPrefix), root, prefix) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageAPI)(nil).GetKeysWithPrefix), bhash, prefix) } // GetStateRootFromBlock mocks base method. diff --git a/dot/rpc/modules/state.go b/dot/rpc/modules/state.go index e2d967a587..3cbaf81428 100644 --- a/dot/rpc/modules/state.go +++ b/dot/rpc/modules/state.go @@ -194,18 +194,6 @@ func NewStateModule(net NetworkAPI, storage StorageAPI, core CoreAPI, blockAPI B // GetPairs returns the keys with prefix, leave empty to get all the keys. func (sm *StateModule) GetPairs(_ *http.Request, req *StatePairRequest, res *StatePairResponse) error { - var ( - stateRootHash *common.Hash - err error - ) - - if req.Bhash != nil { - stateRootHash, err = sm.storageAPI.GetStateRootFromBlock(req.Bhash) - if err != nil { - return err - } - } - if req.Prefix == nil || *req.Prefix == "" || *req.Prefix == "0x" { pairs, err := sm.storageAPI.Entries(req.Bhash) if err != nil { @@ -222,7 +210,7 @@ func (sm *StateModule) GetPairs(_ *http.Request, req *StatePairRequest, res *Sta if err != nil { return fmt.Errorf("cannot convert hex prefix %s to bytes: %w", *req.Prefix, err) } - keys, err := sm.storageAPI.GetKeysWithPrefix(stateRootHash, reqBytes) + keys, err := sm.storageAPI.GetKeysWithPrefix(req.Bhash, reqBytes) if err != nil { return err } diff --git a/dot/rpc/modules/state_integration_test.go b/dot/rpc/modules/state_integration_test.go index a6cc1c551e..3f1557cf5f 100644 --- a/dot/rpc/modules/state_integration_test.go +++ b/dot/rpc/modules/state_integration_test.go @@ -59,7 +59,7 @@ func TestStateModule_GetRuntimeVersion(t *testing.T) { TransactionVersion: 12, } - sm, hash, _ := setupStateModule(t) + sm, hash := setupStateModule(t) randomHash, err := common.HexToHash(RandomHash) require.NoError(t, err) @@ -100,7 +100,7 @@ func TestStateModule_GetRuntimeVersion(t *testing.T) { } func TestStateModule_GetPairs(t *testing.T) { - sm, hash, _ := setupStateModule(t) + sm, hash := setupStateModule(t) randomHash, err := common.HexToHash(RandomHash) require.NoError(t, err) @@ -179,7 +179,7 @@ func TestStateModule_GetPairs(t *testing.T) { } func TestStateModule_GetStorage(t *testing.T) { - sm, hash, _ := setupStateModule(t) + sm, hash := setupStateModule(t) randomHash, err := common.HexToHash(RandomHash) require.NoError(t, err) @@ -229,7 +229,7 @@ func TestStateModule_GetStorage(t *testing.T) { } func TestStateModule_GetStorageHash(t *testing.T) { - sm, hash, _ := setupStateModule(t) + sm, hash := setupStateModule(t) randomHash, err := common.HexToHash(RandomHash) require.NoError(t, err) @@ -277,7 +277,7 @@ func TestStateModule_GetStorageHash(t *testing.T) { } func TestStateModule_GetStorageSize(t *testing.T) { - sm, hash, _ := setupStateModule(t) + sm, hash := setupStateModule(t) randomHash, err := common.HexToHash(RandomHash) require.NoError(t, err) @@ -403,7 +403,7 @@ func TestStateModule_QueryStorage(t *testing.T) { func TestStateModule_GetMetadata(t *testing.T) { t.Skip() // TODO: update expected_metadata (#1026) - sm, hash, _ := setupStateModule(t) + sm, hash := setupStateModule(t) randomHash, err := common.HexToHash(RandomHash) require.NoError(t, err) @@ -444,7 +444,7 @@ func TestStateModule_GetMetadata(t *testing.T) { } func TestStateModule_GetKeysPaged(t *testing.T) { - sm, _, stateRootHash := setupStateModule(t) + sm, blockHash := setupStateModule(t) testCases := []struct { name string @@ -461,7 +461,7 @@ func TestStateModule_GetKeysPaged(t *testing.T) { {name: "allKeysTestBlockHash", params: StateStorageKeyRequest{ Qty: 10, - Block: stateRootHash, + Block: blockHash, }, expected: []string{ "0x3a6368696c645f73746f726167653a64656661756c743a3a6368696c6431", "0x3a6b657931", "0x3a6b657932"}}, @@ -557,7 +557,7 @@ func TestGetReadProof_WhenReturnsProof(t *testing.T) { require.Equal(t, res.Proof, expectedProof) } -func setupStateModule(t *testing.T) (*StateModule, *common.Hash, *common.Hash) { +func setupStateModule(t *testing.T) (*StateModule, *common.Hash) { // setup service net := newNetworkService(t) chain := newTestStateService(t) @@ -607,5 +607,5 @@ func setupStateModule(t *testing.T) (*StateModule, *common.Hash, *common.Hash) { require.NoError(t, err) core := newCoreService(t, chain) - return NewStateModule(net, chain.Storage, core, nil), &hash, &sr1 + return NewStateModule(net, chain.Storage, core, nil), &hash } diff --git a/dot/rpc/modules/state_test.go b/dot/rpc/modules/state_test.go index e9aa490d9e..822908d404 100644 --- a/dot/rpc/modules/state_test.go +++ b/dot/rpc/modules/state_test.go @@ -43,32 +43,23 @@ func TestStateModuleGetPairs(t *testing.T) { m["b"] = []byte{23, 24} mockStorageAPI := mocks.NewMockStorageAPI(ctrl) - mockStorageAPI.EXPECT().GetStateRootFromBlock(&hash).Return(&hash, nil) mockStorageAPI.EXPECT().GetKeysWithPrefix(&hash, common.MustHexToBytes(str)).Return([][]byte{{1}, {1}}, nil) mockStorageAPI.EXPECT().GetStorage(&hash, []byte{1}).Return([]byte{21}, nil).Times(2) mockStorageAPINil := mocks.NewMockStorageAPI(ctrl) - mockStorageAPINil.EXPECT().GetStateRootFromBlock(&hash).Return(&hash, nil) mockStorageAPINil.EXPECT().Entries(&hash).Return(m, nil) mockStorageAPIGetKeysEmpty := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIGetKeysEmpty.EXPECT().GetStateRootFromBlock(&hash).Return(&hash, nil) mockStorageAPIGetKeysEmpty.EXPECT().GetKeysWithPrefix(&hash, common.MustHexToBytes(str)).Return([][]byte{}, nil) mockStorageAPIGetKeysErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIGetKeysErr.EXPECT().GetStateRootFromBlock(&hash).Return(&hash, nil) mockStorageAPIGetKeysErr.EXPECT().GetKeysWithPrefix(&hash, common.MustHexToBytes(str)). Return(nil, errors.New("GetKeysWithPrefix Err")) mockStorageAPIEntriesErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIEntriesErr.EXPECT().GetStateRootFromBlock(&hash).Return(&hash, nil) mockStorageAPIEntriesErr.EXPECT().Entries(&hash).Return(nil, errors.New("entries Err")) - mockStorageAPIErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIErr.EXPECT().GetStateRootFromBlock(&hash).Return(nil, errors.New("GetStateRootFromBlock Err")) - mockStorageAPIGetStorageErr := mocks.NewMockStorageAPI(ctrl) - mockStorageAPIGetStorageErr.EXPECT().GetStateRootFromBlock(&hash).Return(&hash, nil) mockStorageAPIGetStorageErr.EXPECT().GetKeysWithPrefix(&hash, common.MustHexToBytes(str)). Return([][]byte{{2}, {2}}, nil) mockStorageAPIGetStorageErr.EXPECT().GetStorage(&hash, []byte{2}).Return(nil, errors.New("GetStorage Err")) @@ -93,16 +84,6 @@ func TestStateModuleGetPairs(t *testing.T) { expErr error exp StatePairResponse }{ - { - name: "GetStateRootFromBlock Error", - fields: fields{nil, mockStorageAPIErr, nil}, - args: args{ - req: &StatePairRequest{ - Bhash: &hash, - }, - }, - expErr: errors.New("GetStateRootFromBlock Err"), - }, { name: "Nil Prefix OK", fields: fields{nil, mockStorageAPINil, nil}, diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index 87db887505..ee65bbbd18 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -263,8 +263,22 @@ func (s *InmemoryStorageState) Entries(bhash *common.Hash) (map[string][]byte, e } // GetKeysWithPrefix returns all that match the given prefix for the given hash -// (or best block state root if hash is nil) in lexicographic order -func (s *InmemoryStorageState) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { +// (or best block if hash is nil) in lexicographic order +func (s *InmemoryStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { + if bhash == nil { + header, err := s.blockState.BestBlockHeader() + if err != nil { + return nil, err + } + h := header.Hash() + bhash = &h + } + + root, err := s.GetStateRootFromBlock(bhash) + if err != nil { + return nil, err + } + tr, err := s.loadTrie(root) if err != nil { return nil, err diff --git a/dot/state/inmemory_storage_test.go b/dot/state/inmemory_storage_test.go index 81aed66785..56f28be163 100644 --- a/dot/state/inmemory_storage_test.go +++ b/dot/state/inmemory_storage_test.go @@ -137,7 +137,7 @@ func TestStorage_LoadFromDB(t *testing.T) { storage.blockState.GetTries().delete(root) - prefixKeys, err := storage.GetKeysWithPrefix(&root, []byte("ke")) + prefixKeys, err := storage.GetKeysWithPrefix(&hash, []byte("ke")) require.NoError(t, err) require.Equal(t, 2, len(prefixKeys)) diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index a2760a529f..9dc6c0c6a8 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -21,7 +21,7 @@ type StorageState interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) StorageRoot() (common.Hash, error) Entries(bhash *common.Hash) (map[string][]byte, error) // should be overhauled to iterate - GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) + GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) From 2ac93acb1350e1324b2e0069c2cf63a436f90b0c Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Wed, 2 Jul 2025 12:50:54 +0700 Subject: [PATCH 5/8] fix(state): Change StorageState.GetStorageChild() to expect a block hash --- dot/core/mock_state_test.go | 16 ++++----- dot/rpc/interfaces.go | 2 +- dot/rpc/modules/api.go | 2 +- dot/rpc/modules/childstate.go | 15 +------- dot/rpc/modules/childstate_test.go | 54 ++++++++++++----------------- dot/rpc/modules/mocks/mocks.go | 8 ++--- dot/rpc/modules/mocks_test.go | 8 ++--- dot/state/inmemory_storage.go | 16 ++++++++- dot/state/inmemory_storage_test.go | 13 ++++--- dot/state/storage_state.go | 2 +- lib/babe/mock_storage_state_test.go | 16 ++++----- 11 files changed, 75 insertions(+), 77 deletions(-) diff --git a/dot/core/mock_state_test.go b/dot/core/mock_state_test.go index 12b550e877..03bef09310 100644 --- a/dot/core/mock_state_test.go +++ b/dot/core/mock_state_test.go @@ -957,18 +957,18 @@ func (mr *MockStorageStateMockRecorder) GenerateTrieProof(stateRoot, keys any) * } // GetKeysWithPrefix mocks base method. -func (m *MockStorageState) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { +func (m *MockStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetKeysWithPrefix", root, prefix) + ret := m.ctrl.Call(m, "GetKeysWithPrefix", bhash, prefix) ret0, _ := ret[0].([][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetKeysWithPrefix indicates an expected call of GetKeysWithPrefix. -func (mr *MockStorageStateMockRecorder) GetKeysWithPrefix(root, prefix any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetKeysWithPrefix(bhash, prefix any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageState)(nil).GetKeysWithPrefix), root, prefix) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageState)(nil).GetKeysWithPrefix), bhash, prefix) } // GetStateRootFromBlock mocks base method. @@ -1002,18 +1002,18 @@ func (mr *MockStorageStateMockRecorder) GetStorage(bhash, key any) *gomock.Call } // GetStorageChild mocks base method. -func (m *MockStorageState) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) { +func (m *MockStorageState) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageChild", root, keyToChild) + ret := m.ctrl.Call(m, "GetStorageChild", bhash, keyToChild) ret0, _ := ret[0].(trie.Trie) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageChild indicates an expected call of GetStorageChild. -func (mr *MockStorageStateMockRecorder) GetStorageChild(root, keyToChild any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetStorageChild(bhash, keyToChild any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageChild), root, keyToChild) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageChild), bhash, keyToChild) } // GetStorageFromChild mocks base method. diff --git a/dot/rpc/interfaces.go b/dot/rpc/interfaces.go index f2650ba5cb..3d4cf6a1d2 100644 --- a/dot/rpc/interfaces.go +++ b/dot/rpc/interfaces.go @@ -21,7 +21,7 @@ import ( // StorageAPI is the interface for the storage state type StorageAPI interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) - GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) + GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) diff --git a/dot/rpc/modules/api.go b/dot/rpc/modules/api.go index 4c7cf2d1d0..43bd407db8 100644 --- a/dot/rpc/modules/api.go +++ b/dot/rpc/modules/api.go @@ -19,7 +19,7 @@ import ( // StorageAPI is the interface for the storage state type StorageAPI interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) - GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) + GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) diff --git a/dot/rpc/modules/childstate.go b/dot/rpc/modules/childstate.go index 270e2cb54b..be1cdd8cc4 100644 --- a/dot/rpc/modules/childstate.go +++ b/dot/rpc/modules/childstate.go @@ -53,20 +53,7 @@ func NewChildStateModule(s StorageAPI, b BlockAPI) *ChildStateModule { // GetKeys returns the keys from the specified child storage. The keys can also be filtered based on a prefix. func (cs *ChildStateModule) GetKeys(_ *http.Request, req *GetKeysRequest, res *[]string) error { - var hash common.Hash - - if req.Hash == nil { - hash = cs.blockAPI.BestBlockHash() - } else { - hash = *req.Hash - } - - stateRoot, err := cs.storageAPI.GetStateRootFromBlock(&hash) - if err != nil { - return err - } - - trie, err := cs.storageAPI.GetStorageChild(stateRoot, req.Key) + trie, err := cs.storageAPI.GetStorageChild(req.Hash, req.Key) if err != nil { return err } diff --git a/dot/rpc/modules/childstate_test.go b/dot/rpc/modules/childstate_test.go index 6e8ed3e759..9ede4e5efe 100644 --- a/dot/rpc/modules/childstate_test.go +++ b/dot/rpc/modules/childstate_test.go @@ -42,7 +42,7 @@ func createTestTrieState(t *testing.T) (trie.Trie, common.Hash) { func TestChildStateModule_GetKeys(t *testing.T) { ctrl := gomock.NewController(t) - tr, sr := createTestTrieState(t) + tr, _ := createTestTrieState(t) expKeys := tr.GetKeysWithPrefix([]byte{}) expHexKeys := make([]string, len(expKeys)) @@ -51,24 +51,29 @@ func TestChildStateModule_GetKeys(t *testing.T) { } mockStorageAPI := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI1 := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI2 := apimocks.NewMockStorageAPI(ctrl) - mockBlockAPI := apimocks.NewMockBlockAPI(ctrl) + mockErrorStorageAPI := apimocks.NewMockStorageAPI(ctrl) hash := common.MustHexToHash("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") - mockBlockAPI.EXPECT().BestBlockHash().Return(hash).Times(2) - - mockStorageAPI.EXPECT().GetStateRootFromBlock(&hash).Return(&sr, nil).Times(2) - mockStorageAPI.EXPECT().GetStorageChild(&sr, []byte(":child_storage_key")). - Return(tr, nil).Times(2) - - mockErrorStorageAPI1.EXPECT().GetStateRootFromBlock(&common.Hash{}).Return(nil, nil) - mockErrorStorageAPI1.EXPECT().GetStorageChild((*common.Hash)(nil), []byte(nil)). - Return(nil, errors.New("GetStorageChild error")) - mockErrorStorageAPI2.EXPECT().GetStateRootFromBlock(&hash).Return(nil, errors.New("GetStateRootFromBlock error")) - - childStateModule := NewChildStateModule(mockStorageAPI, mockBlockAPI) + mockStorageAPI.EXPECT(). + GetStorageChild((*common.Hash)(nil), []byte(":child_storage_key")). + Return(tr, nil). + MaxTimes(2) + mockStorageAPI.EXPECT(). + GetStorageChild(&hash, []byte(":child_storage_key")). + Return(tr, nil). + MaxTimes(2) + + mockErrorStorageAPI.EXPECT(). + GetStorageChild((*common.Hash)(nil), []byte(nil)). + Return(nil, errors.New("GetStorageChild error")). + MaxTimes(2) + mockErrorStorageAPI.EXPECT(). + GetStorageChild(&common.Hash{}, []byte(nil)). + Return(nil, errors.New("GetStorageChild error")). + MaxTimes(2) + + childStateModule := NewChildStateModule(mockStorageAPI, nil) type fields struct { storageAPI StorageAPI blockAPI BlockAPI @@ -114,8 +119,8 @@ func TestChildStateModule_GetKeys(t *testing.T) { { name: "GetStorageChild_error", fields: fields{ - mockErrorStorageAPI1, - mockBlockAPI, + mockErrorStorageAPI, + nil, }, args: args{ req: &GetKeysRequest{ @@ -124,19 +129,6 @@ func TestChildStateModule_GetKeys(t *testing.T) { }, expErr: errors.New("GetStorageChild error"), }, - { - name: "GetStateRootFromBlock_error", - fields: fields{ - mockErrorStorageAPI2, - mockBlockAPI, - }, - args: args{ - req: &GetKeysRequest{ - Key: []byte(":child_storage_key"), - }, - }, - expErr: errors.New("GetStateRootFromBlock error"), - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/dot/rpc/modules/mocks/mocks.go b/dot/rpc/modules/mocks/mocks.go index d3853e7ee4..ae48e9283c 100644 --- a/dot/rpc/modules/mocks/mocks.go +++ b/dot/rpc/modules/mocks/mocks.go @@ -110,18 +110,18 @@ func (mr *MockStorageAPIMockRecorder) GetStorage(bhash, key any) *gomock.Call { } // GetStorageChild mocks base method. -func (m *MockStorageAPI) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) { +func (m *MockStorageAPI) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageChild", root, keyToChild) + ret := m.ctrl.Call(m, "GetStorageChild", bhash, keyToChild) ret0, _ := ret[0].(trie.Trie) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageChild indicates an expected call of GetStorageChild. -func (mr *MockStorageAPIMockRecorder) GetStorageChild(root, keyToChild any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetStorageChild(bhash, keyToChild any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageChild), root, keyToChild) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageChild), bhash, keyToChild) } // GetStorageFromChild mocks base method. diff --git a/dot/rpc/modules/mocks_test.go b/dot/rpc/modules/mocks_test.go index e98234d83c..0d86c09080 100644 --- a/dot/rpc/modules/mocks_test.go +++ b/dot/rpc/modules/mocks_test.go @@ -106,18 +106,18 @@ func (mr *MockStorageAPIMockRecorder) GetStorage(bhash, key any) *gomock.Call { } // GetStorageChild mocks base method. -func (m *MockStorageAPI) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) { +func (m *MockStorageAPI) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageChild", root, keyToChild) + ret := m.ctrl.Call(m, "GetStorageChild", bhash, keyToChild) ret0, _ := ret[0].(trie.Trie) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageChild indicates an expected call of GetStorageChild. -func (mr *MockStorageAPIMockRecorder) GetStorageChild(root, keyToChild any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetStorageChild(bhash, keyToChild any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageChild), root, keyToChild) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageChild), bhash, keyToChild) } // GetStorageFromChild mocks base method. diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index ee65bbbd18..f5abd94b72 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -288,7 +288,21 @@ func (s *InmemoryStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []by } // GetStorageChild returns a child trie, if it exists -func (s *InmemoryStorageState) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) { +func (s *InmemoryStorageState) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { + if bhash == nil { + header, err := s.blockState.BestBlockHeader() + if err != nil { + return nil, err + } + h := header.Hash() + bhash = &h + } + + root, err := s.GetStateRootFromBlock(bhash) + if err != nil { + return nil, err + } + tr, err := s.loadTrie(root) if err != nil { return nil, err diff --git a/dot/state/inmemory_storage_test.go b/dot/state/inmemory_storage_test.go index 56f28be163..b7f2bde12d 100644 --- a/dot/state/inmemory_storage_test.go +++ b/dot/state/inmemory_storage_test.go @@ -195,21 +195,26 @@ func TestGetStorageChildAndGetStorageFromChild(t *testing.T) { trieState := runtime.NewInMemoryTrieState(genTrie) header := types.NewHeader(blockState.GenesisHash(), trieState.Trie().MustHash(), - common.Hash{}, 1, types.NewDigest()) + common.Hash{}, 1, createPrimaryBABEDigest(t)) err = storage.StoreTrie(trieState, header) require.NoError(t, err) - rootHash, err := genTrie.Hash() + body, err := types.NewBodyFromBytes([]byte{}) require.NoError(t, err) + require.NoError(t, blockState.AddBlock(&types.Block{Header: *header, Body: *body}, nil, nil)) - _, err = storage.GetStorageChild(&rootHash, []byte("keyToChild")) + blockHash := header.Hash() + _, err = storage.GetStorageChild(&blockHash, []byte("keyToChild")) + require.NoError(t, err) + + rootHash, err := genTrie.Hash() require.NoError(t, err) // Clear trie from cache and fetch data from disk. storage.blockState.GetTries().delete(rootHash) - _, err = storage.GetStorageChild(&rootHash, []byte("keyToChild")) + _, err = storage.GetStorageChild(&blockHash, []byte("keyToChild")) require.NoError(t, err) value, err := storage.GetStorageFromChild(&rootHash, []byte("keyToChild"), []byte("keyInsidechild")) diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index 9dc6c0c6a8..31df601626 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -22,7 +22,7 @@ type StorageState interface { StorageRoot() (common.Hash, error) Entries(bhash *common.Hash) (map[string][]byte, error) // should be overhauled to iterate GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) - GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) + GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) LoadCode(hash *common.Hash) ([]byte, error) diff --git a/lib/babe/mock_storage_state_test.go b/lib/babe/mock_storage_state_test.go index bc49af6bc0..fd4eb1e613 100644 --- a/lib/babe/mock_storage_state_test.go +++ b/lib/babe/mock_storage_state_test.go @@ -75,18 +75,18 @@ func (mr *MockStorageStateMockRecorder) GenerateTrieProof(stateRoot, keys any) * } // GetKeysWithPrefix mocks base method. -func (m *MockStorageState) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { +func (m *MockStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetKeysWithPrefix", root, prefix) + ret := m.ctrl.Call(m, "GetKeysWithPrefix", bhash, prefix) ret0, _ := ret[0].([][]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetKeysWithPrefix indicates an expected call of GetKeysWithPrefix. -func (mr *MockStorageStateMockRecorder) GetKeysWithPrefix(root, prefix any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetKeysWithPrefix(bhash, prefix any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageState)(nil).GetKeysWithPrefix), root, prefix) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageState)(nil).GetKeysWithPrefix), bhash, prefix) } // GetStateRootFromBlock mocks base method. @@ -120,18 +120,18 @@ func (mr *MockStorageStateMockRecorder) GetStorage(bhash, key any) *gomock.Call } // GetStorageChild mocks base method. -func (m *MockStorageState) GetStorageChild(root *common.Hash, keyToChild []byte) (trie.Trie, error) { +func (m *MockStorageState) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageChild", root, keyToChild) + ret := m.ctrl.Call(m, "GetStorageChild", bhash, keyToChild) ret0, _ := ret[0].(trie.Trie) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageChild indicates an expected call of GetStorageChild. -func (mr *MockStorageStateMockRecorder) GetStorageChild(root, keyToChild any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetStorageChild(bhash, keyToChild any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageChild), root, keyToChild) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageChild), bhash, keyToChild) } // GetStorageFromChild mocks base method. From ba3e63c8acafdac9b819aba1b1c2332bd8f9de62 Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Wed, 2 Jul 2025 13:00:05 +0700 Subject: [PATCH 6/8] remove redundant code --- dot/state/inmemory_storage.go | 41 ----------------------------------- 1 file changed, 41 deletions(-) diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index f5abd94b72..4eb104a849 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -111,15 +111,6 @@ func (s *InmemoryStorageState) StoreTrie(ts storage.TrieState, header *types.Hea // TrieState returns the TrieState for a given block hash. // If no block hash is provided, it returns the TrieState for the current chain head. func (s *InmemoryStorageState) TrieState(bhash *common.Hash) (storage.TrieState, error) { - if bhash == nil { - header, err := s.blockState.BestBlockHeader() - if err != nil { - return nil, fmt.Errorf("while getting best block header: %w", err) - } - h := header.Hash() - bhash = &h - } - root, err := s.GetStateRootFromBlock(bhash) if err != nil { return nil, fmt.Errorf("getting state root for block hash %s: %w", bhash.String(), err) @@ -194,15 +185,6 @@ func (s *InmemoryStorageState) ExistsStorage(bhash *common.Hash, key []byte) (bo // GetStorage gets the object from the trie using the given key and block hash // If no hash is provided, the current chain head is used func (s *InmemoryStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { - if bhash == nil { - header, err := s.blockState.BestBlockHeader() - if err != nil { - return nil, err - } - h := header.Hash() - bhash = &h - } - root, err := s.GetStateRootFromBlock(bhash) if err != nil { return nil, err @@ -244,11 +226,6 @@ func (s *InmemoryStorageState) StorageRoot() (common.Hash, error) { // Entries returns Entries from the trie for the given block hash func (s *InmemoryStorageState) Entries(bhash *common.Hash) (map[string][]byte, error) { - if bhash == nil { - b := s.blockState.BestBlockHash() - bhash = &b - } - root, err := s.GetStateRootFromBlock(bhash) if err != nil { return nil, err @@ -265,15 +242,6 @@ func (s *InmemoryStorageState) Entries(bhash *common.Hash) (map[string][]byte, e // GetKeysWithPrefix returns all that match the given prefix for the given hash // (or best block if hash is nil) in lexicographic order func (s *InmemoryStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { - if bhash == nil { - header, err := s.blockState.BestBlockHeader() - if err != nil { - return nil, err - } - h := header.Hash() - bhash = &h - } - root, err := s.GetStateRootFromBlock(bhash) if err != nil { return nil, err @@ -289,15 +257,6 @@ func (s *InmemoryStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []by // GetStorageChild returns a child trie, if it exists func (s *InmemoryStorageState) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { - if bhash == nil { - header, err := s.blockState.BestBlockHeader() - if err != nil { - return nil, err - } - h := header.Hash() - bhash = &h - } - root, err := s.GetStateRootFromBlock(bhash) if err != nil { return nil, err From a48a535114398324644d4194cc5b63a7ae4d9871 Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Wed, 2 Jul 2025 13:46:00 +0700 Subject: [PATCH 7/8] fix(state): Change StorageState.GetStorageFromChild() to expect a block hash --- dot/core/mock_state_test.go | 8 +- dot/rpc/interfaces.go | 2 +- dot/rpc/modules/api.go | 2 +- dot/rpc/modules/childstate.go | 49 +--------- dot/rpc/modules/childstate_test.go | 136 ++++++++++------------------ dot/rpc/modules/mocks/mocks.go | 8 +- dot/rpc/modules/mocks_test.go | 8 +- dot/state/inmemory_storage.go | 7 +- dot/state/inmemory_storage_test.go | 2 +- dot/state/storage_state.go | 2 +- lib/babe/mock_storage_state_test.go | 8 +- 11 files changed, 78 insertions(+), 154 deletions(-) diff --git a/dot/core/mock_state_test.go b/dot/core/mock_state_test.go index 03bef09310..3f2ec6f967 100644 --- a/dot/core/mock_state_test.go +++ b/dot/core/mock_state_test.go @@ -1017,18 +1017,18 @@ func (mr *MockStorageStateMockRecorder) GetStorageChild(bhash, keyToChild any) * } // GetStorageFromChild mocks base method. -func (m *MockStorageState) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) { +func (m *MockStorageState) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageFromChild", root, keyToChild, key) + ret := m.ctrl.Call(m, "GetStorageFromChild", bhash, keyToChild, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageFromChild indicates an expected call of GetStorageFromChild. -func (mr *MockStorageStateMockRecorder) GetStorageFromChild(root, keyToChild, key any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetStorageFromChild(bhash, keyToChild, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageFromChild), root, keyToChild, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageFromChild), bhash, keyToChild, key) } // LoadCode mocks base method. diff --git a/dot/rpc/interfaces.go b/dot/rpc/interfaces.go index 3d4cf6a1d2..89782d4683 100644 --- a/dot/rpc/interfaces.go +++ b/dot/rpc/interfaces.go @@ -22,7 +22,7 @@ import ( type StorageAPI interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) - GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) + GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) diff --git a/dot/rpc/modules/api.go b/dot/rpc/modules/api.go index 43bd407db8..8a88b120b4 100644 --- a/dot/rpc/modules/api.go +++ b/dot/rpc/modules/api.go @@ -20,7 +20,7 @@ import ( type StorageAPI interface { GetStorage(bhash *common.Hash, key []byte) ([]byte, error) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) - GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) + GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) diff --git a/dot/rpc/modules/childstate.go b/dot/rpc/modules/childstate.go index be1cdd8cc4..1d88733b2a 100644 --- a/dot/rpc/modules/childstate.go +++ b/dot/rpc/modules/childstate.go @@ -70,20 +70,7 @@ func (cs *ChildStateModule) GetKeys(_ *http.Request, req *GetKeysRequest, res *[ // GetStorageSize returns the size of a child storage entry. func (cs *ChildStateModule) GetStorageSize(_ *http.Request, req *GetChildStorageRequest, res *uint64) error { - var hash common.Hash - - if req.Hash == nil { - hash = cs.blockAPI.BestBlockHash() - } else { - hash = *req.Hash - } - - stateRoot, err := cs.storageAPI.GetStateRootFromBlock(&hash) - if err != nil { - return err - } - - item, err := cs.storageAPI.GetStorageFromChild(stateRoot, req.KeyChild, req.EntryKey) + item, err := cs.storageAPI.GetStorageFromChild(req.Hash, req.KeyChild, req.EntryKey) if err != nil { return err } @@ -97,20 +84,7 @@ func (cs *ChildStateModule) GetStorageSize(_ *http.Request, req *GetChildStorage // GetStorageHash returns the hash of a child storage entry func (cs *ChildStateModule) GetStorageHash(_ *http.Request, req *GetStorageHash, res *string) error { - var hash common.Hash - - if req.Hash == nil { - hash = cs.blockAPI.BestBlockHash() - } else { - hash = *req.Hash - } - - stateRoot, err := cs.storageAPI.GetStateRootFromBlock(&hash) - if err != nil { - return err - } - - item, err := cs.storageAPI.GetStorageFromChild(stateRoot, req.KeyChild, req.EntryKey) + item, err := cs.storageAPI.GetStorageFromChild(req.Hash, req.KeyChild, req.EntryKey) if err != nil { return err } @@ -125,24 +99,7 @@ func (cs *ChildStateModule) GetStorageHash(_ *http.Request, req *GetStorageHash, // GetStorage returns a child storage entry. func (cs *ChildStateModule) GetStorage( _ *http.Request, req *ChildStateStorageRequest, res *StateStorageResponse) error { - var ( - item []byte - err error - hash common.Hash - ) - - if req.Hash == nil { - hash = cs.blockAPI.BestBlockHash() - } else { - hash = *req.Hash - } - - stateRoot, err := cs.storageAPI.GetStateRootFromBlock(&hash) - if err != nil { - return err - } - - item, err = cs.storageAPI.GetStorageFromChild(stateRoot, req.ChildStorageKey, req.Key) + item, err := cs.storageAPI.GetStorageFromChild(req.Hash, req.ChildStorageKey, req.Key) if err != nil { return err } diff --git a/dot/rpc/modules/childstate_test.go b/dot/rpc/modules/childstate_test.go index 9ede4e5efe..a878b81281 100644 --- a/dot/rpc/modules/childstate_test.go +++ b/dot/rpc/modules/childstate_test.go @@ -18,7 +18,7 @@ import ( "github.com/stretchr/testify/require" ) -func createTestTrieState(t *testing.T) (trie.Trie, common.Hash) { +func createTestTrieState(t *testing.T) trie.Trie { t.Helper() _, genesisTrie, _ := newWestendLocalGenesisWithTrieAndHeader(t) @@ -33,16 +33,13 @@ func createTestTrieState(t *testing.T) (trie.Trie, common.Hash) { err = tr.SetChildStorage([]byte(":child_storage_key"), []byte(":another_child"), []byte("value")) require.NoError(t, err) - stateRoot, err := tr.Root() - require.NoError(t, err) - - return genesisTrie, stateRoot + return genesisTrie } func TestChildStateModule_GetKeys(t *testing.T) { ctrl := gomock.NewController(t) - tr, _ := createTestTrieState(t) + tr := createTestTrieState(t) expKeys := tr.GetKeysWithPrefix([]byte{}) expHexKeys := make([]string, len(expKeys)) @@ -151,25 +148,29 @@ func TestChildStateModule_GetKeys(t *testing.T) { func TestChildStateModule_GetStorageSize(t *testing.T) { ctrl := gomock.NewController(t) - _, sr := createTestTrieState(t) - mockStorageAPI := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI1 := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI2 := apimocks.NewMockStorageAPI(ctrl) + mockErrorStorageAPI := apimocks.NewMockStorageAPI(ctrl) mockBlockAPI := apimocks.NewMockBlockAPI(ctrl) hash := common.MustHexToHash("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") - mockBlockAPI.EXPECT().BestBlockHash().Return(hash) - - mockStorageAPI.EXPECT().GetStateRootFromBlock(&hash).Return(&sr, nil).Times(2) - mockStorageAPI.EXPECT().GetStorageFromChild(&sr, []byte(":child_storage_key"), []byte(":child_first")). - Return([]byte(""), nil).Times(2) - mockErrorStorageAPI1.EXPECT().GetStateRootFromBlock(&hash).Return(nil, nil) - mockErrorStorageAPI1.EXPECT().GetStorageFromChild((*common.Hash)(nil), []byte(nil), []byte(nil)). - Return(nil, errors.New("GetStorageChild error")) + mockStorageAPI.EXPECT(). + GetStorageFromChild(&hash, []byte(":child_storage_key"), []byte(":child_first")). + Return([]byte(""), nil). + MaxTimes(2) + mockStorageAPI.EXPECT(). + GetStorageFromChild((*common.Hash)(nil), []byte(":child_storage_key"), []byte(":child_first")). + Return([]byte(""), nil). + MaxTimes(2) - mockErrorStorageAPI2.EXPECT().GetStateRootFromBlock(&hash).Return(nil, errors.New("GetStateRootFromBlock error")) + mockErrorStorageAPI.EXPECT(). + GetStorageFromChild(&hash, []byte(nil), []byte(nil)). + Return(nil, errors.New("GetStorageChild error")). + MaxTimes(2) + mockErrorStorageAPI.EXPECT(). + GetStorageFromChild((*common.Hash)(nil), []byte(nil), []byte(nil)). + Return(nil, errors.New("GetStorageChild error")). + MaxTimes(2) childStateModule := NewChildStateModule(mockStorageAPI, mockBlockAPI) type fields struct { @@ -219,7 +220,7 @@ func TestChildStateModule_GetStorageSize(t *testing.T) { { name: "GetStorageChild_error", fields: fields{ - mockErrorStorageAPI1, + mockErrorStorageAPI, mockBlockAPI, }, args: args{ @@ -229,19 +230,6 @@ func TestChildStateModule_GetStorageSize(t *testing.T) { }, expErr: errors.New("GetStorageChild error"), }, - { - name: "GetStateRootFromBlock_error", - fields: fields{ - mockErrorStorageAPI2, - mockBlockAPI, - }, - args: args{ - req: &GetChildStorageRequest{ - Hash: &hash, - }, - }, - expErr: errors.New("GetStateRootFromBlock error"), - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -264,25 +252,25 @@ func TestChildStateModule_GetStorageSize(t *testing.T) { func TestChildStateModule_GetStorageHash(t *testing.T) { ctrl := gomock.NewController(t) - _, sr := createTestTrieState(t) - mockStorageAPI := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI1 := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI2 := apimocks.NewMockStorageAPI(ctrl) + mockErrorStorageAPI := apimocks.NewMockStorageAPI(ctrl) mockBlockAPI := apimocks.NewMockBlockAPI(ctrl) hash := common.MustHexToHash("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") - mockBlockAPI.EXPECT().BestBlockHash().Return(hash) - mockStorageAPI.EXPECT().GetStateRootFromBlock(&hash).Return(&sr, nil).Times(2) - mockStorageAPI.EXPECT().GetStorageFromChild(&sr, []byte(":child_storage_key"), []byte(":child_first")). - Return([]byte(""), nil).Times(2) - - mockErrorStorageAPI1.EXPECT().GetStateRootFromBlock(&hash).Return(nil, nil) - mockErrorStorageAPI1.EXPECT().GetStorageFromChild((*common.Hash)(nil), []byte(nil), []byte(nil)). - Return(nil, errors.New("GetStorageChild error")) + mockStorageAPI.EXPECT(). + GetStorageFromChild((*common.Hash)(nil), []byte(":child_storage_key"), []byte(":child_first")). + Return([]byte(""), nil). + MaxTimes(2) + mockStorageAPI.EXPECT(). + GetStorageFromChild(&hash, []byte(":child_storage_key"), []byte(":child_first")). + Return([]byte(""), nil). + MaxTimes(2) - mockErrorStorageAPI2.EXPECT().GetStateRootFromBlock(&hash).Return(nil, errors.New("GetStateRootFromBlock error")) + mockErrorStorageAPI.EXPECT(). + GetStorageFromChild(&hash, []byte(nil), []byte(nil)). + Return(nil, errors.New("GetStorageChild error")). + MaxTimes(2) childStateModule := NewChildStateModule(mockStorageAPI, mockBlockAPI) type fields struct { @@ -332,7 +320,7 @@ func TestChildStateModule_GetStorageHash(t *testing.T) { { name: "GetStorageChild_error", fields: fields{ - mockErrorStorageAPI1, + mockErrorStorageAPI, mockBlockAPI, }, args: args{ @@ -342,19 +330,6 @@ func TestChildStateModule_GetStorageHash(t *testing.T) { }, expErr: errors.New("GetStorageChild error"), }, - { - name: "GetStateRootFromBlock_error", - fields: fields{ - mockErrorStorageAPI2, - mockBlockAPI, - }, - args: args{ - req: &GetStorageHash{ - Hash: &hash, - }, - }, - expErr: errors.New("GetStateRootFromBlock error"), - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -377,25 +352,25 @@ func TestChildStateModule_GetStorageHash(t *testing.T) { func TestChildStateModule_GetStorage(t *testing.T) { ctrl := gomock.NewController(t) - _, sr := createTestTrieState(t) - mockStorageAPI := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI1 := apimocks.NewMockStorageAPI(ctrl) - mockErrorStorageAPI2 := apimocks.NewMockStorageAPI(ctrl) + mockErrorStorageAPI := apimocks.NewMockStorageAPI(ctrl) mockBlockAPI := apimocks.NewMockBlockAPI(ctrl) hash := common.MustHexToHash("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") - mockBlockAPI.EXPECT().BestBlockHash().Return(hash) - mockStorageAPI.EXPECT().GetStateRootFromBlock(&hash).Return(&sr, nil).Times(2) - mockStorageAPI.EXPECT().GetStorageFromChild(&sr, []byte(":child_storage_key"), []byte(":child_first")). - Return([]byte("test"), nil).Times(2) - - mockErrorStorageAPI1.EXPECT().GetStateRootFromBlock(&hash).Return(nil, nil) - mockErrorStorageAPI1.EXPECT().GetStorageFromChild((*common.Hash)(nil), []byte(nil), []byte(nil)). - Return(nil, errors.New("GetStorageChild error")) + mockStorageAPI.EXPECT(). + GetStorageFromChild(&hash, []byte(":child_storage_key"), []byte(":child_first")). + Return([]byte("test"), nil). + MaxTimes(2) + mockStorageAPI.EXPECT(). + GetStorageFromChild((*common.Hash)(nil), []byte(":child_storage_key"), []byte(":child_first")). + Return([]byte("test"), nil). + MaxTimes(2) - mockErrorStorageAPI2.EXPECT().GetStateRootFromBlock(&hash).Return(nil, errors.New("GetStateRootFromBlock error")) + mockErrorStorageAPI.EXPECT(). + GetStorageFromChild(&hash, []byte(nil), []byte(nil)). + Return(nil, errors.New("GetStorageChild error")). + MaxTimes(2) childStateModule := NewChildStateModule(mockStorageAPI, mockBlockAPI) type fields struct { @@ -445,7 +420,7 @@ func TestChildStateModule_GetStorage(t *testing.T) { { name: "GetStorageChild_error", fields: fields{ - mockErrorStorageAPI1, + mockErrorStorageAPI, mockBlockAPI, }, args: args{ @@ -455,19 +430,6 @@ func TestChildStateModule_GetStorage(t *testing.T) { }, expErr: errors.New("GetStorageChild error"), }, - { - name: "GetStateRootFromBlock_error", - fields: fields{ - mockErrorStorageAPI2, - mockBlockAPI, - }, - args: args{ - req: &ChildStateStorageRequest{ - Hash: &hash, - }, - }, - expErr: errors.New("GetStateRootFromBlock error"), - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/dot/rpc/modules/mocks/mocks.go b/dot/rpc/modules/mocks/mocks.go index ae48e9283c..b68d4e469d 100644 --- a/dot/rpc/modules/mocks/mocks.go +++ b/dot/rpc/modules/mocks/mocks.go @@ -125,18 +125,18 @@ func (mr *MockStorageAPIMockRecorder) GetStorageChild(bhash, keyToChild any) *go } // GetStorageFromChild mocks base method. -func (m *MockStorageAPI) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) { +func (m *MockStorageAPI) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageFromChild", root, keyToChild, key) + ret := m.ctrl.Call(m, "GetStorageFromChild", bhash, keyToChild, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageFromChild indicates an expected call of GetStorageFromChild. -func (mr *MockStorageAPIMockRecorder) GetStorageFromChild(root, keyToChild, key any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetStorageFromChild(bhash, keyToChild, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageFromChild), root, keyToChild, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageFromChild), bhash, keyToChild, key) } // RegisterStorageObserver mocks base method. diff --git a/dot/rpc/modules/mocks_test.go b/dot/rpc/modules/mocks_test.go index 0d86c09080..f3cd9355f6 100644 --- a/dot/rpc/modules/mocks_test.go +++ b/dot/rpc/modules/mocks_test.go @@ -121,18 +121,18 @@ func (mr *MockStorageAPIMockRecorder) GetStorageChild(bhash, keyToChild any) *go } // GetStorageFromChild mocks base method. -func (m *MockStorageAPI) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) { +func (m *MockStorageAPI) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageFromChild", root, keyToChild, key) + ret := m.ctrl.Call(m, "GetStorageFromChild", bhash, keyToChild, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageFromChild indicates an expected call of GetStorageFromChild. -func (mr *MockStorageAPIMockRecorder) GetStorageFromChild(root, keyToChild, key any) *gomock.Call { +func (mr *MockStorageAPIMockRecorder) GetStorageFromChild(bhash, keyToChild, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageFromChild), root, keyToChild, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageAPI)(nil).GetStorageFromChild), bhash, keyToChild, key) } // RegisterStorageObserver mocks base method. diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index 4eb104a849..fba1ec12e8 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -271,7 +271,12 @@ func (s *InmemoryStorageState) GetStorageChild(bhash *common.Hash, keyToChild [] } // GetStorageFromChild get a value from a child trie -func (s *InmemoryStorageState) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) { +func (s *InmemoryStorageState) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) { + root, err := s.GetStateRootFromBlock(bhash) + if err != nil { + return nil, err + } + tr, err := s.loadTrie(root) if err != nil { return nil, err diff --git a/dot/state/inmemory_storage_test.go b/dot/state/inmemory_storage_test.go index b7f2bde12d..282293697b 100644 --- a/dot/state/inmemory_storage_test.go +++ b/dot/state/inmemory_storage_test.go @@ -217,7 +217,7 @@ func TestGetStorageChildAndGetStorageFromChild(t *testing.T) { _, err = storage.GetStorageChild(&blockHash, []byte("keyToChild")) require.NoError(t, err) - value, err := storage.GetStorageFromChild(&rootHash, []byte("keyToChild"), []byte("keyInsidechild")) + value, err := storage.GetStorageFromChild(&blockHash, []byte("keyToChild"), []byte("keyInsidechild")) require.NoError(t, err) require.Equal(t, []byte("voila"), value) diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index 31df601626..d45c902beb 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -23,7 +23,7 @@ type StorageState interface { Entries(bhash *common.Hash) (map[string][]byte, error) // should be overhauled to iterate GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) - GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) + GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) LoadCode(hash *common.Hash) ([]byte, error) LoadCodeHash(hash *common.Hash) (common.Hash, error) diff --git a/lib/babe/mock_storage_state_test.go b/lib/babe/mock_storage_state_test.go index fd4eb1e613..44dc7caf3f 100644 --- a/lib/babe/mock_storage_state_test.go +++ b/lib/babe/mock_storage_state_test.go @@ -135,18 +135,18 @@ func (mr *MockStorageStateMockRecorder) GetStorageChild(bhash, keyToChild any) * } // GetStorageFromChild mocks base method. -func (m *MockStorageState) GetStorageFromChild(root *common.Hash, keyToChild, key []byte) ([]byte, error) { +func (m *MockStorageState) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStorageFromChild", root, keyToChild, key) + ret := m.ctrl.Call(m, "GetStorageFromChild", bhash, keyToChild, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStorageFromChild indicates an expected call of GetStorageFromChild. -func (mr *MockStorageStateMockRecorder) GetStorageFromChild(root, keyToChild, key any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) GetStorageFromChild(bhash, keyToChild, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageFromChild), root, keyToChild, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageFromChild", reflect.TypeOf((*MockStorageState)(nil).GetStorageFromChild), bhash, keyToChild, key) } // LoadCode mocks base method. From ce373f02799f321c319d03acd0f66073e0076a0b Mon Sep 17 00:00:00 2001 From: Haiko Schol Date: Wed, 2 Jul 2025 14:15:27 +0700 Subject: [PATCH 8/8] simplify StorageState and StorageAPI interfaces --- dot/core/mock_state_test.go | 31 ++++++++--------------------- dot/rpc/interfaces.go | 1 - dot/rpc/modules/api.go | 1 - dot/rpc/modules/api_mocks.go | 1 - dot/rpc/modules/mocks/mocks.go | 15 -------------- dot/rpc/modules/mocks_test.go | 15 -------------- dot/state/inmemory_storage.go | 16 +++++++-------- dot/state/storage_state.go | 5 ++--- lib/babe/mock_storage_state_test.go | 31 ++++++++--------------------- 9 files changed, 26 insertions(+), 90 deletions(-) diff --git a/dot/core/mock_state_test.go b/dot/core/mock_state_test.go index 3f2ec6f967..b337079090 100644 --- a/dot/core/mock_state_test.go +++ b/dot/core/mock_state_test.go @@ -971,21 +971,6 @@ func (mr *MockStorageStateMockRecorder) GetKeysWithPrefix(bhash, prefix any) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageState)(nil).GetKeysWithPrefix), bhash, prefix) } -// GetStateRootFromBlock mocks base method. -func (m *MockStorageState) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStateRootFromBlock", bhash) - ret0, _ := ret[0].(*common.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStateRootFromBlock indicates an expected call of GetStateRootFromBlock. -func (mr *MockStorageStateMockRecorder) GetStateRootFromBlock(bhash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateRootFromBlock", reflect.TypeOf((*MockStorageState)(nil).GetStateRootFromBlock), bhash) -} - // GetStorage mocks base method. func (m *MockStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() @@ -1032,33 +1017,33 @@ func (mr *MockStorageStateMockRecorder) GetStorageFromChild(bhash, keyToChild, k } // LoadCode mocks base method. -func (m *MockStorageState) LoadCode(arg0 *common.Hash) ([]byte, error) { +func (m *MockStorageState) LoadCode(bhash *common.Hash) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LoadCode", arg0) + ret := m.ctrl.Call(m, "LoadCode", bhash) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // LoadCode indicates an expected call of LoadCode. -func (mr *MockStorageStateMockRecorder) LoadCode(arg0 any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) LoadCode(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCode", reflect.TypeOf((*MockStorageState)(nil).LoadCode), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCode", reflect.TypeOf((*MockStorageState)(nil).LoadCode), bhash) } // LoadCodeHash mocks base method. -func (m *MockStorageState) LoadCodeHash(arg0 *common.Hash) (common.Hash, error) { +func (m *MockStorageState) LoadCodeHash(bhash *common.Hash) (common.Hash, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LoadCodeHash", arg0) + ret := m.ctrl.Call(m, "LoadCodeHash", bhash) ret0, _ := ret[0].(common.Hash) ret1, _ := ret[1].(error) return ret0, ret1 } // LoadCodeHash indicates an expected call of LoadCodeHash. -func (mr *MockStorageStateMockRecorder) LoadCodeHash(arg0 any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) LoadCodeHash(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCodeHash", reflect.TypeOf((*MockStorageState)(nil).LoadCodeHash), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCodeHash", reflect.TypeOf((*MockStorageState)(nil).LoadCodeHash), bhash) } // Lock mocks base method. diff --git a/dot/rpc/interfaces.go b/dot/rpc/interfaces.go index 89782d4683..ea6537b392 100644 --- a/dot/rpc/interfaces.go +++ b/dot/rpc/interfaces.go @@ -24,7 +24,6 @@ type StorageAPI interface { GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) - GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) RegisterStorageObserver(observer state.Observer) UnregisterStorageObserver(observer state.Observer) diff --git a/dot/rpc/modules/api.go b/dot/rpc/modules/api.go index 8a88b120b4..91c296b703 100644 --- a/dot/rpc/modules/api.go +++ b/dot/rpc/modules/api.go @@ -22,7 +22,6 @@ type StorageAPI interface { GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) Entries(bhash *common.Hash) (map[string][]byte, error) - GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) RegisterStorageObserver(observer state.Observer) UnregisterStorageObserver(observer state.Observer) diff --git a/dot/rpc/modules/api_mocks.go b/dot/rpc/modules/api_mocks.go index 10908b3550..6f527c6b0e 100644 --- a/dot/rpc/modules/api_mocks.go +++ b/dot/rpc/modules/api_mocks.go @@ -20,7 +20,6 @@ func NewMockAnyStorageAPI(ctrl *gomock.Controller) *modulesmocks.MockStorageAPI m.EXPECT().Entries(gomock.Any()).Return(nil, nil).AnyTimes() m.EXPECT().RegisterStorageObserver(gomock.Any()).AnyTimes() m.EXPECT().UnregisterStorageObserver(gomock.Any()).AnyTimes() - m.EXPECT().GetStateRootFromBlock(gomock.Any()).Return(nil, nil).AnyTimes() m.EXPECT().GetKeysWithPrefix(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes() return m } diff --git a/dot/rpc/modules/mocks/mocks.go b/dot/rpc/modules/mocks/mocks.go index b68d4e469d..03ecaa06a6 100644 --- a/dot/rpc/modules/mocks/mocks.go +++ b/dot/rpc/modules/mocks/mocks.go @@ -79,21 +79,6 @@ func (mr *MockStorageAPIMockRecorder) GetKeysWithPrefix(bhash, prefix any) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageAPI)(nil).GetKeysWithPrefix), bhash, prefix) } -// GetStateRootFromBlock mocks base method. -func (m *MockStorageAPI) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStateRootFromBlock", bhash) - ret0, _ := ret[0].(*common.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStateRootFromBlock indicates an expected call of GetStateRootFromBlock. -func (mr *MockStorageAPIMockRecorder) GetStateRootFromBlock(bhash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateRootFromBlock", reflect.TypeOf((*MockStorageAPI)(nil).GetStateRootFromBlock), bhash) -} - // GetStorage mocks base method. func (m *MockStorageAPI) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() diff --git a/dot/rpc/modules/mocks_test.go b/dot/rpc/modules/mocks_test.go index f3cd9355f6..cd7abaf76a 100644 --- a/dot/rpc/modules/mocks_test.go +++ b/dot/rpc/modules/mocks_test.go @@ -75,21 +75,6 @@ func (mr *MockStorageAPIMockRecorder) GetKeysWithPrefix(bhash, prefix any) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageAPI)(nil).GetKeysWithPrefix), bhash, prefix) } -// GetStateRootFromBlock mocks base method. -func (m *MockStorageAPI) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStateRootFromBlock", bhash) - ret0, _ := ret[0].(*common.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStateRootFromBlock indicates an expected call of GetStateRootFromBlock. -func (mr *MockStorageAPIMockRecorder) GetStateRootFromBlock(bhash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateRootFromBlock", reflect.TypeOf((*MockStorageAPI)(nil).GetStateRootFromBlock), bhash) -} - // GetStorage mocks base method. func (m *MockStorageAPI) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() diff --git a/dot/state/inmemory_storage.go b/dot/state/inmemory_storage.go index fba1ec12e8..3439740caf 100644 --- a/dot/state/inmemory_storage.go +++ b/dot/state/inmemory_storage.go @@ -111,7 +111,7 @@ func (s *InmemoryStorageState) StoreTrie(ts storage.TrieState, header *types.Hea // TrieState returns the TrieState for a given block hash. // If no block hash is provided, it returns the TrieState for the current chain head. func (s *InmemoryStorageState) TrieState(bhash *common.Hash) (storage.TrieState, error) { - root, err := s.GetStateRootFromBlock(bhash) + root, err := s.getStateRootFromBlock(bhash) if err != nil { return nil, fmt.Errorf("getting state root for block hash %s: %w", bhash.String(), err) } @@ -185,7 +185,7 @@ func (s *InmemoryStorageState) ExistsStorage(bhash *common.Hash, key []byte) (bo // GetStorage gets the object from the trie using the given key and block hash // If no hash is provided, the current chain head is used func (s *InmemoryStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { - root, err := s.GetStateRootFromBlock(bhash) + root, err := s.getStateRootFromBlock(bhash) if err != nil { return nil, err } @@ -199,8 +199,8 @@ func (s *InmemoryStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byt return inmemory_trie.GetFromDB(s.db, *root, key) } -// GetStateRootFromBlock returns the state root hash of a given block hash -func (s *InmemoryStorageState) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { +// getStateRootFromBlock returns the state root hash of a given block hash +func (s *InmemoryStorageState) getStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { if bhash == nil { b := s.blockState.BestBlockHash() bhash = &b @@ -226,7 +226,7 @@ func (s *InmemoryStorageState) StorageRoot() (common.Hash, error) { // Entries returns Entries from the trie for the given block hash func (s *InmemoryStorageState) Entries(bhash *common.Hash) (map[string][]byte, error) { - root, err := s.GetStateRootFromBlock(bhash) + root, err := s.getStateRootFromBlock(bhash) if err != nil { return nil, err } @@ -242,7 +242,7 @@ func (s *InmemoryStorageState) Entries(bhash *common.Hash) (map[string][]byte, e // GetKeysWithPrefix returns all that match the given prefix for the given hash // (or best block if hash is nil) in lexicographic order func (s *InmemoryStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []byte) ([][]byte, error) { - root, err := s.GetStateRootFromBlock(bhash) + root, err := s.getStateRootFromBlock(bhash) if err != nil { return nil, err } @@ -257,7 +257,7 @@ func (s *InmemoryStorageState) GetKeysWithPrefix(bhash *common.Hash, prefix []by // GetStorageChild returns a child trie, if it exists func (s *InmemoryStorageState) GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) { - root, err := s.GetStateRootFromBlock(bhash) + root, err := s.getStateRootFromBlock(bhash) if err != nil { return nil, err } @@ -272,7 +272,7 @@ func (s *InmemoryStorageState) GetStorageChild(bhash *common.Hash, keyToChild [] // GetStorageFromChild get a value from a child trie func (s *InmemoryStorageState) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) { - root, err := s.GetStateRootFromBlock(bhash) + root, err := s.getStateRootFromBlock(bhash) if err != nil { return nil, err } diff --git a/dot/state/storage_state.go b/dot/state/storage_state.go index d45c902beb..bda075bd82 100644 --- a/dot/state/storage_state.go +++ b/dot/state/storage_state.go @@ -16,7 +16,6 @@ type StorageState interface { TrieState(bhash *common.Hash) (rtstorage.TrieState, error) StoreTrie(rtstorage.TrieState, *types.Header) error - GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) GenerateTrieProof(stateRoot common.Hash, keys [][]byte) ([][]byte, error) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) StorageRoot() (common.Hash, error) @@ -25,8 +24,8 @@ type StorageState interface { GetStorageChild(bhash *common.Hash, keyToChild []byte) (trie.Trie, error) GetStorageFromChild(bhash *common.Hash, keyToChild, key []byte) ([]byte, error) - LoadCode(hash *common.Hash) ([]byte, error) - LoadCodeHash(hash *common.Hash) (common.Hash, error) + LoadCode(bhash *common.Hash) ([]byte, error) + LoadCodeHash(bhash *common.Hash) (common.Hash, error) RegisterStorageObserver(o Observer) UnregisterStorageObserver(o Observer) diff --git a/lib/babe/mock_storage_state_test.go b/lib/babe/mock_storage_state_test.go index 44dc7caf3f..ae954aabba 100644 --- a/lib/babe/mock_storage_state_test.go +++ b/lib/babe/mock_storage_state_test.go @@ -89,21 +89,6 @@ func (mr *MockStorageStateMockRecorder) GetKeysWithPrefix(bhash, prefix any) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKeysWithPrefix", reflect.TypeOf((*MockStorageState)(nil).GetKeysWithPrefix), bhash, prefix) } -// GetStateRootFromBlock mocks base method. -func (m *MockStorageState) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStateRootFromBlock", bhash) - ret0, _ := ret[0].(*common.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetStateRootFromBlock indicates an expected call of GetStateRootFromBlock. -func (mr *MockStorageStateMockRecorder) GetStateRootFromBlock(bhash any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateRootFromBlock", reflect.TypeOf((*MockStorageState)(nil).GetStateRootFromBlock), bhash) -} - // GetStorage mocks base method. func (m *MockStorageState) GetStorage(bhash *common.Hash, key []byte) ([]byte, error) { m.ctrl.T.Helper() @@ -150,33 +135,33 @@ func (mr *MockStorageStateMockRecorder) GetStorageFromChild(bhash, keyToChild, k } // LoadCode mocks base method. -func (m *MockStorageState) LoadCode(hash *common.Hash) ([]byte, error) { +func (m *MockStorageState) LoadCode(bhash *common.Hash) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LoadCode", hash) + ret := m.ctrl.Call(m, "LoadCode", bhash) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // LoadCode indicates an expected call of LoadCode. -func (mr *MockStorageStateMockRecorder) LoadCode(hash any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) LoadCode(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCode", reflect.TypeOf((*MockStorageState)(nil).LoadCode), hash) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCode", reflect.TypeOf((*MockStorageState)(nil).LoadCode), bhash) } // LoadCodeHash mocks base method. -func (m *MockStorageState) LoadCodeHash(hash *common.Hash) (common.Hash, error) { +func (m *MockStorageState) LoadCodeHash(bhash *common.Hash) (common.Hash, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LoadCodeHash", hash) + ret := m.ctrl.Call(m, "LoadCodeHash", bhash) ret0, _ := ret[0].(common.Hash) ret1, _ := ret[1].(error) return ret0, ret1 } // LoadCodeHash indicates an expected call of LoadCodeHash. -func (mr *MockStorageStateMockRecorder) LoadCodeHash(hash any) *gomock.Call { +func (mr *MockStorageStateMockRecorder) LoadCodeHash(bhash any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCodeHash", reflect.TypeOf((*MockStorageState)(nil).LoadCodeHash), hash) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadCodeHash", reflect.TypeOf((*MockStorageState)(nil).LoadCodeHash), bhash) } // Lock mocks base method.