Skip to content

Commit f7f96e0

Browse files
committed
test(fast-inbox): clarify gas-measurement and bucket-timestamp comments (A-1377)
1 parent 83861ab commit f7f96e0

2 files changed

Lines changed: 12 additions & 8 deletions

File tree

l1-contracts/src/core/messagebridge/Inbox.sol

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,11 @@ contract Inbox is IInbox {
179179
uint64 bucketSeq = currentBucketSeq;
180180
InboxBucket memory bucket = buckets[bucketSeq % BUCKET_RING_SIZE];
181181

182-
// Buckets are keyed by L1 block timestamp: a strictly larger timestamp opens a new bucket. Post-merge
183-
// Ethereum increases block.timestamp strictly per block, so one bucket corresponds to one L1 block. Under
184-
// anvil with manual mining two blocks can share a timestamp and therefore a bucket; this is harmless
185-
// because the consumption cutoff is computed over timestamps, so co-timestamped blocks are equivalent to it.
182+
// Buckets are keyed by L1 block timestamp: a strictly larger timestamp opens a new bucket (a full bucket
183+
// also rolls over within the same block). Post-merge Ethereum increases block.timestamp strictly per block,
184+
// so messages from different L1 blocks always land in different buckets. Under anvil with manual mining two
185+
// blocks can share a timestamp and therefore a bucket; this is harmless because the consumption cutoff is
186+
// computed over timestamps, so co-timestamped blocks are indistinguishable to it.
186187
if (bucketSeq == 0 || bucket.timestamp < block.timestamp || bucket.msgCount == MAX_MSGS_PER_BUCKET) {
187188
bucketSeq += 1;
188189
currentBucketSeq = bucketSeq;

l1-contracts/test/InboxBuckets.t.sol

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ contract InboxBucketsTest is Test {
4141
return leaf;
4242
}
4343

44-
// Sends a message and returns the gas consumed by the external `sendL2Message` call alone. The
45-
// recipient/content/secretHash are built before the measurement window so only the call is timed.
44+
// Sends a message and returns the gas consumed by the external `sendL2Message` call. The
45+
// recipient/content/secretHash are built before the measurement window so only the call is timed. The
46+
// figure is warm execution gas including the CALL overhead; it excludes the 21k intrinsic tx cost, calldata
47+
// gas, and the cold-access surcharge a standalone EOA transaction pays on its first touch of each slot.
4648
function _measureSend(InboxHarness _inbox, uint256 _salt) internal returns (uint256 gasUsed) {
4749
DataStructures.L2Actor memory recipient =
4850
DataStructures.L2Actor({actor: bytes32(uint256(0x1000 + _salt)), version: version});
@@ -269,8 +271,9 @@ contract InboxBucketsTest is Test {
269271
assertEq(inbox.getCurrentBucketSeq(), 2, "rollover opened bucket 2");
270272
}
271273

272-
// Gas cost of the first-ever message against a freshly deployed Inbox: every touched slot is cold,
273-
// including the state struct and bucket 1, so this is the worst-case single insert.
274+
// Gas cost of the first-ever message against a freshly deployed Inbox: the state struct, bucket 1, and the
275+
// first frontier-tree slots are all written cold. This is the cold-storage case, not the global worst-case
276+
// insert — later frontier indices with more levels to hash can cost more.
274277
function testGasSendFirstEverMessage() public {
275278
assertEq(inbox.getCurrentBucketSeq(), 0, "no message sent yet");
276279

0 commit comments

Comments
 (0)