Skip to content

Commit 4d69124

Browse files
committed
fix L1 watcher revert batches
1 parent 08ca239 commit 4d69124

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

crates/database/db/src/operations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ impl<T: WriteConnectionProvider + ?Sized + Sync> DatabaseWriteOperations for T {
279279
.add(models::batch_commit::Column::Index.lte(end_index as i64))
280280
.add(models::batch_commit::Column::RevertedBlockNumber.is_null());
281281

282-
// Fetch the batch hashes to update the
282+
// Fetch the batch hashes
283283
let batch_hashes = models::batch_commit::Entity::find()
284284
.select_only()
285285
.column(models::batch_commit::Column::Hash)

crates/watcher/src/lib.rs

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ use rollup_node_primitives::{
2323
};
2424
use rollup_node_providers::SystemContractProvider;
2525
use scroll_alloy_consensus::TxL1Message;
26-
use scroll_l1::abi::logs::{try_decode_log, CommitBatch, FinalizeBatch, QueueTransaction};
26+
use scroll_l1::abi::logs::{
27+
try_decode_log, CommitBatch, FinalizeBatch, QueueTransaction, RevertBatch_0, RevertBatch_1,
28+
};
2729
use std::{
2830
cmp::Ordering,
2931
fmt::{Debug, Display, Formatter},
@@ -329,6 +331,8 @@ where
329331

330332
// handle all events.
331333
notifications.extend(self.handle_l1_messages(&logs).await?);
334+
notifications.extend(self.handle_batch_reverts(&logs).await?);
335+
notifications.extend(self.handle_batch_revert_ranges(&logs).await?);
332336
notifications.extend(self.handle_batch_commits(&logs).await?);
333337
notifications.extend(self.handle_batch_finalization(&logs).await?);
334338
if let Some(system_contract_update) =
@@ -580,6 +584,63 @@ where
580584
Ok(notifications)
581585
}
582586

587+
/// Handles the batch revert events.
588+
#[tracing::instrument(skip_all)]
589+
async fn handle_batch_reverts(&self, logs: &[Log]) -> L1WatcherResult<Vec<L1Notification>> {
590+
// filter revert logs.
591+
logs.iter()
592+
.map(|l| (l, l.block_number, l.block_hash))
593+
.filter_map(|(log, bn, bh)| {
594+
try_decode_log::<RevertBatch_0>(&log.inner).map(|decoded| (decoded.data, bn, bh))
595+
})
596+
.map(|(decoded_log, maybe_block_number, maybe_block_hash)| {
597+
// process the revert log.
598+
let block_number = maybe_block_number.ok_or(FilterLogError::MissingBlockNumber)?;
599+
let block_hash = maybe_block_hash.ok_or(FilterLogError::MissingBlockHash)?;
600+
let batch_index =
601+
decoded_log.batchIndex.uint_try_to().expect("u256 to u64 conversion error");
602+
let batch_hash = decoded_log.batchHash;
603+
Ok(L1Notification::BatchRevert {
604+
batch_info: BatchInfo { index: batch_index, hash: batch_hash },
605+
block_info: BlockInfo { number: block_number, hash: block_hash },
606+
})
607+
})
608+
.collect()
609+
}
610+
611+
/// Handle the batch revert range events.
612+
#[tracing::instrument(skip_all)]
613+
async fn handle_batch_revert_ranges(
614+
&self,
615+
logs: &[Log],
616+
) -> L1WatcherResult<Vec<L1Notification>> {
617+
// filter revert range logs.
618+
logs.iter()
619+
.map(|l| (l, l.block_number, l.block_hash))
620+
.filter_map(|(log, bn, bh)| {
621+
try_decode_log::<RevertBatch_1>(&log.inner).map(|decoded| (decoded.data, bn, bh))
622+
})
623+
.map(|(decoded_log, maybe_block_number, maybe_block_hash)| {
624+
// process the revert range log.
625+
let block_number = maybe_block_number.ok_or(FilterLogError::MissingBlockNumber)?;
626+
let block_hash = maybe_block_hash.ok_or(FilterLogError::MissingBlockHash)?;
627+
let start_index = decoded_log
628+
.startBatchIndex
629+
.uint_try_to()
630+
.expect("u256 to u64 conversion error");
631+
let end_index = decoded_log
632+
.finishBatchIndex
633+
.uint_try_to()
634+
.expect("u256 to u64 conversion error");
635+
Ok(L1Notification::BatchRevertRange {
636+
start: start_index,
637+
end: end_index,
638+
block_info: BlockInfo { number: block_number, hash: block_hash },
639+
})
640+
})
641+
.collect()
642+
}
643+
583644
/// Handles the finalize batch events.
584645
#[tracing::instrument(skip_all)]
585646
async fn handle_batch_finalization(
@@ -1048,6 +1109,62 @@ mod tests {
10481109
Ok(())
10491110
}
10501111

1112+
#[tokio::test]
1113+
async fn test_should_handle_batch_reverts() -> eyre::Result<()> {
1114+
// Given
1115+
let (finalized, latest, chain) = chain(10);
1116+
let (watcher, _) = l1_watcher(chain, vec![], vec![], finalized.clone(), latest.clone());
1117+
1118+
// build test logs.
1119+
let mut logs = (0..10).map(|_| random!(Log)).collect::<Vec<_>>();
1120+
let mut revert_batch = random!(Log);
1121+
let mut inner_log = random!(alloy_primitives::Log);
1122+
inner_log.data =
1123+
RevertBatch_0 { batchHash: random!(B256), batchIndex: U256::from(random!(u64)) }
1124+
.encode_log_data();
1125+
revert_batch.inner = inner_log;
1126+
revert_batch.block_number = Some(random!(u64));
1127+
revert_batch.block_hash = Some(random!(B256));
1128+
logs.push(revert_batch);
1129+
1130+
// When
1131+
let notification = watcher.handle_batch_reverts(&logs).await?.pop().unwrap();
1132+
1133+
// Then
1134+
assert!(matches!(notification, L1Notification::BatchRevert { .. }));
1135+
1136+
Ok(())
1137+
}
1138+
1139+
#[tokio::test]
1140+
async fn test_should_handle_batch_revert_range() -> eyre::Result<()> {
1141+
// Given
1142+
let (finalized, latest, chain) = chain(10);
1143+
let (watcher, _) = l1_watcher(chain, vec![], vec![], finalized.clone(), latest.clone());
1144+
1145+
// build test logs.
1146+
let mut logs = (0..10).map(|_| random!(Log)).collect::<Vec<_>>();
1147+
let mut revert_batch_range = random!(Log);
1148+
let mut inner_log = random!(alloy_primitives::Log);
1149+
inner_log.data = RevertBatch_1 {
1150+
startBatchIndex: U256::from(random!(u64)),
1151+
finishBatchIndex: U256::from(random!(u64)),
1152+
}
1153+
.encode_log_data();
1154+
revert_batch_range.inner = inner_log;
1155+
revert_batch_range.block_number = Some(random!(u64));
1156+
revert_batch_range.block_hash = Some(random!(B256));
1157+
logs.push(revert_batch_range);
1158+
1159+
// When
1160+
let notification = watcher.handle_batch_revert_ranges(&logs).await?.pop().unwrap();
1161+
1162+
// Then
1163+
assert!(matches!(notification, L1Notification::BatchRevertRange { .. }));
1164+
1165+
Ok(())
1166+
}
1167+
10511168
#[tokio::test]
10521169
async fn test_should_handle_finalize_commits() -> eyre::Result<()> {
10531170
// Given

0 commit comments

Comments
 (0)