Skip to content

feat: streaming inbox propose validation, unwired (A-1378)#24618

Draft
AztecBot wants to merge 1 commit into
cb/a-1377-inbox-bucketsfrom
cb/a-1378-propose-validation
Draft

feat: streaming inbox propose validation, unwired (A-1378)#24618
AztecBot wants to merge 1 commit into
cb/a-1377-inbox-bucketsfrom
cb/a-1378-propose-validation

Conversation

@AztecBot

@AztecBot AztecBot commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #24617 (A-1377). AZIP-22 Fast Inbox, FI-08.

What

Implements the AZIP's censorship assert as ProposeLib.validateInboxConsumption — a new library function that is not yet called: today's inbox.consume() / inHash check in propose is untouched, so this is dead code until the flip wires it in.

Given the checkpoint header's inboxRollingHash, an unsigned calldata bucket hint, the proposed slot, and the parent checkpoint's cumulative consumed total (which the flip will source from the temp checkpoint log), the function enforces:

  1. End anchoring: the header's rolling hash must equal the snapshot in inbox.getBucket(hint) (Rollup__InvalidInboxRollingHash). The hint is a lookup aid only — a wrong hint reverts, it cannot change what gets accepted — and getBucket itself rejects hints beyond the current bucket or already overwritten in the ring. A checkpoint consuming nothing references the same bucket as its parent (the genesis bucket for the first checkpoint), so there is no base case.
  2. Mandatory consumption: the first unconsumed bucket (hint + 1) must be absent, past the cutoff, or cap-escaped (Rollup__UnconsumedInboxMessages). The cutoff is the build-frame start minus INBOX_LAG_SECONDS: a checkpoint proposed in slot S is built during slot S-1 (proposer pipelining), and validators are not required to act on buckets younger than one L1 slot at build start, so cutoff = toTimestamp(S-1) - 12. Cap escape allows stopping when consuming through the next bucket would exceed MAX_L1_TO_L2_MSGS_PER_CHECKPOINT (1024) messages since the parent's total. Both comparisons are exact-boundary tested.

On success the function advances the Inbox's new consumed-bucket pointer (markBucketConsumed, rollup-only): the monotonic cache of consumption position that the upcoming ring overwrite protection needs. It never rewinds — per the design, on prunes the per-checkpoint records in the rollup are the source of truth, and the pointer is only an insert-path locality cache, which also makes it safe under reorged re-proposals.

INBOX_LAG_SECONDS = 12 and MAX_L1_TO_L2_MSGS_PER_CHECKPOINT = 1024 are defined at file level in ProposeLib for now; they mirror the protocol constants and should move into the generated Constants library once the Solidity emitter allow-list includes them.

Testing

New ProposeInboxConsumption.t.sol (15 tests) drives the library function through a harness that owns the Inbox and TimeLib storage, covering the roadmap done-when plus boundaries:

  • empty Inbox (hint 0 / hash 0 passes; non-zero hash rejected),
  • exact-cutoff bucket (timestamp == cutoff must be consumed; cutoff + 1 need not),
  • cap escape (1025 messages spill into buckets of 256+1: stopping at bucket 4 = exactly 1024 escapes; stopping at bucket 3 = 1024-through-next does not; parent total shifts the arithmetic and kills the escape),
  • stale hash (previous bucket's hash against the current bucket) and unknown hash rejection, plus out-of-window hints (future bucket, ring-overwritten bucket),
  • consumed pointer: advances on success, monotonic (no rewind), rollup-only, rejects marking beyond the current bucket.

Full forge test suite: 893 passed, 0 failed (7 pre-existing skips).


Created by claudebox · group: slackbot

@AztecBot AztecBot added ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure claudebox Owned by claudebox. it can push to this PR. labels Jul 8, 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 draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure claudebox Owned by claudebox. it can push to this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant