Skip to content

test(prover): model parity and empty blocks the way the orchestrator schedules them - #176

Draft
spalladino wants to merge 1 commit into
spl/fi-s03-capacity-floorfrom
spl/fi-s04-proving-model
Draft

spalladino wants to merge 1 commit into
spl/fi-s03-capacity-floorfrom
spl/fi-s04-proving-model

Conversation

@spalladino

@spalladino spalladino commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator

The epoch proving simulation in prover-client/src/test/epoch_proving_sim.test.ts is a developer model of how the
orchestrator schedules proving jobs. It is used to reason about proving-time budgets, and it had two assumptions that
production does not share.

First, it treated the checkpoint's InboxParity proof as a dependency of the checkpoint's first block root. In
production the parity proof is proven from the start of the checkpoint and feeds the checkpoint root rollup; it runs
alongside block production and gates no block root at all. Second, it refused a zero-transaction block anywhere except
the first position in a checkpoint. Production has no such constraint: a block with no transactions has no base or
merge proof whose completion would queue its block root, so startNewBlock enqueues that block root itself, wherever
the block sits in the checkpoint.

Both are corrected here. A block root now depends only on its own tx tree. The checkpoint root joins two independent
branches — the reduced block tree and the single parity proof — and is reevaluated whenever either lands, so whichever
finishes last drives the enqueue. Because that join is now reachable from two directions, and because a zero-tx block
root is queued at block start rather than on a proof completion, both enqueues carry a per-key guard that keeps them
idempotent.

New coverage pins the corrected model: no, one and many transactions; a checkpoint mixing empty and non-empty blocks;
and the checkpoint root holding correctly in both orders, with parity landing first and with parity landing last. To
assert on ordering the simulation now records each finished job together with the window its simulated worker held it
for, and returns those records alongside the existing aggregate results.

This corrects a developer model. It is not a measured production regression, the numbers the simulation prints are
model output rather than measurements, and no production proving code is touched. The change is confined to a single
test file.

Stack position

This is rung 13 of 25 in the Fast Inbox node stack, stacked on spl/fi-s03-capacity-floor.

Provenance

Reconstructs the final behavior of bd2116390b (test(prover): model parity and empty blocks the way the orchestrator schedules them), the FI-S04 row of the Fast Inbox port stack, which replaces old PR #25440 with scoped rungs. The
ported diff matches the source commit's shape exactly: one file, +154 / -22.

Tests run

  • prover-client package suite, excluding the two real-proving bb_prover_* files: 16 suites, 256 passed / 6
    skipped
    , exit 0, 38s. Base branch, same command: 250 passed / 6 skipped — exactly the six new cases.
    bb_prover_full_rollup.test.ts and bb_prover_parity.test.ts drive real barretenberg proving and were not run
    locally; they are left to CI. Nothing in this rung can affect them.
  • yarn build, yarn format, yarn lint from yarn-project: all clean.
  • No e2e suites run.

Red/green

Both corrections were shown failing before the fix, by putting the new tests on the unchanged model:

  • Parity gating the first block root. proves an empty block root without waiting for inbox parity failed with the
    block root starting at 16900 instead of 0 — it had waited for the whole parity proof.
  • Tx-less block refused at a non-first position. proves zero-transaction blocks at any position in a checkpoint
    and holds the checkpoint root until parity lands when parity finishes last both threw
    Cannot create a block with 0 txs, unless it's the first block.

Three of the six new cases pass on the old model as intended controls, including
holds the checkpoint root until the block tree lands when parity finishes first, which holds in both models. After
the correction the file is 13/13 green.

The duplicate-enqueue guards are defensive, and this is stated rather than claimed otherwise. Replacing each
guard's early return with a throw and running every scenario in the file — including the large ignition, next-net
and alpha 1tps configurations — showed neither guard is reached: no scenario currently drives either join twice
after its dependencies are satisfied. They are carried from the source because they are what makes the two-sided join
idempotent, and the soleCompletion assertions in the new tests are what would catch a regression that broke that.
Removing either guard reddens nothing today, and no artificial fixture was manufactured to pretend otherwise.

Deliberately left out

No production proof-lifecycle change is included. Proof completion/lifetime joins and archive-after-close behavior are
deferred proof-lifecycle work and stay out of this stack; the source commit sits near that work and none of it was carried.
The Completion type introduced here is the simulation's own record of a finished job and its worker window, unrelated
to that deferred work. No other deferred item (the other six deferred work families) appears in the diff.

…schedules them

The developer proving-time simulation gated inbox parity behind the first block root and refused a
zero-transaction block anywhere but first. Production does neither: a zero-tx block enqueues its own block root
from startNewBlock at any position, and parity runs independently of block-root production, joining at
checkpoint-root readiness. The join is now reevaluated from whichever dependency finishes last and guarded
against a duplicate enqueue, with coverage for no/one/many transactions, mixed empty blocks, and parity landing
first or last.

This corrects a developer model. It is not a measured production regression, and its timings are model output.
@spalladino
spalladino added this pull request to stack #188 September 12, 2026 04:52
@spalladino spalladino added the ci-draft Run CI on this draft PR label Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-draft Run CI on this draft PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant