Skip to content

Commit d425189

Browse files
committed
chore(fast-inbox): emit inbox lag and checkpoint cap from the constants generator (A-1434)
Add INBOX_LAG_SECONDS and MAX_L1_TO_L2_MSGS_PER_CHECKPOINT to the Solidity constants allowlist so the generator emits them into ConstantsGen.sol, matching the values already present in constants.gen.ts. ProposeLib and its consumption test now read the generated Constants library instead of the hand-declared file-scope copies, giving L1 and TS a single source of truth.
1 parent 834ca00 commit d425189

4 files changed

Lines changed: 19 additions & 23 deletions

File tree

l1-contracts/src/core/libraries/ConstantsGen.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ library Constants {
1616
uint256 internal constant MAX_FIELD_VALUE =
1717
21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_616;
1818
uint256 internal constant L1_TO_L2_MSG_SUBTREE_HEIGHT = 10;
19+
uint256 internal constant MAX_L1_TO_L2_MSGS_PER_CHECKPOINT = 1024;
20+
uint256 internal constant INBOX_LAG_SECONDS = 12;
1921
uint256 internal constant MAX_L2_TO_L1_MSGS_PER_TX = 8;
2022
uint256 internal constant INITIAL_CHECKPOINT_NUMBER = 1;
2123
uint256 internal constant MAX_CHECKPOINTS_PER_EPOCH = 32;

l1-contracts/src/core/libraries/rollup/ProposeLib.sol

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pragma solidity >=0.8.27;
44

55
import {BlobLib} from "@aztec-blob-lib/BlobLib.sol";
6+
import {Constants} from "@aztec/core/libraries/ConstantsGen.sol";
67
import {IEscapeHatch} from "@aztec/core/interfaces/IEscapeHatch.sol";
78
import {RollupStore, IRollupCore, CheckpointHeaderValidationFlags} from "@aztec/core/interfaces/IRollup.sol";
89
import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol";
@@ -22,14 +23,6 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol";
2223
import {ProposedHeader, ProposedHeaderLib} from "./ProposedHeaderLib.sol";
2324
import {STFLib} from "./STFLib.sol";
2425

25-
// Streaming-inbox protocol constants (AZIP-22 Fast Inbox). These mirror the protocol circuit constants and
26-
// should move into the generated Constants library once the Solidity emitter includes them.
27-
// Minimum bucket age, in seconds, at the start of a checkpoint's build frame for its consumption to be
28-
// mandatory. One L1 slot: validators cannot be required to act on buckets they may not have seen.
29-
uint256 constant INBOX_LAG_SECONDS = 12;
30-
// Maximum number of L1 to L2 messages a single checkpoint can insert.
31-
uint256 constant MAX_L1_TO_L2_MSGS_PER_CHECKPOINT = 1024;
32-
3326
struct ProposeArgs {
3427
bytes32 archive;
3528
OracleInput oracleInput;
@@ -453,17 +446,17 @@ library ProposeLib {
453446
);
454447

455448
require(
456-
bucket.totalMsgCount - _parentTotalMsgCount <= MAX_L1_TO_L2_MSGS_PER_CHECKPOINT,
449+
bucket.totalMsgCount - _parentTotalMsgCount <= Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT,
457450
Errors.Rollup__TooManyInboxMessagesConsumed(bucket.totalMsgCount - _parentTotalMsgCount)
458451
);
459452

460453
if (_bucketHint < _inbox.getCurrentBucketSeq()) {
461454
IInbox.InboxBucket memory next = _inbox.getBucket(_bucketHint + 1);
462455
Timestamp buildFrameStart = TimeLib.toTimestamp(_slotNumber - Slot.wrap(1));
463-
Timestamp cutoff = buildFrameStart - Timestamp.wrap(INBOX_LAG_SECONDS);
456+
Timestamp cutoff = buildFrameStart - Timestamp.wrap(Constants.INBOX_LAG_SECONDS);
464457
require(
465458
next.timestamp > Timestamp.unwrap(cutoff)
466-
|| next.totalMsgCount - _parentTotalMsgCount > MAX_L1_TO_L2_MSGS_PER_CHECKPOINT,
459+
|| next.totalMsgCount - _parentTotalMsgCount > Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT,
467460
Errors.Rollup__UnconsumedInboxMessages(_bucketHint + 1)
468461
);
469462
}

l1-contracts/test/rollup/ProposeInboxConsumption.t.sol

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ import {Test} from "forge-std/Test.sol";
66
import {TestERC20} from "src/mock/TestERC20.sol";
77
import {IERC20} from "@oz/token/ERC20/IERC20.sol";
88
import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol";
9-
import {
10-
ProposeLib,
11-
INBOX_LAG_SECONDS,
12-
MAX_L1_TO_L2_MSGS_PER_CHECKPOINT
13-
} from "@aztec/core/libraries/rollup/ProposeLib.sol";
9+
import {ProposeLib} from "@aztec/core/libraries/rollup/ProposeLib.sol";
10+
import {Constants} from "@aztec/core/libraries/ConstantsGen.sol";
1411
import {TimeLib, Slot, Timestamp} from "@aztec/core/libraries/TimeLib.sol";
1512
import {Errors} from "@aztec/core/libraries/Errors.sol";
1613
import {DataStructures} from "@aztec/core/libraries/DataStructures.sol";
@@ -50,7 +47,7 @@ contract ProposeInboxConsumptionTest is Test {
5047
// Start of the build frame for a checkpoint proposed in SLOT: it is built during the previous slot.
5148
uint256 internal buildFrameStart = GENESIS_TIME + (Slot.unwrap(SLOT) - 1) * SLOT_DURATION;
5249
// Buckets at or before the cutoff must be consumed by the checkpoint.
53-
uint256 internal cutoff = buildFrameStart - INBOX_LAG_SECONDS;
50+
uint256 internal cutoff = buildFrameStart - Constants.INBOX_LAG_SECONDS;
5451

5552
function setUp() public {
5653
vm.warp(GENESIS_TIME);
@@ -123,7 +120,7 @@ contract ProposeInboxConsumptionTest is Test {
123120
// One more message than the checkpoint cap, all before the cutoff. They spill over into buckets
124121
// 1..4 of 256 (the per-bucket cap) plus bucket 5 with the single excess message.
125122
vm.warp(cutoff - 100);
126-
_sendMany(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
123+
_sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
127124
assertEq(inbox.getCurrentBucketSeq(), 5, "expected five buckets");
128125

129126
vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION);
@@ -132,12 +129,12 @@ contract ProposeInboxConsumptionTest is Test {
132129
// even though it is old.
133130
bytes32 endHash = inbox.getBucket(4).rollingHash;
134131
uint256 consumed = rollup.validateInboxConsumption(inbox, endHash, 4, SLOT, 0);
135-
assertEq(consumed, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, "consumed the full cap");
132+
assertEq(consumed, Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, "consumed the full cap");
136133
}
137134

138135
function testNoCapEscapeAtExactCap() public {
139136
vm.warp(cutoff - 100);
140-
_sendMany(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
137+
_sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
141138

142139
vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION);
143140

@@ -152,7 +149,7 @@ contract ProposeInboxConsumptionTest is Test {
152149
// Same layout as testCapEscape, but the parent checkpoint had already consumed one message:
153150
// buckets 2..5 then hold cap messages total, which fit in one checkpoint, so no escape from bucket 1.
154151
vm.warp(cutoff - 100);
155-
_sendMany(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
152+
_sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
156153

157154
vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION);
158155

@@ -254,14 +251,16 @@ contract ProposeInboxConsumptionTest is Test {
254251
// One more message than the checkpoint cap, all before the cutoff, referenced in a single proposal from
255252
// a fresh parent: the consumed delta exceeds what the circuits can insert.
256253
vm.warp(cutoff - 100);
257-
_sendMany(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
254+
_sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1);
258255
assertEq(inbox.getCurrentBucketSeq(), 5, "expected five buckets");
259256

260257
bytes32 endHash = inbox.getBucket(5).rollingHash;
261258

262259
vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION);
263260
vm.expectRevert(
264-
abi.encodeWithSelector(Errors.Rollup__TooManyInboxMessagesConsumed.selector, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1)
261+
abi.encodeWithSelector(
262+
Errors.Rollup__TooManyInboxMessagesConsumed.selector, Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1
263+
)
265264
);
266265
rollup.validateInboxConsumption(inbox, endHash, 5, SLOT, 0);
267266
}

yarn-project/constants/src/scripts/constants.in.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ const SOLIDITY_CONSTANTS = [
352352
'MAX_L2_TO_L1_MSGS_PER_TX',
353353
'EMPTY_EPOCH_OUT_HASH',
354354
'L1_TO_L2_MSG_SUBTREE_HEIGHT',
355+
'MAX_L1_TO_L2_MSGS_PER_CHECKPOINT',
356+
'INBOX_LAG_SECONDS',
355357
'BLS12_POINT_COMPRESSED_BYTES',
356358
'ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH',
357359
'INITIAL_CHECKPOINT_NUMBER',

0 commit comments

Comments
 (0)