test(archiver): make the re-mine fixture reach recovery - #174
Draft
spalladino wants to merge 2 commits into
Draft
spalladino wants to merge 2 commits into
spalladino wants to merge 2 commits into
Conversation
… helper addBlock resolves once the block is stored but triggers a sync it does not await, so every fixture that adds local blocks and then moves the L1 head backwards races the pass left in flight: recovery against the stale head can commit after the pass for the new head and leave the old height as the synced one. Two fixtures hit this, and both carried their own inline drain. Drain once in the shared helper instead, so the hazard is gone for the whole block and the two call-site drains become the no-op second calls they now are.
The fixture moved the messages to a later L1 block without replacing any block identity, so nothing on L1 ever disagreed with the log: it passed as an ordinary forward append and never reached recovery, while its name claimed it exercised a re-mine beyond the lookup window. Deleting the move left it green and unchanged, which is the proof. It is now split in two. The plain forward append it was really testing keeps its assertions under a name that says so, and a new fixture re-mines the descendants as well: L1 replaces every block from the messages' height on, the messages come back with their content, index and rolling hash intact sixty blocks later, and two more follow them. Every bounded lookup misses, the anchor falls back to the deployment block and the block that consumed the three messages is pruned even though they return unchanged. Discarding work that moved outside the bounded lookup window is the accepted cost of rolling back before refetching, and the test says so rather than only pinning the end state: it counts the three lookups and the prune that recovery performs.
spalladino
added this pull request to stack #188
September 12, 2026 04:52
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.
The re-mine fixture now replaces L1 block identities so it reaches recovery, while a shared helper drains the
block-triggered sync before the fixture rewrites L1. This is a test-only rung. No production source changes; the
single file touched is
yarn-project/archiver/src/archiver-sync.test.ts.The re-mine fixture never reached recovery
Inbox message recoverycarried a fixture named re-mines the same messages beyond the lookup window and appends newones without touching proposed blocks. It moved the stored messages to a later L1 block and then asserted that no
event lookup and no prune happened. Both assertions were true, but not for the reason the name claimed: moving the
messages does not replace any L1 block identity, so nothing ever disagreed with the stored log and the pass was an
ordinary forward append. Deleting the move line left the fixture green and byte-identical in outcome, which is the
demonstration that the re-mine was inert.
It is now split in two, as the source does. The plain forward append it was really exercising keeps its assertions
under the name appends new messages without disturbing the stored ones or the blocks that consumed them. A new
fixture, discards a block consuming unchanged messages that were re-mined beyond the lookup window, re-mines the
descendants too: L1 replaces every block from the messages' height on, the three messages come back with their
content, index and rolling hash intact sixty blocks later, and two new ones follow them. Every bounded lookup misses,
so the anchor falls back to the deployment block and the block that consumed the three messages is pruned even though
they return unchanged. Discarding work that moved outside the bounded lookup window is the accepted cost of rolling
back before refetching — the rollback precedes the refetch — and the fixture says so.
The fixture proves recovery ran rather than only pinning the end state: it counts the three per-message lookups and
the single prune, checks the pruned block by number, and then syncs again at the same head to show the log refetches
from L1 instead of resurrecting the pruned block.
Distance chosen
The window is not the
+/-5the source was written against. Since the 100-block-window rung it is the inclusive[h-49, h+50]thatmessageSentSearchWindowinethereum/src/contracts/inbox.tscomputes fromMESSAGE_SENT_SEARCH_WINDOW_BLOCKS = 100n, clipped at genesis and at the captured head. Messages recorded at L1block 100 therefore have a lookup window of
[51, 150]. The re-mine moves them to block 160 — ten blocks past thetop of the window, with the head at 165 so no clipping is in play — which matches the 59-and-60-block distances the
neighbouring fixtures were re-pinned to on that rung. The source's own 20-block move would now sit comfortably
inside the window and would not miss.
Drain consolidation
addBlockresolves once the block is stored but triggers a sync it does not await, so a fixture that adds localblocks and then moves the L1 head backwards races the pass left in flight: recovery against the stale head can commit
after the pass for the new head and leave the old height as the synced one. Two fixtures hit this and each carried
its own inline drain. The drain now lives once inside the shared
addLocalBlocksConsuminghelper, and the twocall-site drains — which would be no-op second calls — are gone. This completes what the recovery-anchor
authentication rung started: it added the inline drains because the helper-side drain belongs to this change.
Stack position
This is rung 11 of 25 in the Fast Inbox node stack, stacked on
spl/fi-s12-100-block-window.Sources
Reconstructs the archiver part of old PR #25440 commit
4ef9a73073("test: make three fixtures exercise what they claim to"), pluscd5d1f41d3("drain the block-triggered sync inside the local-block helper") andcc6d63ac94("drop the drain nowcovered by the local-block helper") together.
The other two parts of
4ef9a73073are not in this PR: itsend-to-end/src/single-node/cross-chain/streaming_inbox.test.tshunks (thefindInsertingBlockbisection) go to theinsertion-block bisection rung, and its
regenerate_rollup_sample_inputs.test.tshunks (shape-based sample selection)go to the continuation-shaped sample-selector rung.
The new fixture is added in its post-authentication form, without the
fake.setFinalizedL1BlockNumber(95n)line that882af4bc3ddeletes upstream: once every anchor is authenticated on L1 there is no inherited-finality shortcut leftfor that line to defeat, so it is never added rather than added and removed.
Tests run
yarn buildfromyarn-project: green.yarn format --checkandyarn lintover the whole project: clean, exit 0.JEST_MAX_WORKERS=1 yarn workspace @aztec-labs/archiver test: 23 suites, 682 tests,exit 0 (base 681; the split adds one).
archiver-sync.test.tsrepeated 15 times: 15/15 clean, 107 tests each. The drain consolidation does notreintroduce the race at either call site the inline drains were covering.
removing the block-identity replacement from the new fixture reddens it at
expected 3 lookups, received 0— theexact defect the old fixture had. At
LOG_LEVEL=infothe new fixture logs the disagreement at L1 block 165, therollback from 3 messages to 0 with
anchorL1BlockNumber: 0, and the prune of proposed block 1.Left out
No end-to-end suites were run; they are left to CI. None of the seven deferred work families is touched — the
diff is one test file and contains no production symbols at all. Developer and operator docs remain owned by
aztec-packages.