Skip to content

feat: merge-train/spartan-v5 - #24641

Merged
AztecBot merged 2 commits into
v5-nextfrom
merge-train/spartan-v5
Jul 10, 2026
Merged

feat: merge-train/spartan-v5#24641
AztecBot merged 2 commits into
v5-nextfrom
merge-train/spartan-v5

Conversation

@AztecBot

@AztecBot AztecBot commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

BEGIN_COMMIT_OVERRIDE
fix(prover-node): rebuild pruned checkpoint provers and recover the epoch (#24436)
END_COMMIT_OVERRIDE

…poch (#24436)

Resolves A-1290.

## Problem

A `CheckpointProver`'s sub-tree work forks world-state per block. When
an L1 reorg prunes a base block, those fork reads fault and the prover
permanently rejects its one-shot `blockProofs` promise.

The store keeps the prover alive across a prune (`markPruned`) so a
re-add of identical content can reuse its in-flight work. But a prune
that removes the checkpoint also breaks the fork reads, so that reuse
only ever hands back a poisoned prover: a re-add or a full
`EpochSession` recreate re-references the same rejected `blockProofs`
and fails immediately. The affected node then silently abandons the
epoch until a process restart (a healthy prover elsewhere still proves
it, so it's not a network stall).

## Fix

**Drop the reuse machinery — a pruned prover cannot survive, so rebuild
instead of reuse.**

- `CheckpointStore.cancelAndRemoveAboveBlock` cancels and **removes**
orphaned provers (replacing `markPrunedAboveBlock`); a re-add builds a
fresh prover with a fresh `blockProofs`.
- Removed the `pruned` flag / `markPruned` / `markCanonical` from
`CheckpointProver`, and the `SlotWatcher` that only reaped lingering
pruned provers.
- `listCanonical` / `addOrUpdate` simplified — every prover in the store
is now canonical.

**Recover the epoch by rebuilding on re-add, rather than trying to
prevent the terminal state.**

A prune unwinds world-state as soon as it's detected — before the
prover-node cancels the affected session — so a checkpoint prover
mid-fork faults while still live and its session goes terminal `failed`.
That race is inherent (the world-state rejection and the prover being
cancelled are unordered), so instead of trying to reclassify it as a
cancellation, we make the terminal state harmless:

- `SessionManager.openFullSessionIfReady` no longer treats a terminal
session as "already open" — it drops it and rebuilds. So re-adding an
epoch's checkpoints reopens a fresh live session over fresh provers, via
the checkpoint/prune triggers (ungated by the tick high-water mark).
This reopen depends on the store no longer holding the poisoned prover:
with the reuse machinery gone the rebuilt session gets a fresh prover
with a healthy `blockProofs`, so it can actually prove rather than
re-inheriting the rejected one.
- `runSession` skips the failure-upload when the session's checkpoints
no longer match canonical content — a prune-invalidated failure isn't a
genuine proving failure, so it no longer emits a spurious post-mortem
upload / alert.

The only non-recovered case is "content pruned and never re-added"
(chain stops publishing that epoch's checkpoints) — there's nothing to
prove on this node then, so abandoning the epoch is correct.

**Cancel the pruned prover's in-flight work promptly.**
`CheckpointProver` now threads its abort signal into
`PublicProcessor.process`, so a prune-driven cancel stops the current
block's public execution immediately instead of running it to completion
before the next `signal.aborted` check. This is independent of the
recovery logic above — it just avoids wasting CPU re-executing a block
whose checkpoint is being discarded. The in-flight block has not yet
enqueued a broker proof, so aborting it loses no reusable work.

### Note: broker-level proof reuse is unaffected

Removing the `CheckpointProver`-level reuse does not waste proving work.
The expensive part — the SNARK proofs — is cached in the proving broker,
content-addressed by job id, independent of world-state.
`cancelJobsOnStop` defaults to `false`, so cancelling a prover does not
abort its broker jobs; on an identical re-add the fresh prover
regenerates identical inputs, and the broker dedups against the cached
jobs/results (bounded by the broker's per-epoch cleanup). The reuse we
deleted was witness-generation reuse, whose world-state forks cannot
survive a prune anyway.

## Testing

- `session-manager.test.ts`: pins the retry/recovery invariant — the
periodic tick does not re-attempt a failed epoch (gated by
`lastTickEpoch`), but a checkpoint re-add recovers it (ungated); a
`failed` session's epoch is reopened once its checkpoints are re-added;
a genuine proving failure still uploads a post-mortem; a failure
coinciding with a canonical content change (prune) skips the upload.
(Red/green verified for both the gate and the upload suppression.)
- `checkpoint-store.test.ts` / `prover-node.test.ts`: pruned provers are
cancelled and removed (not flagged); a re-add builds a fresh prover.
- `checkpoint-prover.test.ts`: cancelling a prover mid-block aborts the
signal its public execution is running under (red/green verified).
- Full prover-node suite passes (166 tests); package typechecks clean;
lint OK.
- Updated `optimistic.parallel.test.ts` (the e2e that spawned this
issue) to the cancelled+removed semantics.

## Notes

- No operator/contract-dev-facing config or API changed, so no changelog
entry.
- The terminal `failed` state is not prevented, only recovered from: the
world-state unwind and the prover cancellation are unordered, so the
failure can't be reliably reclassified from the session side. Recovering
on re-add is deterministic and needs no such race to be won.

@ludamad ludamad left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto-approved

@AztecBot
AztecBot added this pull request to the merge queue Jul 10, 2026
@AztecBot

Copy link
Copy Markdown
Collaborator Author

🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass.

Merged via the queue into v5-next with commit 571b584 Jul 10, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants