Repository navigation
Drop only interested requests when a historical ledger entry is missing - #8527
Merged
Merged
Conversation
delete_all_interested_requests used Request::get_store_details, which looks up the cache-wide all_stores map shared by every request. While the StoreDetails for the missing seqno was alive, every request looked interested and was erased in handle order until the last owner died, or all of them when next_secret_fetch_handle was the owner. Decide interest per request instead: a request is interested if the seqno is in its own stores, its supporting signatures, or is the ledger secret entry it is waiting for. Also release next_secret_fetch_handle when its entry is erased so the orphaned StoreDetails is not retained. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Amaury Chamayou (achamayou)
October 7, 2026 22:16
View session
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
CI checks remain in progress, leaving validation incomplete.
0 open findings
What changed in this PR
Fixes historical-query cache eviction so a missing or oversized ledger entry drops only requests that depend on it.
Changes:
- Tracks request-specific dependencies and releases failed ledger-secret fetch ownership.
- Adds regression coverage for direct requests, supporting signatures, and ledger-secret recovery.
- Documents the fix under version 7.0.19.
Custom instructions used
Applied the supplied repository, security/safety, and changelog guidance; corresponding instruction files were unavailable locally.
| File | Description |
|---|---|
src/node/test/historical_queries.cpp |
Verifies unrelated requests survive missing entries. |
src/node/historical_queries.h |
Restricts eviction and cleans up failed secret fetches. |
CHANGELOG.md |
Records the historical-query availability fix. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Max (maxtropets)
approved these changes
Oct 8, 2026
Eddy Ashton (eddyashton)
approved these changes
Oct 8, 2026
Eddy Ashton (eddyashton)
enabled auto-merge (squash)
October 8, 2026 14:15
Amaury Chamayou (achamayou)
added a commit
that referenced
this pull request
Oct 9, 2026
Mark the routing index queries [[nodiscard]] and take the request handle by value, as clang-tidy requires. After merging the base, a missing entry drops only the requests interested in it (#8527), so the rejection regression now checks that the unrelated request survives, and the routing oracle checks that Request::is_interested_in agrees with routing membership at every indexed seqno. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Amaury Chamayou (achamayou)
added a commit
that referenced
this pull request
Oct 10, 2026
Mark the routing index queries [[nodiscard]] and take the request handle by value, as clang-tidy requires. After merging the base, a missing entry drops only the requests interested in it (#8527), so the rejection regression now checks that the unrelated request survives, and the routing oracle checks that Request::is_interested_in agrees with routing membership at every indexed seqno. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Amaury Chamayou (achamayou)
added a commit
that referenced
this pull request
Oct 12, 2026
Mark the routing index queries [[nodiscard]] and take the request handle by value, as clang-tidy requires. After merging the base, a missing entry drops only the requests interested in it (#8527), so the rejection regression now checks that the unrelated request survives, and the routing oracle checks that Request::is_interested_in agrees with routing membership at every indexed seqno. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Found while reviewing #8525 (pre-existing on
main, no tracking issue).When the host reports
NotFoundorTooLargefor a requested ledger range,StateCacheImpl::handle_no_entry_rangecallsdelete_all_interested_requests(seqno)to drop the requests which were asking for that entry. Its predicate wasRequest::get_store_details(seqno) != nullptr, which looks up the cache-wideall_storesmap shared by every request rather than the request's own stores. While theStoreDetailsfor that seqno was alive, every request looked interested, so requests were erased in handle order until the last owner of the details died:next_secret_fetch_handleowned the details (the entry was being fetched to recover an older ledger secret), nothing in the loop released it, so every in-flight historical request was dropped.Implementation summary
Request::is_interested_in(seqno): true iff the seqno is inmy_stores, insupporting_signatures, or is the ledger secret entry the request is waiting for (awaiting_ledger_secrets).delete_all_interested_requestsnow uses it.handle_no_entry_rangeresetsnext_secret_fetch_handlewhen the erasedall_storesentry is the one it points at, so the orphanedStoreDetailsis not retained. Tick/expiry/sweep logic is untouched.src/node/test/historical_queries.cpp, each failing before the fix:Missing entries only drop interested requests: an unrelated lower-handle request survives and is served afterhandle_no_entry; the interested request is dropped. Also covers interest held only throughsupporting_signatures.Missing ledger secret entries only drop waiting requests: recovered-node scenario where only the request awaiting the previous ledger secret is dropped.7.0.19/Fixed.Validation:
historical_queries_test(21 cases) passes;cpp-format-checks.sh,prettier-checks.sh,release-notes-checks.sh,ascii-checks.sh,copyright-checks.sh,todo-checks.shpass. A mutation check (removing thesupporting_signatures/awaiting_ledger_secretsclauses) makes the corresponding assertions fail.Safety and compatibility
Availability fix only: the untrusted host could previously cause unrelated historical queries (or all of them) to be dropped by reporting one entry as missing; the affected queries would simply restart on the next request. No change to what entries are trusted, to receipts, to consensus/KV, to any API or data format, or to mixed-version operation. Interest tracking is now strictly per request, and dropped requests are evicted via the existing
lru_evictpath.