Skip to content

Commit 691b279

Browse files
committed
chore(fast-inbox): fix solhint function ordering in Inbox (A-1377)
Move the internal _absorbIntoBucket helper below the external functions so solhint's ordering rule (external before internal) passes. Pure move, no behavior change.
1 parent c7258cc commit 691b279

1 file changed

Lines changed: 41 additions & 41 deletions

File tree

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

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -168,47 +168,6 @@ contract Inbox is IInbox {
168168
return (leaf, index);
169169
}
170170

171-
/**
172-
* @notice Absorbs a message leaf into the consensus rolling hash and snapshots it into the bucket ring
173-
*
174-
* @dev A bucket only holds messages from a single L1 block, up to MAX_MSGS_PER_BUCKET; the first message
175-
* of a new L1 block — or the message after a full bucket, spilling over within the same block — opens the
176-
* next bucket, inheriting the rolling hash and cumulative count. Bucket 0 is the pristine genesis base
177-
* case and never absorbs. Opening a bucket overwrites the ring entry from BUCKET_RING_SIZE buckets ago;
178-
* protection against overwriting unconsumed buckets is not enforced yet.
179-
*
180-
* @param _leaf - The message leaf to absorb
181-
*
182-
* @return The sequence number of the bucket the leaf was absorbed into and the updated rolling hash
183-
*/
184-
function _absorbIntoBucket(bytes32 _leaf) internal returns (uint64, bytes32) {
185-
uint64 bucketSeq = currentBucketSeq;
186-
InboxBucket memory bucket = buckets[bucketSeq % BUCKET_RING_SIZE];
187-
188-
// Buckets are keyed by L1 block timestamp: a strictly larger timestamp opens a new bucket (a full bucket
189-
// also rolls over within the same block). Post-merge Ethereum increases block.timestamp strictly per block,
190-
// so messages from different L1 blocks always land in different buckets. Under anvil with manual mining two
191-
// blocks can share a timestamp and therefore a bucket; this is harmless because the consumption cutoff is
192-
// computed over timestamps, so co-timestamped blocks are indistinguishable to it.
193-
if (bucketSeq == 0 || bucket.timestamp < block.timestamp || bucket.msgCount == MAX_MSGS_PER_BUCKET) {
194-
bucketSeq += 1;
195-
currentBucketSeq = bucketSeq;
196-
bucket = InboxBucket({
197-
rollingHash: bucket.rollingHash,
198-
totalMsgCount: bucket.totalMsgCount,
199-
timestamp: SafeCast.toUint64(block.timestamp),
200-
msgCount: 0
201-
});
202-
}
203-
204-
bucket.rollingHash = Hash.accumulateInboxRollingHash(bucket.rollingHash, _leaf);
205-
bucket.totalMsgCount += 1;
206-
bucket.msgCount += 1;
207-
buckets[bucketSeq % BUCKET_RING_SIZE] = bucket;
208-
209-
return (bucketSeq, bucket.rollingHash);
210-
}
211-
212171
/**
213172
* @notice Consumes the current tree, and starts a new one if needed
214173
*
@@ -269,4 +228,45 @@ contract Inbox is IInbox {
269228
require(_seq <= current && current - _seq < BUCKET_RING_SIZE, Errors.Inbox__BucketOutOfWindow(_seq, current));
270229
return buckets[_seq % BUCKET_RING_SIZE];
271230
}
231+
232+
/**
233+
* @notice Absorbs a message leaf into the consensus rolling hash and snapshots it into the bucket ring
234+
*
235+
* @dev A bucket only holds messages from a single L1 block, up to MAX_MSGS_PER_BUCKET; the first message
236+
* of a new L1 block — or the message after a full bucket, spilling over within the same block — opens the
237+
* next bucket, inheriting the rolling hash and cumulative count. Bucket 0 is the pristine genesis base
238+
* case and never absorbs. Opening a bucket overwrites the ring entry from BUCKET_RING_SIZE buckets ago;
239+
* protection against overwriting unconsumed buckets is not enforced yet.
240+
*
241+
* @param _leaf - The message leaf to absorb
242+
*
243+
* @return The sequence number of the bucket the leaf was absorbed into and the updated rolling hash
244+
*/
245+
function _absorbIntoBucket(bytes32 _leaf) internal returns (uint64, bytes32) {
246+
uint64 bucketSeq = currentBucketSeq;
247+
InboxBucket memory bucket = buckets[bucketSeq % BUCKET_RING_SIZE];
248+
249+
// Buckets are keyed by L1 block timestamp: a strictly larger timestamp opens a new bucket (a full bucket
250+
// also rolls over within the same block). Post-merge Ethereum increases block.timestamp strictly per block,
251+
// so messages from different L1 blocks always land in different buckets. Under anvil with manual mining two
252+
// blocks can share a timestamp and therefore a bucket; this is harmless because the consumption cutoff is
253+
// computed over timestamps, so co-timestamped blocks are indistinguishable to it.
254+
if (bucketSeq == 0 || bucket.timestamp < block.timestamp || bucket.msgCount == MAX_MSGS_PER_BUCKET) {
255+
bucketSeq += 1;
256+
currentBucketSeq = bucketSeq;
257+
bucket = InboxBucket({
258+
rollingHash: bucket.rollingHash,
259+
totalMsgCount: bucket.totalMsgCount,
260+
timestamp: SafeCast.toUint64(block.timestamp),
261+
msgCount: 0
262+
});
263+
}
264+
265+
bucket.rollingHash = Hash.accumulateInboxRollingHash(bucket.rollingHash, _leaf);
266+
bucket.totalMsgCount += 1;
267+
bucket.msgCount += 1;
268+
buckets[bucketSeq % BUCKET_RING_SIZE] = bucket;
269+
270+
return (bucketSeq, bucket.rollingHash);
271+
}
272272
}

0 commit comments

Comments
 (0)