Skip to content

chore(fast-inbox): delete legacy L1 inbox path (A-1386) - #24791

Closed
spalladino wants to merge 10 commits into
spl/a-1385-streaming-e2efrom
spl/a-1386-l1-cleanup
Closed

chore(fast-inbox): delete legacy L1 inbox path (A-1386)#24791
spalladino wants to merge 10 commits into
spl/a-1385-streaming-e2efrom
spl/a-1386-l1-cleanup

Conversation

@spalladino

@spalladino spalladino commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Deletes the legacy L1 Inbox path now that propose enforces streaming-inbox consumption (AZIP-22 Fast Inbox, FI-16). Stacked on spl/a-1385-streaming-e2e; part of the Fast Inbox stack (#24784..#24790 below this one).

What is deleted

  • Frontier trees: the trees mapping, forest, HEIGHT/SIZE/EMPTY_ROOT, the per-message tree insert, getRoot(), and the whole consume() flow.
  • LAG / inboxLag: the LAG immutable and _lag/_height constructor args (the Inbox constructor is now (rollup, feeAsset, version, bucketRingSize)), RollupConfigInput.inboxLag and its RollupCore pass-through, and Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT from the Inbox construction.
  • Dead event field: the MessageSent.checkpointNumber (former inProgress) argument, which became meaningless once consume() stopped advancing it.
  • Orphaned errors: Inbox__Unauthorized, Inbox__MustBuildBeforeConsume, Rollup__InvalidInHash.

What is re-homed / kept

  • The compact message index now reads the current bucket's running total (totalMsgCount) instead of a parallel counter; InboxState.inProgress and getInProgress() are gone.
  • The 128-bit rollingHash, InboxState.{rollingHash, totalMessagesInserted}, getState(), and getTotalMessagesInserted() are kept: the node still consumes them for message sync and L1-reorg detection. Their removal is the node cleanup's job (FI-18).
  • FrontierLib is kept — it still backs the base-parity (test/Parity.t.sol) and merkle (test/merkle/Frontier.t.sol) tests, which are unrelated to the Inbox (parity-circuit territory, FI-17). The plan's "delete the file" assumption is contradicted by grep.

TS follow-through

  • ethereum InboxContract: drop getLag(), drop the MessageSent.checkpointNumber decode, stop reading inProgress; InboxContractState.treeInProgress is now optional (no longer tracked on-chain).
  • Stop threading inboxLag through queries.getL1ContractsConfig and the L1 deploy env. The broader AZTEC_INBOX_LAG config sweep (ethereum/src/config.ts, foundation, stdlib, ~30 e2e configs) is deferred to FI-18, which explicitly owns it.
  • Archiver decode derives the message's checkpoint number from the compact index (the event no longer carries it), keeping the legacy per-checkpoint store shape untouched for FI-18.
  • Removed the obsolete advanceInboxInProgress cheat code + its inbox-drift tests, and the orphaned archiver inHash-mismatch sync test (the cross-check was removed at the flip).

Gas

Deleting the frontier insert is a large sendL2Message win. Whole-test gas (forge test on InboxBuckets.t.sol), before → after:

Case Before After
First-ever message 175,251 116,835
First message of a new L1 block 329,460 195,555
Absorb into an existing bucket 286,673 149,968
Rollover mid-block (256 messages) 18,923,988 3,068,480

Per-call sendL2Message gas after cleanup: first-ever 99,526; first-of-new-block 53,763; existing-bucket absorb 9,273; rollover 53,801.

Testing

  • forge build + forge test green: 887 passed, 0 failed. This fixes 4 pre-existing baseline failures the flip stranded (fee_portal/TokenPortal deposit tests using tree-relative indices + the old event shape).
  • @aztec/ethereum builds clean; config/queries unit tests green.
  • @aztec/archiver has no self-owned type errors; message_store (36), archiver-sync (59), and the decode/struct suites (58) all pass. (Pre-existing noir-protocol-circuits-types stale-artifact errors are unaffected.)
  • e2e not run locally. The stability gate ("a few days of green e2e/networks before deleting the fallback") applies at merge time for this stacked line, not at PR creation.

Review follow-up (phase-2 final review)

Deleting the inbox-drift bot test left bot.test.ts's cheatCodes variable unused (lint error); a follow-up commit removes it.

Leftover sweep (post-review)

  • Corrected the PublicInputArgs natspec in IRollup.sol: it still described previousInboxRollingHash / endInboxRollingHash as deliberately unvalidated "until the Fast Inbox flip", but the flip (feat(fast-inbox): flip consensus to streaming inbox (A-1384) #24789, below this branch) added exactly that validation — EpochProofLib anchors the start boundary against the propose-time record, and the end boundary is covered transitively by the stored checkpoint header hashes. The comment now describes the implemented behavior.
  • The 128-bit rolling hash this PR deliberately kept (see "What is re-homed / kept") is now removed at the node-cleanup PR chore(fast-inbox): delete legacy node message paths (A-1388) #24793, where its last TS readers disappear.

@spalladino
spalladino requested a review from just-mitch as a code owner July 18, 2026 17:24
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from 651d40c to 14003e9 Compare July 19, 2026 01:25
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from 86a8360 to a7eb238 Compare July 19, 2026 01:25
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from 14003e9 to e65d6c5 Compare July 19, 2026 14:05
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch 2 times, most recently from 721cb08 to f09a847 Compare July 19, 2026 15:10
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from bba7724 to e896f31 Compare July 19, 2026 15:36
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from f09a847 to 8fa5988 Compare July 19, 2026 15:36
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from e896f31 to a1f18f3 Compare July 19, 2026 17:57
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from 8fa5988 to 60d21bc Compare July 19, 2026 17:57
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from a1f18f3 to 7d0b8da Compare July 19, 2026 20:30
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from 225d2e7 to 3eb6939 Compare July 19, 2026 20:30
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from 7d0b8da to 6599148 Compare July 19, 2026 20:48
@spalladino
spalladino requested a review from a team as a code owner July 19, 2026 20:48
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch 2 times, most recently from 70acb89 to 7a02f46 Compare July 19, 2026 20:51
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch 2 times, most recently from 595fd99 to 7c61dba Compare July 20, 2026 13:32
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch 2 times, most recently from 180983d to 7d55b36 Compare July 20, 2026 14:07
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from 7c61dba to 6057ab5 Compare July 20, 2026 14:07
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from 7d55b36 to df4a7eb Compare July 20, 2026 15:30
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from 36db4d0 to e971f40 Compare July 20, 2026 17:28
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch 2 times, most recently from 480a601 to 670ebbf Compare July 20, 2026 21:21
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch 2 times, most recently from 231a93d to fb159da Compare July 21, 2026 02:58
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from 670ebbf to 11b1638 Compare July 21, 2026 02:58
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from fb159da to faaf5c2 Compare July 21, 2026 03:39
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch 2 times, most recently from cf29763 to 7b32375 Compare July 21, 2026 04:43
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch 2 times, most recently from 611555a to 342c25c Compare July 21, 2026 12:06
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch 2 times, most recently from 2b91492 to 5295095 Compare July 21, 2026 15:02
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch from 342c25c to 2f89525 Compare July 21, 2026 15:02
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from 5295095 to e853cd3 Compare July 21, 2026 22:32
@spalladino
spalladino force-pushed the spl/a-1385-streaming-e2e branch 2 times, most recently from 1a51d95 to 6b97921 Compare July 27, 2026 20:53
@spalladino
spalladino force-pushed the spl/a-1386-l1-cleanup branch from e853cd3 to b6d1007 Compare July 27, 2026 20:53
Remove the frontier-tree machinery, legacy consume(), the LAG/inboxLag
plumbing and the dead MessageSent event field now that propose enforces
streaming-inbox consumption (AZIP-22 Fast Inbox).

Inbox / IInbox:
- Drop the frontier tree forest (trees mapping, forest, HEIGHT/SIZE/EMPTY_ROOT),
  the per-message tree insert, getRoot(), and consume().
- Drop the LAG immutable and the _lag/_height constructor args; the constructor
  now takes only (rollup, feeAsset, version, bucketRingSize).
- Source the compact message index from the current bucket's running total
  instead of a parallel counter; drop InboxState.inProgress and getInProgress().
- Drop the meaningless checkpointNumber (former inProgress) from MessageSent.
- Keep the 128-bit rolling hash, InboxState.{rollingHash,totalMessagesInserted}
  and getState()/getTotalMessagesInserted(): the node still consumes them for
  message sync and L1-reorg detection until that path is retired.

Rollup / config / errors:
- Remove RollupConfigInput.inboxLag and the RollupCore constructor pass-through;
  drop Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT from the Inbox construction.
- Sweep orphaned errors Inbox__Unauthorized, Inbox__MustBuildBeforeConsume and
  Rollup__InvalidInHash; refresh the now-stale ProposeLib NatSpec.

Tests: delete the frontier/consume suites and fuzz, re-home the bucket/rolling-hash
coverage, update the propose-path fixtures (inHash is an unconstrained hint now),
and fix the flip-stranded fee-portal/token-portal index and event expectations.

FrontierLib is kept: it still backs the base-parity and merkle Frontier tests.
… (A-1386)

Track the regenerated Inbox ABI after the legacy L1 path was removed
(AZIP-22 Fast Inbox):

- ethereum InboxContract: drop getLag() (the LAG getter is gone) and the
  MessageSent checkpointNumber decode; getState() no longer reads inProgress and
  InboxContractState.treeInProgress becomes optional (no longer tracked on-chain).
- Stop threading inboxLag through queries/getL1ContractsConfig and the L1 deploy
  env; the broader AZTEC_INBOX_LAG config removal is deferred to the node cleanup.
- archiver decode: derive the message's checkpoint number from the compact index
  (the event no longer carries it), keeping the legacy per-checkpoint store shape.
- Remove the obsolete advanceInboxInProgress cheat code and its inbox-drift tests;
  drop the orphaned archiver inHash-mismatch sync test (the cross-check was removed
  at the flip). Add the flip-stranded bucketHint to the propose-call test fixtures.
…ift test removal (A-1386)

Deleting the inbox-drift bot test left the suite's cheatCodes variable (and
its import) unused, tripping lint.
…A-1386)

The legacy L1 inbox cleanup removes checkpointNumber from the MessageSent event, changing its topic
again; keep the hardcoded example ABIs in lockstep.
…x docs (A-1386)

The legacy-inbox cleanup removed IInbox.consume(), getRoot(), getInProgress() and
InboxState.inProgress, but inbox.md still documented them — the #include_code for
consume broke the docs build (identifier not found) once the lint gate stopped
masking it. Drop the stale view-function rows, the internal consume() section, and
the in-progress mention in getState; the surviving send_l1_to_l2_message include
still resolves.
…ecked (A-1386)

The end boundary is now compared against the record written at propose, not only
pinned transitively through the stored header hashes.
…vers (A-1386)

The legacy send-and-consume fuzz went away with the frontier trees, leaving the bucket suite fully
deterministic apart from the single-message field fuzz. This adds randomized send-path coverage:
message batches spread over several L1 blocks, with one batch per run exceeding the per-bucket cap so
rollover is always exercised. Each run re-derives the whole ring from the returned message leaves and
the per-block batch sizes, asserting the rolling-hash chain, the cumulative totals, the per-bucket
cap, and that bucket boundaries track L1 blocks. Consume-side interleaving and ring wraparound stay
out of scope.
…-1386)

The cap moved to file scope in Inbox.sol so the propose-side settled-bucket check can
share one definition with the Inbox; the fuzz harness still read it through the
removed contract getter.
@spalladino

