Skip to content

execution/commitment: budget-deferred db-hits lose overlay provenance across Run calls #23143

Description

@lystopad

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions