@@ -1814,104 +1814,38 @@ async fn signer_rotation() -> eyre::Result<()> {
18141814
18151815// Test that the chain orchestrator detects gaps in batch commits, triggers a reset command to the
18161816// L1 watcher for self-healing and skips duplicate batch commits.
1817- // #[tokio::test]
1818- // async fn test_batch_commit_gap() -> eyre::Result<()> {
1819- // reth_tracing::init_test_tracing();
1820- //
1821- // let (mut nodes, _tasks, _wallet) = setup_engine(
1822- // default_test_scroll_rollup_node_config(),
1823- // 1,
1824- // (*SCROLL_DEV).clone(),
1825- // false,
1826- // false,
1827- // )
1828- // .await?;
1829- // let node = nodes.pop().unwrap();
1830- //
1831- // // Get handles for sending L1 notifications and receiving commands
1832- // let l1_watcher_tx = node.inner.add_ons_handle.l1_watcher_tx.clone().unwrap();
1833- // let l1_watcher_command_rx = node.inner.add_ons_handle.l1_watcher_command_rx.clone();
1834- // let chain_orchestrator = node.inner.add_ons_handle.rollup_manager_handle.clone();
1835- //
1836- // // Get event listener to monitor chain orchestrator events
1837- // let mut events = chain_orchestrator.get_event_listener().await?;
1838- //
1839- // // Node is unsynced initially -> does not derive batches (which is what we want)
1840- //
1841- // // Send batch commit 1 to populate the database
1842- // let batch_commit_1 =
1843- // BatchCommitData { hash: B256::random(), index: 1, block_number: 1, ..Default::default()
1844- // };
1845- //
1846- // l1_watcher_tx
1847- // .send(Arc::new(L1Notification::BatchCommit {
1848- // block_info: BlockInfo { number: batch_commit_1.block_number, hash: B256::random() },
1849- // data: batch_commit_1.clone(),
1850- // }))
1851- // .await?;
1852- // wait_for_event_5s(
1853- // &mut events,
1854- // ChainOrchestratorEvent::BatchCommitIndexed {
1855- // batch_info: BatchInfo { index: batch_commit_1.index, hash: batch_commit_1.hash },
1856- // l1_block_number: batch_commit_1.block_number,
1857- // },
1858- // )
1859- // .await?;
1860- //
1861- // // Send duplicate batch commit 1 - should be skipped and duplicate detected
1862- // l1_watcher_tx
1863- // .send(Arc::new(L1Notification::BatchCommit {
1864- // block_info: BlockInfo { number: batch_commit_1.block_number, hash: B256::random() },
1865- // data: batch_commit_1.clone(),
1866- // }))
1867- // .await?;
1868- // wait_for_event_5s(
1869- // &mut events,
1870- // ChainOrchestratorEvent::BatchCommitDuplicate(batch_commit_1.index),
1871- // )
1872- // .await?;
1873- //
1874- // // Send batch commit 3 - should trigger reset due to gap (missing batch 2)
1875- // let batch_commit_3 = BatchCommitData {
1876- // hash: B256::random(),
1877- // index: 3, // Gap! Missing index 2
1878- // block_number: 3,
1879- // ..Default::default()
1880- // };
1881- //
1882- // l1_watcher_tx
1883- // .send(Arc::new(L1Notification::BatchCommit {
1884- // block_info: BlockInfo { number: batch_commit_3.block_number, hash: B256::random() },
1885- // data: batch_commit_3.clone(),
1886- // }))
1887- // .await?;
1888- // wait_for_event_5s(
1889- // &mut events,
1890- // ChainOrchestratorEvent::BatchCommitGap {
1891- // missing_index: batch_commit_3.index,
1892- // l1_block_number_reset: batch_commit_1.block_number,
1893- // },
1894- // )
1895- // .await?;
1896- //
1897- // let mut command_rx = l1_watcher_command_rx.lock().await;
1898- // let command = tokio::time::timeout(Duration::from_secs(5), command_rx.recv())
1899- // .await
1900- // .expect("should receive command within timeout")
1901- // .expect("should receive Some(command)");
1902- //
1903- // // Verify it's a ResetToBlock command with the correct block number
1904- // match command {
1905- // L1WatcherCommand::ResetToBlock { block, .. } => {
1906- // assert_eq!(
1907- // block, batch_commit_1.block_number,
1908- // "Reset block should be the L1 block of the last known batch"
1909- // );
1910- // }
1911- // }
1912- //
1913- // Ok(())
1914- // }
1817+ #[ tokio:: test]
1818+ async fn test_batch_commit_gap ( ) -> eyre:: Result < ( ) > {
1819+ reth_tracing:: init_test_tracing ( ) ;
1820+
1821+ let mut fixture = TestFixture :: builder ( ) . sequencer ( ) . build ( ) . await ?;
1822+
1823+ // Node is unsynced initially -> does not derive batches (which is what we want)
1824+
1825+ let batch_1_hash = B256 :: random ( ) ;
1826+ // Send batch commit 1 to populate the database
1827+ fixture. l1 ( ) . commit_batch ( ) . hash ( batch_1_hash) . index ( 1 ) . block_number ( 1 ) . send ( ) . await ?;
1828+ fixture. expect_event ( ) . batch_commit_indexed ( 1 , 1 ) . await ?;
1829+
1830+ // Send duplicate batch commit 1 - should be skipped and duplicate detected
1831+ fixture. l1 ( ) . commit_batch ( ) . hash ( batch_1_hash) . index ( 1 ) . block_number ( 1 ) . send ( ) . await ?;
1832+ fixture. expect_event ( ) . batch_commit_duplicates ( 1 ) . await ?;
1833+
1834+ // Send batch commit 3 - should trigger reset due to gap (missing batch 2)
1835+ fixture. l1 ( ) . commit_batch ( ) . index ( 3 ) . block_number ( 3 ) . send ( ) . await ?;
1836+ // Expect gap event: missing index 3, reset to L1 block 1 (where batch 1 was committed)
1837+ fixture. expect_event ( ) . batch_commit_gap ( 3 , 1 ) . await ?;
1838+
1839+ // Verify that a ResetToBlock command was sent to the L1 watcher
1840+ let command = fixture. expect_l1_watcher_command ( ) . await ?;
1841+ match command {
1842+ rollup_node_watcher:: L1WatcherCommand :: ResetToBlock { block, .. } => {
1843+ assert_eq ! ( block, 1 , "Reset block should be the L1 block of the last known batch" ) ;
1844+ }
1845+ }
1846+
1847+ Ok ( ( ) )
1848+ }
19151849
19161850// Test that the chain orchestrator detects gaps in L1 messages, triggers a reset command to the
19171851// L1 watcher for self-healing and skips duplicate L1 messages received.
0 commit comments