Commit fbc1e32
committed
feat(fast-inbox): per-block L1-to-L2 message bundles, move parity to checkpoint root (A-1374)
Stacked on #24600 (A-1373). AZIP-22 Fast Inbox, FI-04.
Moves parity verification from the block-root circuits to the **checkpoint root**, and gives every block-root variant a per-block L1→L2 message bundle. This gets the circuit structure right for per-block messages while keeping behavior bit-identical to today — the flip to compact per-block distribution (FI-14) becomes a constant change plus padding removal, not a circuit restructure.
- **Block-root variants** take a message bundle (`l1_to_l2_messages`, `num_msgs`, frontier hint) and append it to the L1→L2 tree via `append_leaves_to_snapshot` (the A-1372 gadget), absorbing the same leaves into an `L1ToL2MessageSponge` (Poseidon2) threaded across the checkpoint's blocks. First-block variants lose the parity-root proof.
- **`BlockRollupPublicInputs`** drops `in_hash` and the FI-03 `inbox_rolling_hash` pair; gains `is_first_block: bool` and `start_msg_sponge`/`end_msg_sponge`. `is_first_block` takes over `in_hash`'s former structural role (leftmost asserted true at the checkpoint root, every right rollup asserted false at merge) and drives the block-end blob-absorb flag.
- **Block merge** propagates `is_first_block` and `start_msg_sponge` from the left, `end_msg_sponge` from the right; `validate_consecutive_block_rollups` asserts `!right.is_first_block` and `right.start_msg_sponge == left.end_msg_sponge`.
- **Checkpoint root** verifies the moved parity-root proof, asserts `parity.start_sponge == empty` and `merged.end_msg_sponge == parity.end_sponge` (the "blocks inserted exactly the parity-committed list, in order" check — no leaf arrays cross a circuit boundary), and sources the header's `in_hash = parity.sha_root` and `inbox_rolling_hash = parity.end_rolling_hash`.
- **Parity** base absorbs the padded batch into a message sponge; parity root threads it across the four bases alongside the rolling hash.
- New `stdlib/src/messaging/l1_to_l2_message_sponge.ts` mirrors the noir sponge (iv-0, absorb-only). Parity/block/checkpoint-root inputs and `conversion/server.ts` mirror the field changes.
- Orchestrator DAG: parity proofs move from `block-proving-state.ts` to `checkpoint-proving-state.ts`; the sub-tree enqueues parity once per checkpoint and surfaces it in `SubTreeResult`; block roots no longer gate on parity. Transitional wiring: first block carries the checkpoint's messages padded to 1024 (`num_msgs=1024`), non-first blocks carry empty bundles inheriting the checkpoint sponge.
`L1_TO_L2_MESSAGE_SPONGE_LENGTH = 10`; `BLOCK_ROLLUP_PUBLIC_INPUTS_LENGTH` 58 → 76. Circuit ABIs changed, so `pinned-build.tar.gz` is regenerated and committed.
- noir `rollup_lib` 386 passed (adds sponge-threading, `is_first_block` structural, and checkpoint-root parity/sponge-mismatch failure cases); transitional equivalence held (`append_matches_subtree_insert_1024`, unchanged checkpoint-header fixtures).
- `yarn build`, `yarn lint`/`format`, forge, orchestrator suites (15), and touched stdlib suites (22) all green.
- Cross-chain `l1_to_l2` e2e: the real send+consume path (the new per-block bundle circuit path) works; the suite's only two cases are the duplicate re-consumption ones, which hit a pre-existing PXE nullifier-sync issue registered flaky in `.test_patterns.yml`, unrelated to this change.
- A codex cross-layer review found no correctness bugs; it confirmed sponge chunking associativity, tree/list pinning, `is_first_block` soundness, header sourcing/continuity, the blob-flag derivation, and TS↔noir serde order.
This branch now carries the oldest-epoch-first proving-broker scheduling fix (originally the head commit of #24759 / A-1427), moved down to the base of this segment. On the intermediate stack the single prover agent otherwise starves `PARITY_BASE` behind later-epoch `BLOCK_ROOT` jobs, so `long_proving_time` deterministically times out here; with the commit present it passes (`generates proof over multiple epochs`, verified on a bb-capable box). The move is content-neutral at the stack top — only the commit's position changed.
The relocated commit's proving-broker test asserts an older epoch beats a higher-priority proof type from a younger epoch. It needs a proof type that is (a) lower-priority than `PRIVATE_TX_BASE_ROLLUP` and (b) present under the same name across the whole stack, since this commit sits at the base and its content flows up unchanged. No parity name qualifies: it originally used `INBOX_PARITY` (only exists at A-1427 and above), and `PARITY_BASE` only exists at A-1374/A-1375 because A-1427 replaces both `PARITY_BASE`/`PARITY_ROOT` with a single `INBOX_PARITY`. The test now uses `PUBLIC_VM`, which is stable across the entire stack and sits just below `PRIVATE_TX_BASE_ROLLUP` in `PROOF_TYPES_IN_PRIORITY_ORDER` at every branch. Verified with a real `tsc` (not jest) at the owning branch (below the flip), at A-1384 (above the flip), and at the stack top.
Replaces #24603.1 parent c3cb239 commit fbc1e32
71 files changed
Lines changed: 9990 additions & 4123 deletions
File tree
- noir-projects/fnd/noir-protocol-circuits/crates
- rollup-block-merge
- rollup-block-root-first-empty-tx
- rollup-block-root-first-single-tx
- rollup-block-root-first
- rollup-block-root-single-tx
- rollup-block-root
- rollup-checkpoint-merge
- rollup-checkpoint-root-single-block
- rollup-checkpoint-root
- rollup-lib/src
- abis
- block_merge
- tests
- utils
- block_root
- components
- tests
- checkpoint_root
- components
- tests
- parity
- tests
- tests
- rollup-root
- types/src
- playground
- yarn-project
- ivc-integration/src
- noir-protocol-circuits-types/src/conversion
- prover-client/src
- orchestrator
- proving_broker
- test
- prover-node/src/job
- stdlib/src
- messaging
- parity
- rollup
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
378 | 378 | | |
379 | 379 | | |
380 | 380 | | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
381 | 391 | | |
382 | 392 | | |
383 | 393 | | |
| |||
Lines changed: 273 additions & 205 deletions
Large diffs are not rendered by default.
Lines changed: 1040 additions & 558 deletions
Large diffs are not rendered by default.
Lines changed: 1160 additions & 678 deletions
Large diffs are not rendered by default.
Lines changed: 1286 additions & 804 deletions
Large diffs are not rendered by default.
Lines changed: 1205 additions & 122 deletions
Large diffs are not rendered by default.
Lines changed: 1354 additions & 271 deletions
Large diffs are not rendered by default.
Lines changed: 250 additions & 250 deletions
Large diffs are not rendered by default.
Lines changed: 762 additions & 137 deletions
Large diffs are not rendered by default.
Lines changed: 914 additions & 255 deletions
Large diffs are not rendered by default.
0 commit comments