Skip to content

Commit c7751a5

Browse files
authored
Merge branch 'main' into feat-forward-txs-to-sequencer
2 parents 1ac2481 + 7bb6759 commit c7751a5

File tree

36 files changed

+2572
-2424
lines changed

36 files changed

+2572
-2424
lines changed

Cargo.lock

Lines changed: 149 additions & 163 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM rust:1.86.0 AS chef
1+
FROM rust:1.88.0 AS chef
22

33
RUN apt-get update -y && apt-get upgrade -y
44

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ test:
7070
--all-features \
7171
--no-fail-fast
7272

73+
# Used to update the mainnet-sample.sql data. Provide the path to the sqlite database that should be read from
74+
# using `DB_PATH`.
75+
.PHONY: test-data
76+
export-sample-test-data:
77+
sqlite3 "$(DB_PATH)" <<EOF > mainnet-sample.sql
78+
.headers on
79+
.mode insert block_data
80+
SELECT * FROM block_data LIMIT 2000;
81+
EOF
82+
7383
.PHONY: docs
7484
docs:
7585
cargo docs --document-private-items

crates/codec/src/decoding/blob.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl<'a> Iterator for BlobSliceIter<'a> {
2020
type Item = &'a u8;
2121

2222
fn next(&mut self) -> Option<Self::Item> {
23-
if self.count % 32 == 0 {
23+
if self.count.is_multiple_of(32) {
2424
let _ = self.iterator.next();
2525
self.count += 1;
2626
}

crates/codec/src/decoding/payload.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub struct PayloadData {
1111
pub blocks: Vec<L2Block>,
1212
/// Contains information about the current state of the L1 message queue.
1313
pub l1_message_queue_info: L1MessageQueueInfo,
14+
/// Contains the skipped L1 message bitmap if present.
15+
pub skipped_l1_message_bitmap: Option<Vec<u8>>,
1416
}
1517

1618
/// Information about the state of the L1 message queue.

crates/codec/src/decoding/v0/batch_header.rs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55

66
use alloy_primitives::{
77
bytes::{Buf, BufMut},
8-
keccak256, B256, U256,
8+
keccak256, B256,
99
};
1010

1111
/// The batch header for V0.
@@ -24,7 +24,7 @@ pub struct BatchHeaderV0 {
2424
/// The parent batch hash.
2525
pub parent_batch_hash: B256,
2626
/// A bitmap to indicate which L1 messages are skipped in the batch.
27-
pub skipped_l1_message_bitmap: Vec<U256>,
27+
pub skipped_l1_message_bitmap: Vec<u8>,
2828
}
2929

3030
impl BatchHeaderV0 {
@@ -38,7 +38,7 @@ impl BatchHeaderV0 {
3838
total_l1_message_popped: u64,
3939
data_hash: B256,
4040
parent_batch_hash: B256,
41-
skipped_l1_message_bitmap: Vec<U256>,
41+
skipped_l1_message_bitmap: Vec<u8>,
4242
) -> Self {
4343
Self {
4444
version,
@@ -69,7 +69,9 @@ impl BatchHeaderV0 {
6969

7070
let skipped_l1_message_bitmap: Vec<_> = buf
7171
.chunks(SKIPPED_L1_MESSAGE_BITMAP_ITEM_BYTES_SIZE)
72-
.map(|chunk| U256::from_be_slice(chunk))
72+
.flatten()
73+
.rev()
74+
.copied()
7375
.collect();
7476

7577
// check leftover bytes are correct.
@@ -78,7 +80,7 @@ impl BatchHeaderV0 {
7880
{
7981
return Err(DecodingError::Eof)
8082
}
81-
buf.advance(skipped_l1_message_bitmap.len() * SKIPPED_L1_MESSAGE_BITMAP_ITEM_BYTES_SIZE);
83+
buf.advance(skipped_l1_message_bitmap.len());
8284

8385
Ok(Self {
8486
version,
@@ -104,12 +106,7 @@ impl BatchHeaderV0 {
104106
bytes.put_slice(&self.data_hash.0);
105107
bytes.put_slice(&self.parent_batch_hash.0);
106108

107-
let skipped_l1_message_flat_bitmap = self
108-
.skipped_l1_message_bitmap
109-
.iter()
110-
.flat_map(|u| u.to_be_bytes::<32>())
111-
.collect::<Vec<_>>();
112-
bytes.put_slice(&skipped_l1_message_flat_bitmap);
109+
bytes.put_slice(&self.skipped_l1_message_bitmap);
113110

114111
keccak256(bytes)
115112
}
@@ -119,7 +116,7 @@ impl BatchHeaderV0 {
119116
mod tests {
120117
use crate::decoding::{test_utils::read_to_bytes, v0::BatchHeaderV0};
121118

122-
use alloy_primitives::{b256, U256};
119+
use alloy_primitives::b256;
123120
use alloy_sol_types::SolCall;
124121
use scroll_l1::abi::calls::commitBatchCall;
125122

@@ -139,7 +136,34 @@ mod tests {
139136
33,
140137
b256!("2aa3eeb5adebb96a49736583c744b89b0b3be45056e8e178106a42ab2cd1a063"),
141138
b256!("c0173d7e3561501cf57913763c7c34716216092a222a99fe8b85dcb466730f56"),
142-
vec![U256::ZERO],
139+
vec![0; 32],
140+
);
141+
assert_eq!(header, expected);
142+
143+
Ok(())
144+
}
145+
146+
#[test]
147+
fn test_should_decode_header_with_skipped_l1_messages() -> eyre::Result<()> {
148+
// <https://sepolia.etherscan.io/tx/0xacacfe48bed1944d6586ca8f0bec3ecd10ea0a99e104517f75845b8602dcab31>
149+
let raw_commit_calldata =
150+
read_to_bytes("./testdata/calldata_v0_with_skipped_l1_messages.bin")?;
151+
let commit_calldata = commitBatchCall::abi_decode(&raw_commit_calldata)?;
152+
153+
let mut raw_batch_header = &*commit_calldata.parent_batch_header.to_vec();
154+
let header = BatchHeaderV0::try_from_buf(&mut raw_batch_header)?;
155+
156+
let expected = BatchHeaderV0::new(
157+
0,
158+
100,
159+
3,
160+
22,
161+
b256!("4867e8b3c751abf5f0f8cd8e3e91f78ff15011b48b981ad742cb42dfd746844c"),
162+
b256!("b4d0a673c704d567eebcd758802ce87cf103b16acbae7c52b2807928fd8dc76e"),
163+
vec![
164+
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
165+
0, 0, 0, 0,
166+
],
143167
);
144168
assert_eq!(header, expected);
145169

@@ -156,7 +180,7 @@ mod tests {
156180
33,
157181
b256!("2aa3eeb5adebb96a49736583c744b89b0b3be45056e8e178106a42ab2cd1a063"),
158182
b256!("c0173d7e3561501cf57913763c7c34716216092a222a99fe8b85dcb466730f56"),
159-
vec![U256::ZERO],
183+
vec![0; 32],
160184
);
161185

162186
let expected = b256!("A7F7C528E1827D3E64E406C76DE6C750D5FC3DE3DE4386E6C69958A89461D064");

crates/codec/src/decoding/v0/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@ pub fn decode_v0(calldata: &[u8]) -> Result<Batch, DecodingError> {
6161
let parent_header = BatchHeaderV0::try_from_buf(&mut (&*raw_parent_header))?;
6262
let l1_message_start_index = parent_header.total_l1_message_popped;
6363

64-
let payload =
65-
PayloadData { blocks: l2_blocks, l1_message_queue_info: l1_message_start_index.into() };
64+
let payload = PayloadData {
65+
blocks: l2_blocks,
66+
l1_message_queue_info: l1_message_start_index.into(),
67+
skipped_l1_message_bitmap: call.skipped_l1_message_bitmap(),
68+
};
6669

6770
Ok(Batch::new(call.version(), Some(chunks_block_count), payload))
6871
}

crates/codec/src/decoding/v1/batch_header.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55

66
use alloy_primitives::{
77
bytes::{Buf, BufMut},
8-
keccak256, B256, U256,
8+
keccak256, B256,
99
};
1010

1111
/// The batch header for V1.
@@ -26,7 +26,7 @@ pub struct BatchHeaderV1 {
2626
/// The parent batch hash.
2727
pub parent_batch_hash: B256,
2828
/// A bitmap to indicate which L1 messages are skipped in the batch.
29-
pub skipped_l1_message_bitmap: Vec<U256>,
29+
pub skipped_l1_message_bitmap: Vec<u8>,
3030
}
3131

3232
impl BatchHeaderV1 {
@@ -42,7 +42,7 @@ impl BatchHeaderV1 {
4242
data_hash: B256,
4343
blob_versioned_hash: B256,
4444
parent_batch_hash: B256,
45-
skipped_l1_message_bitmap: Vec<U256>,
45+
skipped_l1_message_bitmap: Vec<u8>,
4646
) -> Self {
4747
Self {
4848
version,
@@ -75,7 +75,9 @@ impl BatchHeaderV1 {
7575

7676
let skipped_l1_message_bitmap: Vec<_> = buf
7777
.chunks(SKIPPED_L1_MESSAGE_BITMAP_ITEM_BYTES_SIZE)
78-
.map(|chunk| U256::from_be_slice(chunk))
78+
.flatten()
79+
.rev()
80+
.copied()
7981
.collect();
8082

8183
// check leftover bytes are correct.
@@ -84,7 +86,7 @@ impl BatchHeaderV1 {
8486
{
8587
return Err(DecodingError::Eof)
8688
}
87-
buf.advance(skipped_l1_message_bitmap.len() * SKIPPED_L1_MESSAGE_BITMAP_ITEM_BYTES_SIZE);
89+
buf.advance(skipped_l1_message_bitmap.len());
8890

8991
Ok(Self {
9092
version,
@@ -112,12 +114,7 @@ impl BatchHeaderV1 {
112114
bytes.put_slice(&self.blob_versioned_hash.0);
113115
bytes.put_slice(&self.parent_batch_hash.0);
114116

115-
let skipped_l1_message_flat_bitmap = self
116-
.skipped_l1_message_bitmap
117-
.iter()
118-
.flat_map(|u| u.to_be_bytes::<32>())
119-
.collect::<Vec<_>>();
120-
bytes.put_slice(&skipped_l1_message_flat_bitmap);
117+
bytes.put_slice(&self.skipped_l1_message_bitmap);
121118

122119
keccak256(bytes)
123120
}

crates/codec/src/decoding/v1/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,19 @@ pub fn decode_v1(calldata: &[u8], blob: &[u8]) -> Result<Batch, DecodingError> {
5252
// move pass chunk information.
5353
buf.advance(TRANSACTION_DATA_BLOB_INDEX_OFFSET);
5454

55-
decode_v1_chunk(call.version(), l1_message_start_index, chunks, buf)
55+
decode_v1_chunk(
56+
call.version(),
57+
call.skipped_l1_message_bitmap(),
58+
l1_message_start_index,
59+
chunks,
60+
buf,
61+
)
5662
}
5763

5864
/// Decode the provided chunks and blob data into [`L2Block`].
5965
pub(crate) fn decode_v1_chunk(
6066
version: u8,
67+
skipped_l1_message_bitmap: Option<Vec<u8>>,
6168
l1_message_start_index: u64,
6269
chunks: Vec<&[u8]>,
6370
blob: &[u8],
@@ -98,8 +105,11 @@ pub(crate) fn decode_v1_chunk(
98105
}
99106
}
100107

101-
let payload =
102-
PayloadData { blocks: l2_blocks, l1_message_queue_info: l1_message_start_index.into() };
108+
let payload = PayloadData {
109+
blocks: l2_blocks,
110+
l1_message_queue_info: l1_message_start_index.into(),
111+
skipped_l1_message_bitmap,
112+
};
103113

104114
Ok(Batch::new(version, Some(chunks_block_count), payload))
105115
}

crates/codec/src/decoding/v2/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ pub fn decode_v2(calldata: &[u8], blob: &[u8]) -> Result<Batch, DecodingError> {
5050
// clone buf and move pass chunk information.
5151
buf.advance(TRANSACTION_DATA_BLOB_INDEX_OFFSET);
5252

53-
decode_v1_chunk(call.version(), l1_message_start_index, chunks, buf)
53+
decode_v1_chunk(
54+
call.version(),
55+
call.skipped_l1_message_bitmap(),
56+
l1_message_start_index,
57+
chunks,
58+
buf,
59+
)
5460
}
5561

5662
#[cfg(test)]

0 commit comments

Comments
 (0)