Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 3 additions & 4 deletions barretenberg/.claude/skills/gate-counts/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ Regenerates `Prover.toml` for: `private-kernel-init` and its `private-kernel-ini
variants, `private-kernel-inner` and its `private-kernel-inner-N` variants,
`private-kernel-reset`, `private-kernel-reset-tail`,
`private-kernel-reset-tail-to-public`, `rollup-tx-base-private`,
`rollup-tx-base-public`, `rollup-block-root-first`,
`rollup-block-root-first-single-tx`, `rollup-checkpoint-root-single-block`,
`rollup-tx-base-public`, `rollup-block-root`,
`rollup-block-root-single-tx`, `rollup-checkpoint-root-single-block`,
`rollup-checkpoint-merge`, `rollup-root`.

**Rollup circuits NOT covered by `full.test`** (incl. `rollup-tx-merge`):
Expand All @@ -233,8 +233,7 @@ AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 \
yarn workspace @aztec/prover-client test src/orchestrator/orchestrator_single_checkpoint.test.ts
```

Regenerates `Prover.toml` for `rollup-tx-merge`, `rollup-block-root-first-empty-tx`,
`rollup-block-root` (single-tx checkpoint test) and `rollup-block-root-single-tx`,
Regenerates `Prover.toml` for `rollup-tx-merge`, `rollup-block-root-no-txs`,
`rollup-block-merge`, `rollup-checkpoint-root` (multi-block checkpoint test).

> **`rollup-tx-merge`'s `Prover.toml` is regenerated by the prover-client
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/.claude/skills/update-prover-toml/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ The circuit list lives in the `forEach(circuitName => ...)` loop in `full.test.t
- `private-kernel-inner`, `private-kernel-inner-2` … `private-kernel-inner-5`
- `private-kernel-reset-tail`, `private-kernel-reset-tail-to-public` (the terminal resets — these run as part of every tx's tail)
- `rollup-tx-base-private`, `rollup-tx-base-public`
- `rollup-block-root-first`, `rollup-block-root-first-single-tx`
- `rollup-block-root`, `rollup-block-root-single-tx`
- `rollup-checkpoint-root-single-block`, `rollup-checkpoint-merge`
- `rollup-root`

`private-kernel-reset` (the **inner** reset) is deliberately **commented out** of this list and is **not** generated by the test — see the exception below.

Other entries commented out (e.g. `rollup-tx-merge`, `rollup-block-root`, `rollup-block-merge`, `rollup-checkpoint-root`) are also not produced by this flow; the inline comment points to the orchestrator single-checkpoint test for those.
Other entries commented out (e.g. `rollup-tx-merge`, `rollup-block-root-no-txs`, `rollup-block-merge`, `rollup-checkpoint-root`) are also not produced by this flow; the inline comment points to the orchestrator single-checkpoint test for those.

If you add a new circuit crate, add its name to that list so its toml gets generated.

Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn workspace @aztec/end-to-end test e

`FAKE_PROOFS=1` skips real proving — runs in ~2 min (orchestrator + witness generation only). Writes 12 `Prover.toml` files under `noir-projects/fnd/noir-protocol-circuits/crates/<circuit>/Prover.toml`.

For circuits not exercised by `full.test.ts` (`rollup-tx-merge`, `rollup-block-root`, `rollup-block-root-single-tx`, `rollup-block-merge`, `rollup-checkpoint-root`, `rollup-block-root-first-empty-tx`), additionally run:
For circuits not exercised by `full.test.ts` (`rollup-tx-merge`, `rollup-block-root-no-txs`, `rollup-block-merge`, `rollup-checkpoint-root`), additionally run:

```bash
AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test orchestrator_single_checkpoint
Expand Down
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