Copy link
Copy Markdown
Contributor Author

Superseded by #25038.

The Fast Inbox stack has been regrouped from 20 per-issue PRs (plus 2 umbrellas) down to 3 area PRs plus an umbrella, and rebased onto merge-train/spartan including #25007 (the noir-projects fnd//labs/ split). This PR's diff is preserved verbatim as a single squashed commit in #25038, and this description is preserved in that commit's message.

New structure: #25036 (circuits + L1) → #25037 (node + flip) → #25038 (cleanup), with #25039 as the full-stack umbrella. The original branch for this PR is left on the remote as a recovery point.

Closing here to cut the rebase and review overhead of maintaining 22 PRs; the work is not abandoned.

@spalladino spalladino closed this Jul 28, 2026
spalladino added a commit that referenced this pull request Jul 28, 2026
Deletes the legacy L1 Inbox path now that `propose` enforces streaming-inbox consumption (AZIP-22 Fast Inbox, FI-16). Stacked on `spl/a-1385-streaming-e2e`; part of the Fast Inbox stack (#24784..#24790 below this one).

## What is deleted

- **Frontier trees**: the `trees` mapping, `forest`, `HEIGHT`/`SIZE`/`EMPTY_ROOT`, the per-message tree insert, `getRoot()`, and the whole `consume()` flow.
- **LAG / inboxLag**: the `LAG` immutable and `_lag`/`_height` constructor args (the Inbox constructor is now `(rollup, feeAsset, version, bucketRingSize)`), `RollupConfigInput.inboxLag` and its `RollupCore` pass-through, and `Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT` from the Inbox construction.
- **Dead event field**: the `MessageSent.checkpointNumber` (former `inProgress`) argument, which became meaningless once `consume()` stopped advancing it.
- **Orphaned errors**: `Inbox__Unauthorized`, `Inbox__MustBuildBeforeConsume`, `Rollup__InvalidInHash`.

## What is re-homed / kept

- The compact message index now reads the current bucket's running total (`totalMsgCount`) instead of a parallel counter; `InboxState.inProgress` and `getInProgress()` are gone.
- The 128-bit `rollingHash`, `InboxState.{rollingHash, totalMessagesInserted}`, `getState()`, and `getTotalMessagesInserted()` are **kept**: the node still consumes them for message sync and L1-reorg detection. Their removal is the node cleanup's job (FI-18).
- `FrontierLib` is **kept** — it still backs the base-parity (`test/Parity.t.sol`) and merkle (`test/merkle/Frontier.t.sol`) tests, which are unrelated to the Inbox (parity-circuit territory, FI-17). The plan's "delete the file" assumption is contradicted by grep.

## TS follow-through

- `ethereum` InboxContract: drop `getLag()`, drop the `MessageSent.checkpointNumber` decode, stop reading `inProgress`; `InboxContractState.treeInProgress` is now optional (no longer tracked on-chain).
- Stop threading `inboxLag` through `queries.getL1ContractsConfig` and the L1 deploy env. The broader `AZTEC_INBOX_LAG` config sweep (`ethereum/src/config.ts`, `foundation`, `stdlib`, ~30 e2e configs) is deferred to FI-18, which explicitly owns it.
- Archiver decode derives the message's checkpoint number from the compact index (the event no longer carries it), keeping the legacy per-checkpoint store shape untouched for FI-18.
- Removed the obsolete `advanceInboxInProgress` cheat code + its inbox-drift tests, and the orphaned archiver `inHash`-mismatch sync test (the cross-check was removed at the flip).

## Gas

Deleting the frontier insert is a large `sendL2Message` win. Whole-test gas (`forge test` on `InboxBuckets.t.sol`), before → after:

| Case | Before | After |
| --- | --- | --- |
| First-ever message | 175,251 | 116,835 |
| First message of a new L1 block | 329,460 | 195,555 |
| Absorb into an existing bucket | 286,673 | 149,968 |
| Rollover mid-block (256 messages) | 18,923,988 | 3,068,480 |

Per-call `sendL2Message` gas after cleanup: first-ever 99,526; first-of-new-block 53,763; existing-bucket absorb 9,273; rollover 53,801.

## Testing

- `forge build` + `forge test` green: 887 passed, 0 failed. This fixes 4 pre-existing baseline failures the flip stranded (`fee_portal`/`TokenPortal` deposit tests using tree-relative indices + the old event shape).
- `@aztec/ethereum` builds clean; `config`/`queries` unit tests green.
- `@aztec/archiver` has no self-owned type errors; `message_store` (36), `archiver-sync` (59), and the decode/struct suites (58) all pass. (Pre-existing `noir-protocol-circuits-types` stale-artifact errors are unaffected.)
- e2e not run locally. The stability gate ("a few days of green e2e/networks before deleting the fallback") applies at merge time for this stacked line, not at PR creation.


## Review follow-up (phase-2 final review)

Deleting the inbox-drift bot test left `bot.test.ts`'s `cheatCodes` variable unused (lint error); a follow-up commit removes it.

## Leftover sweep (post-review)

- Corrected the `PublicInputArgs` natspec in `IRollup.sol`: it still described `previousInboxRollingHash` / `endInboxRollingHash` as deliberately unvalidated "until the Fast Inbox flip", but the flip (#24789, below this branch) added exactly that validation — `EpochProofLib` anchors the start boundary against the propose-time record, and the end boundary is covered transitively by the stored checkpoint header hashes. The comment now describes the implemented behavior.
- The 128-bit rolling hash this PR deliberately kept (see "What is re-homed / kept") is now removed at the node-cleanup PR #24793, where its last TS readers disappear.



Replaces #24791.
spalladino added a commit that referenced this pull request Jul 28, 2026
…387)

FI-17 of the Fast Inbox (AZIP-22) stack. Stacked on #24791 (A-1386); it removes the legacy `inHash` from the checkpoint header now that the consensus flip (#24789, A-1384) has switched validation to the streaming rolling hash. After this PR, `inboxRollingHash` is the checkpoint's only inbox commitment.

## Consensus-format change

- The checkpoint header loses its `inHash` field across all three preimage layers in lockstep: noir `CheckpointHeader` (`checkpoint_header.nr`), TS `CheckpointHeader` (`stdlib/src/rollup/checkpoint_header.ts`), and Solidity `ProposedHeaderLib` (struct + hash packing). The field ordering is otherwise unchanged; the header shrinks by one field (32 bytes: `CHECKPOINT_HEADER_SIZE_IN_BYTES` 380 to 348, `CHECKPOINT_HEADER_LENGTH` 14 to 13).
- The header-hash fixtures were regenerated from `checkpoint_header.test.ts` (the established workflow) and pasted into the noir tests; the p2p golden-byte fixture (`wire_compat_fixtures.ts`) was refreshed for the checkpoint-proposal serialization, which shrinks by exactly the one removed field. The block-proposal wire fixture is unchanged (block-level `inHash` is out of scope, see A-1388).

## Circuits and constants

- Strips the dead unconstrained `in_hash` pass-through from the sized `InboxParity<S>` circuit and `ParityPublicInputs` (noir + TS + the hand-written `noir-protocol-circuits-types` conversion wrappers). The circuit is kept (sized-parity, per FI-06's topology decision), so no VK-tree indices move.
- Retires `NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP` (replaced everywhere by `MAX_L1_TO_L2_MSGS_PER_CHECKPOINT`, same value 1024) and the now-dead `NUM_MSGS_PER_BASE_PARITY`, `NUM_BASE_PARITY_PER_ROOT_PARITY`, and `L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH`. Generated constants (`constants.gen.ts`, `ConstantsGen.sol`) were regenerated via `remake-constants`.
- Deletes `FrontierLib.sol` and its tests (`Parity.t.sol`, the `Frontier` harness and merkle test) now that their last users are gone.

## Verification

- Noir: `types::checkpoint_header` (5/5), `rollup_lib::parity` and `checkpoint_root::parity_tests` (15/15), and the checkpoint-root header-assembly path pass locally. The full `checkpoint_root` suite (68 tests) is too slow to run in full locally and rides CI.
- Solidity: `forge test` green across `Rollup`, `RollupFieldRange`, `Inbox`, `InboxBuckets`, `RollupGetters` (76/76), covering header hashing and the regenerated checkpoint fixtures.
- Jest: `checkpoint_header`, the p2p wire-compat suites, and the parity/messaging suites pass (43 tests), confirming the fixture regeneration is byte-consistent.
- VK/artifact/Prover.toml regeneration and the generated Noir ABI types ride CI (local `yarn build` in `noir-protocol-circuits-types` / `simulator` / `prover-client` is expected to fail on stale circuit artifacts until then); e2e and the broken-zone typecheck are the CI-of-record for those.

## Stack

Part of the Fast Inbox stack #24784 through #24791 (umbrella #24774): A-1379 (#24784), A-1380 (#24785), A-1381 (#24786), A-1382 (#24787), A-1383 (#24788), A-1384 flip (#24789), A-1385 (#24790), A-1386 (#24791, base of this PR).

Resolves A-1387.


## l1 publisher inbox consumption via the streaming selector (CI fix, pass-8)

The A-1387 inHash-removal rewrite left `l1_publisher.integration.test.ts` hardcoding `previousInboxRollingHash = Fr.ZERO` and `bucketHint = 0n` while consuming real L1→L2 messages, so message-consuming checkpoints reverted on L1 with `Rollup__InvalidInboxRollingHash` / `UnconsumedInboxMessages` (masked every prior CI round behind earlier failures). `INBOX_LAG_SECONDS` is an L1-time censorship cutoff, not whole checkpoints, so no checkpoint-depth shift register reproduces the aged bucket set. The test now mirrors the real Inbox buckets into its `MockL1ToL2MessageSource` and reuses the production `selectInboxBucketForBlock` (which mirrors `ProposeLib.validateInboxConsumption`) to pick exactly the buckets each checkpoint must consume, deriving the consumed bundle, the propose bucket hint, and the header rolling hash from that one selection. Box: 13/13, verified at a-1387 and a-1388.


Replaces #24792.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant