erigontech / erigontech/erigon
execution/commitment: budget-deferred db-hits lose overlay provenance across Run calls
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
`ContractTrunkPreloadParallel` classifies each frontier entry per `Run` call by looking it up in the `dbBranches` overlay it was handed (`sortAndPartitionFrontier`). Entries not found there become file misses and go to the batch resolver.
A `pathKey` that was a db-hit on one `Run` but got deferred into `p.frontier` by the budget carries no record of that. On a later `Run` the caller supplies a fresh overlay, and if the key is no longer in it and the file layer also lacks it (it existed only in the overlay), `resolve()` returns nil and the `v == nil { continue }` path drops it silently — indistinguishable from a genuine BFS-fringe absence, where a set `afterMap` bit names a leaf with no branch record.
The entry is skipped and its children are never queued, so the preload under-pins that subtree.
**Impact is performance, not correctness.** A missing pin is a `BranchCache` miss, and commitment falls back to reading the entry from the db/file layer as it would without any preload at all. No wrong data, no wrong root.
**Why it matters now.** `AdaptivePinController.runExtensionLocked` keeps one preload instance alive across blocks and calls it with a fresh overlay each time, so budget-deferred waves resuming into a rotated overlay is the normal path. Before #23066 such a wave either hung or drained within a single `Run`, so this was largely unreachable in practice.
Reported by @awskii in review of #23066 and deliberately left out of that PR, which is a livelock fix.
No test covers a db-hit surviving a deferral into a `Run` whose overlay no longer contains it — worth adding alongside whatever fix lands.
Contributor guide
Assessment
This issue has not been assessed yet.