Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0c7dcdb
feat: message-bundle components in rollup-lib (A-1372)
spalladino Jul 7, 2026
63f9df0
refactor: batched level-merge for append_leaves_to_snapshot
spalladino Jul 7, 2026
f961ad2
docs(fast-inbox): state that a full l1-to-l2 tree halts the chain (A-…
spalladino Jul 27, 2026
9a4faed
fix(fast-inbox): harden the leaf-index guards in append_leaves_to_sna…
spalladino Jul 27, 2026
3923fc4
test(fast-inbox): constrain the frontier-hint and capacity edge cases…
spalladino Jul 27, 2026
b8c073b
feat: introduce inboxRollingHash end to end, dual with inHash (A-1373)
spalladino Jul 7, 2026
53d6c00
feat: expose inbox rolling hash on root rollup public inputs (A-1373)
spalladino Jul 7, 2026
f9bbf43
chore: regenerate rollup sample inputs for inbox rolling hash ABI (A-…
spalladino Jul 8, 2026
5bf6ee9
chore: regenerate checkpoint-root sample inputs for inbox rolling has…
spalladino Jul 13, 2026
41d92e5
chore: drop stale pinned build (A-1373)
spalladino Jul 13, 2026
c13ba1e
fix: verify checkpoint headers in getEpochProofPublicInputs (A-1373)
spalladino Jul 17, 2026
a0e7d0a
test(fast-inbox): regenerate pxe L2 tips snapshot for inboxRollingHas…
spalladino Jul 19, 2026
c49779c
test(fast-inbox): stub parent-checkpoint sourcing for the inbox rolli…
spalladino Jul 19, 2026
52748c6
fix(fast-inbox): dedupe checkpoint header verification on epoch proof…
spalladino Jul 27, 2026
9a9c5f3
fix(fast-inbox): thread the previous inbox rolling hash into the reru…
spalladino Jul 28, 2026
fd4eda7
fix(fast-inbox): schedule proving jobs oldest-epoch-first across proo…
spalladino Jul 19, 2026
aaec2d5
feat: per-block L1-to-L2 message bundles, move parity to checkpoint r…
spalladino Jul 7, 2026
cee6523
chore: drop unused imports and fix test-input types after per-block b…
spalladino Jul 7, 2026
7419645
test: assert sub-tree surfaces the checkpoint parity root proof (A-1374)
spalladino Jul 8, 2026
3351f07
docs: correct block-merge propagation comment (A-1374)
spalladino Jul 8, 2026
4e26de5
fix: enqueue block root for empty first blocks after parity moved to …
spalladino Jul 13, 2026
98e0f0f
chore: regenerate rollup sample inputs for per-block message bundle A…
spalladino Jul 13, 2026
18addde
chore(fast-inbox): regenerate block-root sample inputs for message_bu…
spalladino Jul 17, 2026
dadb7a7
chore(fast-inbox): regenerate block-root sample inputs at the per-blo…
spalladino Jul 19, 2026
aa03b00
chore: bump playground main-entrypoint chunk-size limit to 1960 KB
spalladino Jul 17, 2026
a322758
chore(fast-inbox): mark multi_proof as a flake under CI's 2-CPU limit…
spalladino Jul 20, 2026
02be796
chore(fast-inbox): skip multi_proof on the transitional intermediate …
spalladino Jul 20, 2026
626d8e5
fix(fast-inbox): require the message-bundle append before finishing a…
spalladino Jul 28, 2026
f515cb2
test(fast-inbox): cover block-root message appends at a non-zero tree…
spalladino Jul 28, 2026
db26f5d
feat: add block_root_msgs_only_rollup circuit for no-tx blocks with m…
spalladino Jul 8, 2026
e53f794
fix: complete proving-broker and bb-prover wiring for msgs-only block…
spalladino Jul 8, 2026
7fcb4af
docs: warn that the msgs-only single-block allowlist entry rests on i…
spalladino Jul 13, 2026
182ecbd
fix(fast-inbox): include the message-only block-root proof in the Pro…
spalladino Jul 21, 2026
b3f77b1
fix(fast-inbox): bump the proving broker database schema version (A-1…
spalladino Jul 27, 2026
dcfc8e3
feat: single variable-size InboxParity proof per checkpoint (A-1427)
spalladino Jul 17, 2026
40245b0
fix: drop unused NESTED_RECURSIVE_PROOF_LENGTH imports orphaned by th…
spalladino Jul 17, 2026
fe87c0c
fix: map L1ToL2MessageBundle messages to a fixed-length Noir array
spalladino Jul 17, 2026
7104e09
fix: use top-level import type in checkpoint-proving-state
spalladino Jul 17, 2026
adaf3a2
fix: feed a valid sha-truncated inHash in bb_prover_parity test
spalladino Jul 17, 2026
5831c6b
chore(fast-inbox): regenerate checkpoint-root sample inputs for inbox…
spalladino Jul 17, 2026
7a8a603
chore(fast-inbox): regenerate block-root sample inputs for the messag…
spalladino Jul 19, 2026
2b08840
refactor(fast-inbox): name the checkpoint sub-tree proof bundle for w…
spalladino Jul 27, 2026
fa7a627
test(fast-inbox): follow the InboxParity request type through the bro…
spalladino Jul 28, 2026
e5efd1d
fix(fast-inbox): annotate the rerun checkpoint job return type (A-1427)
spalladino Jul 28, 2026
fb142eb
feat(fast-inbox): same-block L1-to-L2 message consumption for non-fir…
spalladino Jul 17, 2026
3042611
docs(fast-inbox): mirror the same-block l1ToL2TreeSnapshot semantics …
spalladino Jul 18, 2026
d73a969
fix(fast-inbox): dispatch block-root proving on the rollupType discri…
spalladino Jul 19, 2026
eb38c30
chore(fast-inbox): regenerate block-root sample inputs for same-block…
spalladino Jul 19, 2026
37ee1a7
docs(fast-inbox): state circuits and stdlib inbox comments on their o…
spalladino Jul 27, 2026
51cb753
feat: rolling-hash buckets in the Inbox alongside frontier trees
spalladino Jul 17, 2026
e76b842
test(fast-inbox): gas measurements for Inbox.sendL2Message and timest…
spalladino Jul 17, 2026
c0ee535
test(fast-inbox): clarify gas-measurement and bucket-timestamp commen…
spalladino Jul 17, 2026
f25a2bd
feat(fast-inbox): enforce a minimum Inbox bucket-ring size of 512 (A-…
spalladino Jul 18, 2026
f65c86f
chore(fast-inbox): clarify Inbox ring-floor rationale comment (A-1377)
spalladino Jul 18, 2026
95a022b
chore(fast-inbox): fix solhint function ordering in Inbox (A-1377)
spalladino Jul 19, 2026
50a0f07
docs(fast-inbox): follow the MessageSent event through the example In…
spalladino Jul 19, 2026
3a2047d
feat: streaming inbox propose validation, unwired
spalladino Jul 17, 2026
decfb91
test(fast-inbox): use the real 512 ring floor in the overwritten-hint…
spalladino Jul 18, 2026
a6444aa
test(fast-inbox): drop the backwards proposal-time warp in the overwr…
spalladino Jul 18, 2026
83a77c2
chore(fast-inbox): fix solhint import order in ProposeLib (A-1378)
spalladino Jul 19, 2026
91e0559
chore(fast-inbox): re-enable multi_proof from this point in the stack…
spalladino Jul 20, 2026
f1080bf
docs(fast-inbox): describe the inbox rolling-hash mechanism without a…
spalladino Jul 27, 2026
e5284d7
fix(fast-inbox): reject propose against a still-mutable inbox bucket …
spalladino Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/examples/ts/aave_bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ const INBOX_ABI = [
{ name: "index", type: "uint256", indexed: false },
{ name: "hash", type: "bytes32", indexed: true },
{ name: "rollingHash", type: "bytes16", indexed: false },
{ name: "inboxRollingHash", type: "bytes32", indexed: false },
{ name: "bucketSeq", type: "uint256", indexed: false },
],
},
] as const;
Expand Down
2 changes: 2 additions & 0 deletions docs/examples/ts/example_swap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ const INBOX_ABI = [
{ name: "index", type: "uint256", indexed: false },
{ name: "hash", type: "bytes32", indexed: true },
{ name: "rollingHash", type: "bytes16", indexed: false },
{ name: "inboxRollingHash", type: "bytes32", indexed: false },
{ name: "bucketSeq", type: "uint256", indexed: false },
],
},
] as const;
Expand Down
2 changes: 2 additions & 0 deletions docs/examples/ts/token_bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ const INBOX_ABI = [
{ name: "index", type: "uint256", indexed: false },
{ name: "hash", type: "bytes32", indexed: true },
{ name: "rollingHash", type: "bytes16", indexed: false },
{ name: "inboxRollingHash", type: "bytes32", indexed: false },
{ name: "bucketSeq", type: "uint256", indexed: false },
],
},
] as const;
Expand Down
11 changes: 9 additions & 2 deletions l1-contracts/src/core/RollupCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {ProposeArgs} from "@aztec/core/libraries/rollup/ProposeLib.sol";
import {STFLib, GenesisState} from "@aztec/core/libraries/rollup/STFLib.sol";
import {StakingLib} from "@aztec/core/libraries/rollup/StakingLib.sol";
import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol";
import {Inbox} from "@aztec/core/messagebridge/Inbox.sol";
import {Inbox, INBOX_BUCKET_RING_SIZE} from "@aztec/core/messagebridge/Inbox.sol";
import {Outbox} from "@aztec/core/messagebridge/Outbox.sol";
import {ISlasher} from "@aztec/core/slashing/Slasher.sol";
import {GSE} from "@aztec/governance/GSE.sol";
Expand Down Expand Up @@ -621,7 +621,14 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali

IInbox inbox = IInbox(
address(
new Inbox(address(this), _feeAsset, _config.version, Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT, _config.inboxLag)
new Inbox(
address(this),
_feeAsset,
_config.version,
Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT,
_config.inboxLag,
INBOX_BUCKET_RING_SIZE
)
)
);

Expand Down
5 changes: 5 additions & 0 deletions l1-contracts/src/core/interfaces/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ struct PublicInputArgs {
bytes32 previousArchive;
bytes32 endArchive;
bytes32 outHash;
// Inbox rolling-hash chain segment consumed across the proven epoch (AZIP-22 Fast Inbox). Deliberately UNVALIDATED
// until the Fast Inbox flip, when they get checked against per-checkpoint records written at propose; for now they
// are only passed through to the proof's public inputs.
bytes32 previousInboxRollingHash;
bytes32 endInboxRollingHash;
address proverId;
}

Expand Down
52 changes: 51 additions & 1 deletion l1-contracts/src/core/interfaces/messagebridge/IInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ pragma solidity >=0.8.27;

import {DataStructures} from "../../libraries/DataStructures.sol";

// Maximum number of messages a single bucket can hold before further messages in the same L1 block spill over
// into the next bucket. Matches the number of L1 to L2 messages a single L2 block can insert once the streaming
// inbox is live, so any one bucket is always consumable by one block.
uint256 constant MAX_MSGS_PER_BUCKET = 256;

/**
* @title Inbox
* @author Aztec Labs
Expand All @@ -13,6 +18,8 @@ interface IInbox {
struct InboxState {
// Rolling hash of all messages inserted into the inbox.
// Used by clients to check for consistency.
// TODO: remove once the streaming inbox (AZIP-22 Fast Inbox) flips on and clients rely on the
// consensus rolling hash tracked in the buckets instead.
bytes16 rollingHash;
// This value is not used much by the contract, but it is useful for synching the node faster
// as it can more easily figure out if it can just skip looking for events for a time period.
Expand All @@ -21,14 +28,43 @@ interface IInbox {
uint64 inProgress;
}

/**
* @notice Snapshot of the consensus rolling hash over the messages inserted into the Inbox, stored in a
* fixed-size ring indexed by a dense bucket sequence number (`seq % ringSize`). A bucket only accumulates
* messages sent within a single L1 block, so its final state is the chain position as of the end of that
* block; the censorship check at `propose` compares the checkpoint header's rolling hash against these
* snapshots.
*/
struct InboxBucket {
// Rolling hash after the last message absorbed into this bucket. Each link is
// `sha256ToField(previousRollingHash || leaf)`; the genesis value is zero.
bytes32 rollingHash;
// Cumulative number of messages inserted into the Inbox up to and including this bucket.
uint64 totalMsgCount;
// L1 block timestamp at which this bucket was opened. Recency comparisons (message lag,
// censorship cutoff) are done in seconds against this value.
uint64 timestamp;
// Number of messages absorbed into this bucket, capped at the per-bucket maximum.
uint32 msgCount;
}

