From 6d3c6a19634c9b3e79752d97cd9d58c21aaa2e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 6 May 2024 17:24:18 +0300 Subject: [PATCH] core/state: don't use the prefetcher for missing snapshot items --- core/state/dump.go | 2 +- core/state/state_object.go | 17 +++++++++++------ core/state/statedb_test.go | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/core/state/dump.go b/core/state/dump.go index c9aad4f8e2..66802dcb95 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -165,7 +165,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey [] } if !conf.SkipStorage { account.Storage = make(map[common.Hash]string) - tr, err := obj.getTrie() + tr, err := obj.getTrie(true) if err != nil { log.Error("Failed to load storage trie", "err", err) continue diff --git a/core/state/state_object.go b/core/state/state_object.go index 4df29ba811..5087bed583 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -130,11 +130,16 @@ func (s *stateObject) touch() { // getTrie returns the associated storage trie. The trie will be opened // if it's not loaded previously. An error will be returned if trie can't // be loaded. -func (s *stateObject) getTrie() (Trie, error) { +// +// The skipPrefetcher parameter is used to request a direct load from disk, even +// if a prefetcher is available. This path is used if snapshots are unavailable, +// since that requires reading the trie *during* execution, when the prefetchers +// cannot yet return data. +func (s *stateObject) getTrie(skipPrefetcher bool) (Trie, error) { if s.trie == nil { - // Try fetching from prefetcher first - if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil { - // When the miner is creating the pending state, there is no prefetcher + // Try fetching from prefetcher first, unless skipping it was explicitly + // requested + if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil && !skipPrefetcher { trie, err := s.db.prefetcher.trie(s.addrHash, s.data.Root) if err != nil { log.Error("Failed to retrieve storage pre-fetcher trie", "addr", s.address, "err", err) @@ -211,7 +216,7 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { // If the snapshot is unavailable or reading from it fails, load from the database. if s.db.snap == nil || err != nil { start := time.Now() - tr, err := s.getTrie() + tr, err := s.getTrie(true) if err != nil { s.db.setError(err) return common.Hash{} @@ -315,7 +320,7 @@ func (s *stateObject) updateTrie() (Trie, error) { storage map[common.Hash][]byte origin map[common.Hash][]byte ) - tr, err := s.getTrie() + tr, err := s.getTrie(false) if err != nil { s.db.setError(err) return nil, err diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 71d64f5628..300ddfce06 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -551,7 +551,7 @@ func forEachStorage(s *StateDB, addr common.Address, cb func(key, value common.H if so == nil { return nil } - tr, err := so.getTrie() + tr, err := so.getTrie(true) if err != nil { return err }