Skip to content
This repository was archived by the owner on Jan 16, 2026. It is now read-only.

Commit 79fc6e6

Browse files
committed
refactor(protocol/protocol) switch to nested structs
1 parent 55152ee commit 79fc6e6

13 files changed

Lines changed: 1208 additions & 493 deletions

File tree

crates/protocol/derive/src/stages/batch/batch_queue.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -987,16 +987,16 @@ mod tests {
987987
batch_vec.push(Ok(batch));
988988
}
989989
// Insert a deposit transaction in the front of the second batch txs
990-
let expected = L1BlockInfoBedrock {
991-
number: 16988980031808077784,
992-
time: 1697121143,
993-
base_fee: 10419034451,
994-
block_hash: b256!("392012032675be9f94aae5ab442de73c5f4fb1bf30fa7dd0d2442239899a40fc"),
995-
sequence_number: 4,
996-
batcher_address: address!("6887246668a3b87f54deb3b94ba47a6f63f32985"),
997-
l1_fee_overhead: U256::from(0xbc),
998-
l1_fee_scalar: U256::from(0xa6fe0),
999-
};
990+
let expected = L1BlockInfoBedrock::new(
991+
16988980031808077784,
992+
1697121143,
993+
10419034451,
994+
b256!("392012032675be9f94aae5ab442de73c5f4fb1bf30fa7dd0d2442239899a40fc"),
995+
4,
996+
address!("6887246668a3b87f54deb3b94ba47a6f63f32985"),
997+
U256::from(0xbc),
998+
U256::from(0xa6fe0),
999+
);
10001000
let deposit_tx_calldata: Bytes = L1BlockInfoTx::Bedrock(expected).encode_calldata();
10011001
let tx = TxDeposit {
10021002
source_hash: B256::left_padding_from(&[0xde, 0xad]),
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/// For structs that has an embedded basefield.
2+
pub(crate) trait HasBaseField<BaseField> {
3+
fn base(&self) -> BaseField;
4+
}

crates/protocol/protocol/src/info/bedrock.rs

Lines changed: 149 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
use alloc::vec::Vec;
44
use alloy_primitives::{Address, B256, Bytes, U256};
55

6-
use crate::DecodeError;
7-
6+
use crate::{
7+
DecodeError,
8+
info::{HasBaseField, L1BlockInfoBedrockBaseFields, bedrock_base::L1BlockInfoBedrockBase},
9+
};
810
/// Represents the fields within a Bedrock L1 block info transaction.
911
///
1012
/// Bedrock Binary Format
@@ -24,24 +26,73 @@ use crate::DecodeError;
2426
#[derive(Debug, Clone, Hash, Eq, PartialEq, Default, Copy)]
2527
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2628
pub struct L1BlockInfoBedrock {
27-
/// The current L1 origin block number
28-
pub number: u64,
29-
/// The current L1 origin block's timestamp
30-
pub time: u64,
31-
/// The current L1 origin block's basefee
32-
pub base_fee: u64,
33-
/// The current L1 origin block's hash
34-
pub block_hash: B256,
35-
/// The current sequence number
36-
pub sequence_number: u64,
37-
/// The address of the batch submitter
38-
pub batcher_address: Address,
39-
/// The fee overhead for L1 data
29+
#[cfg_attr(feature = "serde", serde(flatten))]
30+
base: L1BlockInfoBedrockBase,
31+
/// The fee overhead for L1 data. Deprecated in Ecotone.
4032
pub l1_fee_overhead: U256,
41-
/// The fee scalar for L1 data
33+
/// The fee scalar for L1 data. Deprecated in Ecotone.
4234
pub l1_fee_scalar: U256,
4335
}
4436

37+
impl HasBaseField<L1BlockInfoBedrockBase> for L1BlockInfoBedrock {
38+
fn base(&self) -> L1BlockInfoBedrockBase {
39+
self.base
40+
}
41+
}
42+
43+
impl L1BlockInfoBedrockBaseFields for L1BlockInfoBedrock {
44+
fn number(&self) -> u64 {
45+
self.base().number()
46+
}
47+
48+
fn time(&self) -> u64 {
49+
self.base().time()
50+
}
51+
52+
fn base_fee(&self) -> u64 {
53+
self.base().base_fee()
54+
}
55+
56+
fn block_hash(&self) -> B256 {
57+
self.base().block_hash()
58+
}
59+
60+
fn sequence_number(&self) -> u64 {
61+
self.base().sequence_number()
62+
}
63+
64+
fn batcher_address(&self) -> Address {
65+
self.base().batcher_address()
66+
}
67+
}
68+
69+
/// Accessors for fields deprecated after Bedrock.
70+
pub trait L1BlockInfoBedrockOnlyFields {
71+
/// The fee overhead for L1 data. Deprecated in Ecotone.
72+
fn l1_fee_overhead(&self) -> U256;
73+
74+
/// The fee scalar for L1 data. Deprecated in Ecotone.
75+
fn l1_fee_scalar(&self) -> U256;
76+
}
77+
78+
impl L1BlockInfoBedrockOnlyFields for L1BlockInfoBedrock {
79+
fn l1_fee_overhead(&self) -> U256 {
80+
self.l1_fee_overhead
81+
}
82+
83+
fn l1_fee_scalar(&self) -> U256 {
84+
self.l1_fee_scalar
85+
}
86+
}
87+
88+
/// Accessors trait for all fields on [`L1BlockInfoBedrock`].
89+
pub trait L1BlockInfoBedrockFields:
90+
L1BlockInfoBedrockBaseFields + L1BlockInfoBedrockOnlyFields
91+
{
92+
}
93+
94+
impl L1BlockInfoBedrockFields for L1BlockInfoBedrock {}
95+
4596
impl L1BlockInfoBedrock {
4697
/// The length of an L1 info transaction in Bedrock.
4798
pub const L1_INFO_TX_LEN: usize = 4 + 32 * 8;
@@ -54,14 +105,14 @@ impl L1BlockInfoBedrock {
54105
pub fn encode_calldata(&self) -> Bytes {
55106
let mut buf = Vec::with_capacity(Self::L1_INFO_TX_LEN);
56107
buf.extend_from_slice(Self::L1_INFO_TX_SELECTOR.as_ref());
57-
buf.extend_from_slice(U256::from(self.number).to_be_bytes::<32>().as_slice());
58-
buf.extend_from_slice(U256::from(self.time).to_be_bytes::<32>().as_slice());
59-
buf.extend_from_slice(U256::from(self.base_fee).to_be_bytes::<32>().as_slice());
60-
buf.extend_from_slice(self.block_hash.as_slice());
61-
buf.extend_from_slice(U256::from(self.sequence_number).to_be_bytes::<32>().as_slice());
62-
buf.extend_from_slice(self.batcher_address.into_word().as_slice());
63-
buf.extend_from_slice(self.l1_fee_overhead.to_be_bytes::<32>().as_slice());
64-
buf.extend_from_slice(self.l1_fee_scalar.to_be_bytes::<32>().as_slice());
108+
buf.extend_from_slice(U256::from(self.number()).to_be_bytes::<32>().as_slice());
109+
buf.extend_from_slice(U256::from(self.time()).to_be_bytes::<32>().as_slice());
110+
buf.extend_from_slice(U256::from(self.base_fee()).to_be_bytes::<32>().as_slice());
111+
buf.extend_from_slice(self.block_hash().as_slice());
112+
buf.extend_from_slice(U256::from(self.sequence_number()).to_be_bytes::<32>().as_slice());
113+
buf.extend_from_slice(self.batcher_address().into_word().as_slice());
114+
buf.extend_from_slice(self.l1_fee_overhead().to_be_bytes::<32>().as_slice());
115+
buf.extend_from_slice(self.l1_fee_scalar().to_be_bytes::<32>().as_slice());
65116
buf.into()
66117
}
67118

@@ -100,7 +151,7 @@ impl L1BlockInfoBedrock {
100151
let l1_fee_overhead = U256::from_be_slice(r[196..228].as_ref());
101152
let l1_fee_scalar = U256::from_be_slice(r[228..260].as_ref());
102153

103-
Ok(Self {
154+
Ok(Self::new(
104155
number,
105156
time,
106157
base_fee,
@@ -109,7 +160,69 @@ impl L1BlockInfoBedrock {
109160
batcher_address,
110161
l1_fee_overhead,
111162
l1_fee_scalar,
112-
})
163+
))
164+
}
165+
/// Construct from all values.
166+
#[allow(clippy::too_many_arguments)]
167+
pub const fn new(
168+
number: u64,
169+
time: u64,
170+
base_fee: u64,
171+
block_hash: B256,
172+
sequence_number: u64,
173+
batcher_address: Address,
174+
l1_fee_overhead: U256,
175+
l1_fee_scalar: U256,
176+
) -> Self {
177+
Self {
178+
base: L1BlockInfoBedrockBase::new(
179+
number,
180+
time,
181+
base_fee,
182+
block_hash,
183+
sequence_number,
184+
batcher_address,
185+
),
186+
l1_fee_overhead,
187+
l1_fee_scalar,
188+
}
189+
}
190+
/// Construct from default values and `base_fee`.
191+
pub fn new_from_base_fee(base_fee: u64) -> Self {
192+
Self { base: L1BlockInfoBedrockBase::new_from_base_fee(base_fee), ..Default::default() }
193+
}
194+
/// Construct from default values and `block_hash`.
195+
pub fn new_from_block_hash(block_hash: B256) -> Self {
196+
Self { base: L1BlockInfoBedrockBase::new_from_block_hash(block_hash), ..Default::default() }
197+
}
198+
/// Construct from default values and `sequence_number`.
199+
pub fn new_from_sequence_number(sequence_number: u64) -> Self {
200+
Self {
201+
base: L1BlockInfoBedrockBase::new_from_sequence_number(sequence_number),
202+
..Default::default()
203+
}
204+
}
205+
/// Construct from default values and `batcher_address`.
206+
pub fn new_from_batcher_address(batcher_address: Address) -> Self {
207+
Self {
208+
base: L1BlockInfoBedrockBase::new_from_batcher_address(batcher_address),
209+
..Default::default()
210+
}
211+
}
212+
/// Construct from default values and `l1_fee_scalar`.
213+
pub fn new_from_l1_fee_scalar(l1_fee_scalar: U256) -> Self {
214+
Self { l1_fee_scalar, ..Default::default() }
215+
}
216+
/// Construct from default values and `l1_fee_overhead`.
217+
pub fn new_from_l1_fee_overhead(l1_fee_overhead: U256) -> Self {
218+
Self { l1_fee_overhead, ..Default::default() }
219+
}
220+
/// Construct from default values, `number` and `block_hash`.
221+
pub fn new_from_number_and_block_hash(number: u64, block_hash: B256) -> Self {
222+
Self {
223+
base: L1BlockInfoBedrockBase::new_from_number_and_block_hash(number, block_hash),
224+
..Default::default()
225+
}
113226
}
114227
}
115228

@@ -129,16 +242,16 @@ mod tests {
129242

130243
#[test]
131244
fn test_l1_block_info_bedrock_roundtrip_calldata_encoding() {
132-
let info = L1BlockInfoBedrock {
133-
number: 1,
134-
time: 2,
135-
base_fee: 3,
136-
block_hash: B256::from([4u8; 32]),
137-
sequence_number: 5,
138-
batcher_address: Address::from([6u8; 20]),
139-
l1_fee_overhead: U256::from(7),
140-
l1_fee_scalar: U256::from(8),
141-
};
245+
let info = L1BlockInfoBedrock::new(
246+
1,
247+
2,
248+
3,
249+
B256::from([4u8; 32]),
250+
5,
251+
Address::from([6u8; 20]),
252+
U256::from(7),
253+
U256::from(8),
254+
);
142255

143256
let calldata = info.encode_calldata();
144257
let decoded_info = L1BlockInfoBedrock::decode_calldata(&calldata).unwrap();
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use alloy_primitives::{Address, B256};
2+
3+
#[derive(Debug, Clone, Hash, Eq, PartialEq, Default, Copy)]
4+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5+
pub(crate) struct L1BlockInfoBedrockBase {
6+
/// The current L1 origin block number
7+
pub number: u64,
8+
/// The current L1 origin block's timestamp
9+
pub time: u64,
10+
/// The current L1 origin block's basefee
11+
pub base_fee: u64,
12+
/// The current L1 origin block's hash
13+
pub block_hash: B256,
14+
/// The current sequence number
15+
pub sequence_number: u64,
16+
/// The address of the batch submitter
17+
pub batcher_address: Address,
18+
}
19+
20+
/// Accessors for Bedrock fields that still are available in latest hardfork.
21+
pub trait L1BlockInfoBedrockBaseFields {
22+
/// The current L1 origin block number
23+
fn number(&self) -> u64;
24+
25+
/// The current L1 origin block's timestamp
26+
fn time(&self) -> u64;
27+
28+
/// The current L1 origin block's basefee
29+
fn base_fee(&self) -> u64;
30+
31+
/// The current L1 origin block's hash
32+
fn block_hash(&self) -> B256;
33+
34+
/// The current sequence number
35+
fn sequence_number(&self) -> u64;
36+
37+
/// The address of the batch new_from_l1_base_feesubmitter
38+
fn batcher_address(&self) -> Address;
39+
}
40+
41+
impl L1BlockInfoBedrockBaseFields for L1BlockInfoBedrockBase {
42+
fn number(&self) -> u64 {
43+
self.number
44+
}
45+
46+
fn time(&self) -> u64 {
47+
self.time
48+
}
49+
50+
fn base_fee(&self) -> u64 {
51+
self.base_fee
52+
}
53+
54+
fn block_hash(&self) -> B256 {
55+
self.block_hash
56+
}
57+
58+
fn sequence_number(&self) -> u64 {
59+
self.sequence_number
60+
}
61+
62+
fn batcher_address(&self) -> Address {
63+
self.batcher_address
64+
}
65+
}
66+
67+
impl L1BlockInfoBedrockBase {
68+
/// Construct from all values.
69+
#[allow(clippy::too_many_arguments)]
70+
pub(crate) const fn new(
71+
number: u64,
72+
time: u64,
73+
base_fee: u64,
74+
block_hash: B256,
75+
sequence_number: u64,
76+
batcher_address: Address,
77+
) -> Self {
78+
Self { number, time, base_fee, block_hash, sequence_number, batcher_address }
79+
}
80+
/// Construct from default values and `base_fee`.
81+
pub(crate) fn new_from_base_fee(base_fee: u64) -> Self {
82+
Self { base_fee, ..Default::default() }
83+
}
84+
/// Construct from default values and `block_hash`.
85+
pub(crate) fn new_from_block_hash(block_hash: B256) -> Self {
86+
Self { block_hash, ..Default::default() }
87+
}
88+
/// Construct from default values and `sequence_number`.
89+
pub(crate) fn new_from_sequence_number(sequence_number: u64) -> Self {
90+
Self { sequence_number, ..Default::default() }
91+
}
92+
/// Construct from default values and `batcher_address`.
93+
pub(crate) fn new_from_batcher_address(batcher_address: Address) -> Self {
94+
Self { batcher_address, ..Default::default() }
95+
}
96+
/// Construct from default values, `number` and `block_hash`.
97+
pub(crate) fn new_from_number_and_block_hash(number: u64, block_hash: B256) -> Self {
98+
Self { number, block_hash, ..Default::default() }
99+
}
100+
}

0 commit comments

Comments
 (0)