Skip to content

Commit ab3f532

Browse files
committed
feat: check continuity of blocks + rework wrappers
1 parent 05e9ce8 commit ab3f532

File tree

8 files changed

+202
-153
lines changed

8 files changed

+202
-153
lines changed

crates/derivation-pipeline/src/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ pub enum DerivationPipelineError {
1919
/// Missing L1 message.
2020
#[error("missing l1 message for L2 block {0:?}")]
2121
MissingL1Message(L2Block),
22+
/// Blocks are not contiguous
23+
#[error("loss of contiguity in blocks: expected {expected}, got {got}")]
24+
BlockDiscontinuity {
25+
/// The expected block number.
26+
expected: u64,
27+
/// The actual block number.
28+
got: u64,
29+
},
2230
/// Unknown batch.
2331
#[error("unknown batch for index {0}")]
2432
UnknownBatch(u64),

crates/derivation-pipeline/src/lib.rs

Lines changed: 118 additions & 73 deletions
Large diffs are not rendered by default.

crates/engine/src/driver.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use crate::{
88
use alloy_provider::Provider;
99
use futures::{ready, task::AtomicWaker, FutureExt, Stream};
1010
use rollup_node_primitives::{
11-
BlockInfo, ChainImport, MeteredFuture, ScrollPayloadAttributesWithBatchInfo, WithBlockNumber,
11+
BlockInfo, ChainImport, MeteredFuture, WithFullL2Meta, WithL1FinalizedBlockNumber,
12+
WithL2BlockNumber,
1213
};
1314
use scroll_alloy_hardforks::ScrollHardforks;
1415
use scroll_alloy_network::Scroll;
@@ -38,7 +39,7 @@ pub struct EngineDriver<EC, CS, P> {
3839
/// Block building duration.
3940
block_building_duration: Duration,
4041
/// The pending payload attributes derived from batches on L1.
41-
l1_payload_attributes: VecDeque<WithBlockNumber<ScrollPayloadAttributesWithBatchInfo>>,
42+
l1_payload_attributes: VecDeque<WithFullL2Meta<ScrollPayloadAttributes>>,
4243
/// The pending block imports received over the network.
4344
chain_imports: VecDeque<ChainImport>,
4445
/// The latest optimistic sync target.
@@ -158,8 +159,8 @@ where
158159
// L2 reorged number.
159160
if let Some(MeteredFuture { fut, .. }) = self.engine_future.as_ref() {
160161
match fut {
161-
EngineFuture::ChainImport(WithBlockNumber { number, .. })
162-
if number > &l2_head_block_info.number =>
162+
EngineFuture::ChainImport(WithL2BlockNumber { l2_block, .. })
163+
if l2_block > &l2_head_block_info.number =>
163164
{
164165
self.engine_future = None
165166
}
@@ -182,15 +183,15 @@ where
182183
if matches!(
183184
self.engine_future.as_ref(),
184185
Some(MeteredFuture {
185-
fut: EngineFuture::L1Consolidation(WithBlockNumber { number, .. }),
186+
fut: EngineFuture::L1Consolidation(WithL1FinalizedBlockNumber { l1_block, .. }),
186187
..
187-
}) if number > &l1_block_number
188+
}) if l1_block > &l1_block_number
188189
) {
189190
self.engine_future = None;
190191
}
191192

192193
// retain the L1 payload attributes with block number <= L1 block.
193-
self.l1_payload_attributes.retain(|attribute| attribute.number <= l1_block_number);
194+
self.l1_payload_attributes.retain(|attribute| attribute.l1_block <= l1_block_number);
194195
}
195196

196197
/// Handles a block import request by adding it to the queue and waking up the driver.
@@ -217,10 +218,7 @@ where
217218

218219
/// Handles a [`ScrollPayloadAttributes`] sourced from L1 by initiating a task sending the
219220
/// attribute to the EN via the [`EngineDriver`].
220-
pub fn handle_l1_consolidation(
221-
&mut self,
222-
attributes: WithBlockNumber<ScrollPayloadAttributesWithBatchInfo>,
223-
) {
221+
pub fn handle_l1_consolidation(&mut self, attributes: WithFullL2Meta<ScrollPayloadAttributes>) {
224222
self.l1_payload_attributes.push_back(attributes);
225223
self.waker.wake();
226224
}

crates/engine/src/error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use alloy_rpc_types_engine::PayloadError;
2-
use rollup_node_primitives::{ScrollPayloadAttributesWithBatchInfo, WithBlockNumber};
2+
use rollup_node_primitives::WithFullL2Meta;
33
use scroll_alloy_provider::ScrollEngineApiError;
44
use scroll_alloy_rpc_types_engine::ScrollPayloadAttributes;
55

@@ -21,7 +21,7 @@ pub enum EngineDriverError {
2121
/// The payload id field is missing in the forkchoice update response for an L1 consolidation
2222
/// job.
2323
#[error("Forkchoice update response missing payload id for L1 consolidation job")]
24-
L1ConsolidationMissingPayloadId(WithBlockNumber<ScrollPayloadAttributesWithBatchInfo>),
24+
L1ConsolidationMissingPayloadId(WithFullL2Meta<ScrollPayloadAttributes>),
2525
/// The payload id field is missing in the forkchoice update response for a payload building
2626
/// job.
2727
#[error("Forkchoice update response missing payload id for payload building job")]

crates/engine/src/future/mod.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use eyre::Result;
1111
use reth_scroll_engine_primitives::try_into_block;
1212
use reth_scroll_primitives::ScrollBlock;
1313
use rollup_node_primitives::{
14-
BatchInfo, BlockInfo, ChainImport, L2BlockInfoWithL1Messages, MeteredFuture,
15-
ScrollPayloadAttributesWithBatchInfo, WithBlockNumber,
14+
BatchInfo, BlockInfo, ChainImport, L2BlockInfoWithL1Messages, MeteredFuture, WithFullL2Meta,
15+
WithL1FinalizedBlockNumber, WithL2BlockNumber,
1616
};
1717
use rollup_node_signer::SignatureAsBytes;
1818
use scroll_alloy_hardforks::ScrollHardforks;
@@ -99,8 +99,8 @@ pub(crate) type OptimisticSyncFuture =
9999
/// An enum that represents the different types of futures that can be executed on the engine API.
100100
/// It can be a block import job, an L1 consolidation job, or a new payload processing.
101101
pub(crate) enum EngineFuture {
102-
ChainImport(WithBlockNumber<ChainImportFuture>),
103-
L1Consolidation(WithBlockNumber<L1ConsolidationFuture>),
102+
ChainImport(WithL2BlockNumber<ChainImportFuture>),
103+
L1Consolidation(WithL1FinalizedBlockNumber<L1ConsolidationFuture>),
104104
NewPayload(NewPayloadFuture),
105105
OptimisticSync(OptimisticSyncFuture),
106106
}
@@ -115,7 +115,7 @@ impl EngineFuture {
115115
EC: ScrollEngineApi + Unpin + Send + Sync + 'static,
116116
{
117117
let highest_block_number = chain_import.chain.last().unwrap().number;
118-
Self::ChainImport(WithBlockNumber::new(
118+
Self::ChainImport(WithL2BlockNumber::new(
119119
highest_block_number,
120120
Box::pin(handle_chain_import(client, chain_import, fcs)),
121121
))
@@ -133,14 +133,14 @@ impl EngineFuture {
133133
client: Arc<EC>,
134134
execution_payload_provider: P,
135135
fcs: ForkchoiceState,
136-
payload_attributes: WithBlockNumber<ScrollPayloadAttributesWithBatchInfo>,
136+
payload_attributes: WithFullL2Meta<ScrollPayloadAttributes>,
137137
) -> Self
138138
where
139139
EC: ScrollEngineApi + Unpin + Send + Sync + 'static,
140140
P: Provider<Scroll> + Unpin + Send + Sync + 'static,
141141
{
142-
Self::L1Consolidation(WithBlockNumber::new(
143-
payload_attributes.number,
142+
Self::L1Consolidation(WithL1FinalizedBlockNumber::new(
143+
payload_attributes.l1_block,
144144
Box::pin(handle_payload_attributes(
145145
client,
146146
execution_payload_provider,
@@ -267,16 +267,19 @@ async fn handle_payload_attributes<EC, P>(
267267
client: Arc<EC>,
268268
provider: P,
269269
fcs: ForkchoiceState,
270-
payload_attributes_with_batch_info: WithBlockNumber<ScrollPayloadAttributesWithBatchInfo>,
270+
payload_attributes_with_batch_info: WithFullL2Meta<ScrollPayloadAttributes>,
271271
) -> Result<ConsolidationOutcome, EngineDriverError>
272272
where
273273
EC: ScrollEngineApi + Unpin + Send + Sync + 'static,
274274
P: Provider<Scroll> + Unpin + Send + Sync + 'static,
275275
{
276276
tracing::trace!(target: "scroll::engine::future", ?fcs, ?payload_attributes_with_batch_info, "handling payload attributes");
277277

278-
let ScrollPayloadAttributesWithBatchInfo { mut payload_attributes, batch_info } =
279-
payload_attributes_with_batch_info.inner.clone();
278+
let batch_info = BatchInfo::new(
279+
payload_attributes_with_batch_info.index,
280+
payload_attributes_with_batch_info.hash,
281+
);
282+
let mut payload_attributes = payload_attributes_with_batch_info.inner.inner.inner.clone();
280283

281284
let maybe_execution_payload = provider
282285
.get_block((fcs.safe_block_info().number + 1).into())

crates/primitives/src/attributes.rs

Lines changed: 0 additions & 18 deletions
This file was deleted.

crates/primitives/src/block.rs

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use core::{
88
pin::Pin,
99
task::{ready, Context, Poll},
1010
};
11+
use derive_more::{Deref, DerefMut};
1112
use reth_primitives_traits::transaction::signed::SignedTransaction;
1213
use reth_scroll_primitives::{ScrollBlock, ScrollTransactionSigned};
1314
use scroll_alloy_consensus::L1_MESSAGE_TRANSACTION_TYPE;
@@ -83,69 +84,84 @@ impl arbitrary::Arbitrary<'_> for BlockInfo {
8384
}
8485
}
8586

86-
/// A type alias for a wrapper around a type to which a L1 finalized block number is attached.
87-
pub type WithFinalizedBlockNumber<T> = WithBlockNumber<T>;
88-
8987
/// A wrapper around a type to which a block number is attached.
90-
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
91-
pub struct WithBlockNumber<T> {
92-
/// The block number.
93-
pub number: u64,
88+
#[derive(Debug, Deref, DerefMut, Default, Copy, Clone, PartialEq, Eq)]
89+
pub struct WithL2BlockNumber<T> {
90+
/// The L2 block number.
91+
pub l2_block: u64,
9492
/// The wrapped type.
93+
#[deref]
94+
#[deref_mut]
9595
pub inner: T,
9696
}
9797

98-
impl<T> WithBlockNumber<T> {
98+
impl<T> WithL2BlockNumber<T> {
9999
/// Returns a new instance of a [`WithBlockNumber`] wrapper.
100-
pub const fn new(number: u64, inner: T) -> Self {
101-
Self { number, inner }
100+
pub const fn new(l2_block: u64, inner: T) -> Self {
101+
Self { l2_block, inner }
102102
}
103103
}
104104

105-
impl<T: Future + Unpin> Future for WithBlockNumber<T> {
106-
type Output = WithBlockNumber<<T as Future>::Output>;
105+
impl<T: Future + Unpin> Future for WithL2BlockNumber<T> {
106+
type Output = WithL2BlockNumber<<T as Future>::Output>;
107107

108108
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
109-
let block_number = self.number;
109+
let block_number = self.l2_block;
110110
let inner = ready!(Pin::new(&mut self.get_mut().inner).poll(cx));
111-
Poll::Ready(WithBlockNumber::new(block_number, inner))
111+
Poll::Ready(WithL2BlockNumber::new(block_number, inner))
112+
}
113+
}
114+
115+
/// A wrapper around a type to which a block number is attached.
116+
#[derive(Debug, Deref, DerefMut, Default, Copy, Clone, PartialEq, Eq)]
117+
pub struct WithL1FinalizedBlockNumber<T> {
118+
/// The block number.
119+
pub l1_block: u64,
120+
/// The wrapped type.
121+
#[deref]
122+
#[deref_mut]
123+
pub inner: T,
124+
}
125+
126+
impl<T> WithL1FinalizedBlockNumber<T> {
127+
/// Returns a new instance of a [`WithBlockNumber`] wrapper.
128+
pub const fn new(l1_block: u64, inner: T) -> Self {
129+
Self { l1_block, inner }
112130
}
113131
}
114132

115-
/// A type alias for a wrapper around a type to which a finalized batch information is attached.
116-
pub type WithFinalizedBatchInfo<T> = WithBatchInfo<T>;
133+
impl<T: Future + Unpin> Future for WithL1FinalizedBlockNumber<T> {
134+
type Output = WithL1FinalizedBlockNumber<<T as Future>::Output>;
117135

118-
/// A type alias for a wrapper around a type to which a committed batch information is attached.
119-
pub type WithCommittedBatchInfo<T> = WithBatchInfo<T>;
136+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
137+
let block_number = self.l1_block;
138+
let inner = ready!(Pin::new(&mut self.get_mut().inner).poll(cx));
139+
Poll::Ready(WithL1FinalizedBlockNumber::new(block_number, inner))
140+
}
141+
}
120142

121143
/// A wrapper around a type to which a batch information is attached.
122-
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
144+
#[derive(Debug, Deref, DerefMut, Default, Copy, Clone, PartialEq, Eq)]
123145
pub struct WithBatchInfo<T> {
124-
/// The l1 block number associated with the batch.
125-
pub number: u64,
126146
/// The index of the batch.
127147
pub index: u64,
148+
/// The hash of the batch.
149+
pub hash: B256,
128150
/// The wrapped type.
151+
#[deref]
152+
#[deref_mut]
129153
pub inner: T,
130154
}
131155

132156
impl<T> WithBatchInfo<T> {
133157
/// Returns a new instance of a [`WithBatchInfo`] wrapper.
134-
pub const fn new(index: u64, number: u64, inner: T) -> Self {
135-
Self { index, number, inner }
158+
pub const fn new(index: u64, hash: B256, inner: T) -> Self {
159+
Self { index, hash, inner }
136160
}
137161
}
138162

139-
impl<T: Future + Unpin> Future for WithBatchInfo<T> {
140-
type Output = WithBatchInfo<<T as Future>::Output>;
141-
142-
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
143-
let block_number = self.number;
144-
let index = self.index;
145-
let inner = ready!(Pin::new(&mut self.get_mut().inner).poll(cx));
146-
Poll::Ready(WithBatchInfo::new(index, block_number, inner))
147-
}
148-
}
163+
/// Type alias for a wrapper type with the full L2 metadata.
164+
pub type WithFullL2Meta<T> = WithL1FinalizedBlockNumber<WithL2BlockNumber<WithBatchInfo<T>>>;
149165

150166
/// This struct represents an L2 block with a vector the hashes of the L1 messages included in the
151167
/// block.

crates/primitives/src/lib.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44
#[cfg(not(feature = "std"))]
55
extern crate alloc as std;
66

7-
mod attributes;
8-
pub use attributes::ScrollPayloadAttributesWithBatchInfo;
9-
107
mod block;
118
pub use block::{
12-
BlockInfo, L2BlockInfoWithL1Messages, WithBatchInfo, WithBlockNumber, WithCommittedBatchInfo,
13-
WithFinalizedBatchInfo, WithFinalizedBlockNumber, DEFAULT_BLOCK_DIFFICULTY,
9+
BlockInfo, L2BlockInfoWithL1Messages, WithBatchInfo, WithFullL2Meta,
10+
WithL1FinalizedBlockNumber, WithL2BlockNumber, DEFAULT_BLOCK_DIFFICULTY,
1411
};
1512

1613
mod batch;

0 commit comments

Comments
 (0)