/**
* @notice Emitted when a message is sent
* @param checkpointNumber - The checkpoint number in which the message is included
* @param index - The index of the message in the L1 to L2 messages tree
* @param hash - The hash of the message
* @param rollingHash - The rolling hash of all messages inserted into the inbox
* @param inboxRollingHash - The consensus rolling hash (truncated sha256 chain) after this message
* @param bucketSeq - The sequence number of the bucket this message was absorbed into
*/
event MessageSent(uint256 indexed checkpointNumber, uint256 index, bytes32 indexed hash, bytes16 rollingHash);
event MessageSent(
uint256 indexed checkpointNumber,
uint256 index,
bytes32 indexed hash,
bytes16 rollingHash,
bytes32 inboxRollingHash,
uint256 bucketSeq
);

// docs:start:send_l1_to_l2_message
/**
Expand Down Expand Up @@ -68,4 +104,18 @@ interface IInbox {
function getTotalMessagesInserted() external view returns (uint64);

function getInProgress() external view returns (uint64);

/**
* @notice Returns the sequence number of the bucket currently accumulating messages
* @return The current bucket sequence number
*/
function getCurrentBucketSeq() external view returns (uint64);

/**
* @notice Returns the bucket with the given sequence number
* @dev Reverts if the bucket is ahead of the current one or has already been overwritten in the ring
* @param _seq - The bucket sequence number
* @return The bucket
*/
function getBucket(uint256 _seq) external view returns (InboxBucket memory);
}
6 changes: 6 additions & 0 deletions l1-contracts/src/core/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ library Errors {
error Inbox__ContentTooLarge(bytes32 content); // 0x47452014
error Inbox__SecretHashTooLarge(bytes32 secretHash); // 0xecde7e2c
error Inbox__MustBuildBeforeConsume(); // 0xc4901999
error Inbox__BucketOutOfWindow(uint256 seq, uint256 current); // 0xfee255b7

// Outbox
error Outbox__Unauthorized(); // 0x2c9490c2
Expand Down Expand Up @@ -58,6 +59,11 @@ library Errors {
error Rollup__InvalidCheckpointHeaderCount(uint256 expected, uint256 actual);
error Rollup__InvalidCheckpointNumber(uint256 expected, uint256 actual); // 0xd1ba9bfa
error Rollup__InvalidInHash(bytes32 expected, bytes32 actual); // 0xcd6f4233
error Rollup__InvalidInboxRollingHash(bytes32 expected, bytes32 actual); // 0xed1f7bb5
error Rollup__InboxBucketStillMutable(uint256 bucketSeq); // 0x7254b980
error Rollup__UnconsumedInboxMessages(uint256 nextBucketSeq); // 0x2bd4bf10
error Rollup__InboxConsumptionBehindParent(uint256 expected, uint256 actual); // 0x54e0c025
error Rollup__TooManyInboxMessagesConsumed(uint256 consumed); // 0xf76d1426
error Rollup__InvalidOutHash(bytes32 expected, bytes32 actual); // 0x8eb39062
error Rollup__InvalidPreviousArchive(bytes32 expected, bytes32 actual); // 0xb682a40e
error Rollup__InvalidProof(); // 0xa5b2ba17
Expand Down
12 changes: 12 additions & 0 deletions l1-contracts/src/core/libraries/crypto/Hash.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,16 @@ library Hash {
function sha256ToField(bytes memory _data) internal pure returns (bytes32) {
return bytes32(bytes.concat(new bytes(1), bytes31(sha256(_data))));
}

/**
* @notice Advances the Inbox consensus rolling hash by one message leaf
* @dev Truncated at every link so the value is always a field element; the rollup circuits recompute the
* identical chain over the message leaves they insert. The genesis value is zero.
* @param _rollingHash - The current rolling hash
* @param _leaf - The message leaf to absorb
* @return The updated rolling hash
*/
function accumulateInboxRollingHash(bytes32 _rollingHash, bytes32 _leaf) internal pure returns (bytes32) {
return sha256ToField(abi.encodePacked(_rollingHash, _leaf));
}
}
Loading
Loading