Release v0.8.1 — CONTEXT.headers is nine, not ten - #18
Merged
Conversation
…etime budget The three-slot flood guard on unknown-parent header requests was backed by a set that was only ever inserted into — never cleared when the parent arrived, never expired when none ever did. Three was therefore a budget for the life of the process rather than a cap on requests in flight. Once spent, the node could no longer ask for a missing parent at all, and recovered only if a peer volunteered the header unprompted. Observed 2026-08-18: a node that woke from suspend on an orphaned tip at 1,853,471 sat there 1h48m, receiving headers it could not attach, until a peer announced the one header it could no longer request. Slots are now released when the parent chains, and expire after 60s when it never arrives. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Consensus divergence, accept-side. The JVM's `lastHeaders` holds ten and includes the block's own header at the head; `sigmaLastHeaders` — what a script sees as CONTEXT.headers — is `lastHeaders.drop(1)`, so nine. `UpcomingStateContext` overrides that with the whole list, which is why candidate and mempool prediction saw ten. Our window holds headers strictly preceding the block, since the block's own header lives in the preheader. So the JVM's drop(1) never meant "drop something here" — it meant take nine instead of ten. We took ten everywhere. `headerChainBack(10, …)` was cited in the source as parity evidence; it gathers lastHeaders, not sigmaLastHeaders, and that citation is what made ten look right. A script reading CONTEXT.headers(9) evaluated here and threw ArrayIndexOutOfBoundsException on every JVM node — we would follow a chain the network orphans, with nothing in the logs reporting it. Surfaced by the mainnet block-production incident of 2026-08-18; resolution agreed cross-client as nine plus preheader on every path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.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.
Consensus fix: full-block validation exposed ten preceding headers where the reference node exposes nine, so this node could accept a block every JVM node rejects. Mempool and candidate paths aligned to nine as well. Surfaced by the mainnet block-production incident of 2026-08-18.
Also fixes a node getting stuck on an orphaned tip: the unknown-parent request guard was a lifetime budget, not an in-flight limit.
No resync required. 1102 tests pass.
🤖 Generated with Claude Code