Skip to content

Commit 354bf11

Browse files
authored
test(e2e): relax post-boundary slot assertion in epochs_proof_at_boundary (#23108)
## Summary Fixes flaky CI on `merge-train/spartan` ([run](https://github.com/AztecProtocol/aztec-packages/actions/runs/25570963690), [log](http://ci.aztec-labs.com/1778262953204813)) where `epochs_proof_at_boundary.parallel.test.ts > proof never lands so no checkpoint submission is attempted` failed with: ``` expect(received).toBe(expected) Expected: 31 Received: 32 > 312 | expect(Number(firstPostBoundary.slot)).toBe(Number(boundarySlot) + 1); ``` ## Root cause The assertion's inline comment explicitly acknowledges this is *empirical*: whether the on-chain prune fires in-tx at `boundarySlot+1` or only at `boundarySlot+2` depends on real-time L1 / proposer-rebuild timing. In this run, slot 31's pipelined propose still failed (`Rollup__InvalidArchive`) and slot 32 was the first slot where the propose was accepted and the checkpoint published. The merge-train head — #23098 (one-line log-context fix) — cannot influence this timing. The flake originated from #23056 (`feat(sequencer): build optimistically across pruning epoch boundary`) earlier in the same train. ## Fix Relax `toBe(boundarySlot + 1)` → `toBeLessThanOrEqual(boundarySlot + 2)` for both the no-parent and with-parent variants of "proof never lands". The lower bound is already enforced by `waitForFirstCheckpointAfterBoundary` filtering for `slot > boundarySlot`. The test's intent (a checkpoint lands in the new epoch shortly after the boundary) is preserved. The other two boundary tests where the proof DOES land use `checkpointNumber >= boundaryPublished.checkpoint`, not slot equality, so they aren't affected. Full analysis: https://gist.github.com/AztecBot/b4010e694332cca93a51024915867e9a ## Test plan CI on this PR. The container ClaudeBox runs in lacks docker / writeable cache, so local `./bootstrap.sh ci` could not be executed. ClaudeBox log: https://claudebox.work/s/d49b46d7e0cb49a6?run=1
1 parent a358573 commit 354bf11

1 file changed

Lines changed: 9 additions & 10 deletions

File tree

yarn-project/end-to-end/src/e2e_epochs/epochs_proof_at_boundary.parallel.test.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,13 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => {
302302
expect(boundaryPreparing.some(p => p.hadProposedParent)).toBe(true);
303303
expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true);
304304

305-
// After the boundary fails, the next slot's propose tx triggers the on-chain prune (since the
306-
// proof never landed and the deadline has expired) and resets `tips.pending`. The fresh
307-
// checkpoint against the genesis archive lands at boundarySlot+1: empirically the next slot's
308-
// proposer rebuilds with no proposed parent (the boundary's pipelined parent is invalidated
309-
// when its publish fails), the on-chain prune fires in-tx on this propose, and the propose
310-
// is accepted in the same slot.
305+
// After the boundary fails, a subsequent slot's propose tx triggers the on-chain prune (since
306+
// the proof never landed and the deadline has expired) and resets `tips.pending`. The fresh
307+
// checkpoint against the genesis archive should land within a few slots of the boundary —
308+
// empirically the next slot or two depending on whether the proposer rebuilds in time and
309+
// whether the on-chain prune fires in-tx on the first post-boundary propose attempt.
311310
const firstPostBoundary = await waitForFirstCheckpointAfterBoundary(events, boundarySlot);
312-
expect(Number(firstPostBoundary.slot)).toBe(Number(boundarySlot) + 1);
311+
expect(Number(firstPostBoundary.slot)).toBeLessThanOrEqual(Number(boundarySlot) + 2);
313312
expect(getEpochAtSlot(firstPostBoundary.slot, test.constants)).toBe(boundaryEpoch);
314313
});
315314

@@ -381,9 +380,9 @@ describe('e2e_epochs/epochs_proof_at_boundary', () => {
381380
expect(boundaryPreparing.every(p => !p.hadProposedParent)).toBe(true);
382381
expect(boundaryPreparing.some(p => p.provenOverride !== undefined)).toBe(true);
383382

384-
// See the parent test for the reasoning: the on-chain prune fires in-tx on the next slot's
385-
// propose, so the first post-boundary checkpoint lands at boundarySlot+1.
383+
// See the parent test for the reasoning: a subsequent slot's propose triggers the on-chain
384+
// prune in-tx, so the first post-boundary checkpoint lands within a couple of slots.
386385
const firstPostBoundary = await waitForFirstCheckpointAfterBoundary(events, boundarySlot);
387-
expect(Number(firstPostBoundary.slot)).toBe(Number(boundarySlot) + 1);
386+
expect(Number(firstPostBoundary.slot)).toBeLessThanOrEqual(Number(boundarySlot) + 2);
388387
});
389388
});

0 commit comments

Comments
 (0)