From cd8ce62b40137b929a58b6a090a170e935575e20 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Thu, 30 Apr 2026 23:57:23 +0200 Subject: [PATCH] core: wait for prefetcher before reading PrefetchReadTimes Forward prefetchStateReader.Wait() through *reader.WaitPrefetch and call it before reading the read-time atomics. Eliminates the edge-case where prefetcher goroutines outlast block execution + commit. For slow blocks (the metric's target audience) this is a no-op; for fast blocks it ensures the metric is complete rather than slightly under. --- core/blockchain.go | 3 +++ core/state/reader.go | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/core/blockchain.go b/core/blockchain.go index 22d36e76c4..59f5716638 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -683,6 +683,9 @@ func (bc *BlockChain) processBlockWithAccessList(parentRoot common.Hash, block * // Sum read times across per-tx execution, BAL state-transition, and // prefetcher async fetches. Sum-of-CPU-time, not wall-clock. + if w, ok := prefetchReader.(interface{ WaitPrefetch() }); ok { + w.WaitPrefetch() // ensure all prefetcher reads are accounted for + } var prefetchAccountReads, prefetchStorageReads time.Duration if pr, ok := prefetchReader.(interface { PrefetchReadTimes() (time.Duration, time.Duration) diff --git a/core/state/reader.go b/core/state/reader.go index b184c75aeb..2128773ddf 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -576,3 +576,11 @@ func (r *reader) PrefetchReadTimes() (account, storage time.Duration) { } return 0, 0 } + +// WaitPrefetch blocks until the wrapped prefetcher (if any) finishes its +// task list. No-op for non-prefetch readers. +func (r *reader) WaitPrefetch() { + if pr, ok := r.StateReader.(interface{ Wait() error }); ok { + _ = pr.Wait() + } +}