Skip to content

Commit 1eb8f41

Browse files
committed
fix: l1 sync test && address some comments
1 parent a66cae7 commit 1eb8f41

File tree

3 files changed

+76
-51
lines changed

3 files changed

+76
-51
lines changed

crates/node/src/test_utils/fixture.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ impl TestFixture {
237237
Ok(())
238238
}
239239

240-
/// Send a raw transaction to Anvil.
241-
pub async fn anvil_send_raw_transaction(
240+
/// Inject a raw transaction to Anvil.
241+
pub async fn anvil_inject_tx(
242242
&self,
243243
raw_tx: impl Into<alloy_primitives::Bytes>,
244244
) -> eyre::Result<alloy_primitives::B256> {

crates/node/tests/l1_sync.rs

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ fn read_test_transaction(tx_type: &str, index: &str) -> eyre::Result<Bytes> {
7979
// Test Suite 1: Correct behavior when consuming events from L1
8080
// =============================================================================
8181

82-
/// Test: `BatchCommit` events during initial syncing should be buffered and processed after `L1Synced`.
82+
/// Test: `BatchCommit` events during initial syncing should be buffered and processed after
83+
/// `L1Synced`.
8384
///
8485
/// # Test Flow
8586
/// 1. Start a follower node in syncing state (skip automatic L1Synced notifications)
@@ -106,21 +107,23 @@ async fn test_l1_sync_batch_commit() -> eyre::Result<()> {
106107
.await?;
107108

108109
// Record initial state - should be at genesis
109-
let initial_status = fixture.get_sequencer_status().await?;
110+
let initial_status = fixture.get_status(0).await?;
110111
let initial_safe = initial_status.l2.fcs.safe_block_info().number;
112+
assert_eq!(initial_safe, 0, "Initial safe head should be at genesis (block 0)");
111113

112114
// Step 2: Send BatchCommit transactions to L1 while node is syncing
113115
// These commits contain L2 blocks that should eventually become the safe head
114116
for i in 0..=6 {
115117
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
116-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
118+
fixture.anvil_inject_tx(commit_batch_tx).await?;
117119
}
120+
// fixture.anvil_mine_blocks(1).await?;
118121

119122
// Allow time for L1 block processing
120123
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
121124

122125
// Step 3: Verify safe head hasn't moved - events should be buffered
123-
let status = fixture.get_sequencer_status().await?;
126+
let status = fixture.get_status(0).await?;
124127
assert_eq!(
125128
status.l2.fcs.safe_block_info().number,
126129
0,
@@ -130,10 +133,12 @@ async fn test_l1_sync_batch_commit() -> eyre::Result<()> {
130133
// Step 4: Trigger L1 sync completion
131134
fixture.l1().sync().await?;
132135
fixture.expect_event().l1_synced().await?;
133-
fixture.expect_event().batch_consolidated().await?;
136+
for _ in 1..=6 {
137+
fixture.expect_event().batch_consolidated().await?;
138+
}
134139

135140
// Step 5: Verify safe head advanced after processing buffered events
136-
let new_status = fixture.get_sequencer_status().await?;
141+
let new_status = fixture.get_status(0).await?;
137142
assert!(
138143
new_status.l2.fcs.safe_block_info().number > initial_safe,
139144
"Safe head should advance after L1Synced when processing buffered BatchCommit events"
@@ -154,10 +159,10 @@ async fn test_l1_sync_batch_commit() -> eyre::Result<()> {
154159
/// 7. Verify only finalized head advances (safe head already set by commits)
155160
///
156161
/// # Expected Behavior
157-
/// - Before `L1Synced`: `BatchFinalized` events update both safe and finalized heads
158-
/// because they imply the batches are committed and finalized on L1.
159-
/// - After `L1Synced`: `BatchFinalized` events only update the finalized head,
160-
/// as the safe head is already managed by `BatchCommit` events.
162+
/// - Before `L1Synced`: `BatchFinalized` events update both safe and finalized heads because they
163+
/// imply the batches are committed and finalized on L1.
164+
/// - After `L1Synced`: `BatchFinalized` events only update the finalized head, as the safe head is
165+
/// already managed by `BatchCommit` events.
161166
#[tokio::test]
162167
async fn test_l1_sync_batch_finalized() -> eyre::Result<()> {
163168
reth_tracing::init_test_tracing();
@@ -172,20 +177,25 @@ async fn test_l1_sync_batch_finalized() -> eyre::Result<()> {
172177
.await?;
173178

174179
// Record initial state
175-
let initial_status = fixture.get_sequencer_status().await?;
180+
let initial_status = fixture.get_status(0).await?;
176181
let initial_safe = initial_status.l2.fcs.safe_block_info().number;
177182
let initial_finalized = initial_status.l2.fcs.finalized_block_info().number;
183+
assert_eq!(
184+
(initial_safe, initial_finalized),
185+
(0, 0),
186+
"Initial safe and finalized heads should both be at genesis (block 0)"
187+
);
178188

179189
// Step 2: Send BatchCommit transactions (batches 0-6) to L1
180190
for i in 0..=6 {
181191
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
182-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
192+
fixture.anvil_inject_tx(commit_batch_tx).await?;
183193
}
184194

185195
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
186196

187197
// Step 3: Verify safe head hasn't changed (still syncing)
188-
let status = fixture.get_sequencer_status().await?;
198+
let status = fixture.get_status(0).await?;
189199
assert_eq!(
190200
status.l2.fcs.safe_block_info().number,
191201
0,
@@ -194,18 +204,21 @@ async fn test_l1_sync_batch_finalized() -> eyre::Result<()> {
194204

195205
// Step 4: Send BatchFinalized transactions (batches 1-3) while syncing
196206
// Mine 64 blocks to ensure the BatchFinalized events are themselves finalized on L1
207+
// This should trigger all unprocessed BatchCommit events up to the finalized batch
197208
for i in 1..=3 {
198209
let finalize_batch_tx = read_test_transaction("finalizeBatch", &i.to_string())?;
199-
fixture.anvil_send_raw_transaction(finalize_batch_tx).await?;
210+
fixture.anvil_inject_tx(finalize_batch_tx).await?;
200211
}
201212
fixture.anvil_mine_blocks(64).await?;
202213

203-
fixture.expect_event().batch_finalized().await?;
204-
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
214+
for _ in 1..=3 {
215+
// fixture.expect_event().batch_finalized().await?;
216+
fixture.expect_event().batch_consolidated().await?;
217+
}
205218

206219
// Step 5: Verify both safe and finalized heads advanced
207220
// During syncing, BatchFinalized implies the batch is both committed and finalized
208-
let batch_finalized_status = fixture.get_sequencer_status().await?;
221+
let batch_finalized_status = fixture.get_status(0).await?;
209222
assert!(
210223
batch_finalized_status.l2.fcs.safe_block_info().number > initial_safe,
211224
"Safe head should advance after BatchFinalized event during syncing"
@@ -215,24 +228,38 @@ async fn test_l1_sync_batch_finalized() -> eyre::Result<()> {
215228
"Finalized head should advance after BatchFinalized event"
216229
);
217230

218-
// Step 6: Complete L1 sync
231+
// Step 6: Complete L1 sync, this will process the buffered BatchCommit events
219232
fixture.l1().sync().await?;
220233
fixture.expect_event().l1_synced().await?;
221-
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
222-
223-
let l1_synced_status = fixture.get_sequencer_status().await?;
234+
for _ in 1..=3 {
235+
fixture.expect_event().batch_consolidated().await?;
236+
}
237+
let l1_synced_status = fixture.get_status(0).await?;
238+
assert!(
239+
batch_finalized_status.l2.fcs.safe_block_info().number <
240+
l1_synced_status.l2.fcs.safe_block_info().number,
241+
"Safe head should advance after L1 Synced when processing buffered BatchCommit events"
242+
);
224243

225244
// Step 7: Send more BatchFinalized transactions (batches 4-6) after L1Synced
226245
for i in 4..=6 {
227246
let finalize_batch_tx = read_test_transaction("finalizeBatch", &i.to_string())?;
228-
fixture.anvil_send_raw_transaction(finalize_batch_tx).await?;
247+
fixture.anvil_inject_tx(finalize_batch_tx).await?;
229248
}
230-
fixture.anvil_mine_blocks(64).await?;
249+
let batch_finalized_status = fixture.get_status(0).await?;
250+
assert_eq!(
251+
batch_finalized_status.l2.fcs.finalized_block_info().number,
252+
l1_synced_status.l2.fcs.finalized_block_info().number,
253+
"Finalized head should not advance before BatchFinalized event are finalized on L1"
254+
);
231255

232-
fixture.expect_event().batch_finalized().await?;
256+
fixture.anvil_mine_blocks(64).await?;
257+
for _ in 1..=3 {
258+
fixture.expect_event().batch_finalized().await?;
259+
}
233260

234261
// Step 8: Verify only finalized head advanced (safe head managed by BatchCommit)
235-
let batch_finalized_status = fixture.get_sequencer_status().await?;
262+
let batch_finalized_status = fixture.get_status(0).await?;
236263
assert!(
237264
batch_finalized_status.l2.fcs.safe_block_info().number ==
238265
l1_synced_status.l2.fcs.safe_block_info().number,
@@ -274,13 +301,14 @@ async fn test_l1_sync_batch_revert() -> eyre::Result<()> {
274301
.await?;
275302

276303
// Record initial state
277-
let initial_status = fixture.get_sequencer_status().await?;
304+
let initial_status = fixture.get_status(0).await?;
278305
let initial_safe = initial_status.l2.fcs.safe_block_info().number;
306+
assert_eq!(initial_safe, 0, "Initial safe head should be at genesis (block 0)");
279307

280308
// Step 2: Send BatchCommit transactions (batches 0-6) to L1
281309
for i in 0..=6 {
282310
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
283-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
311+
fixture.anvil_inject_tx(commit_batch_tx).await?;
284312
}
285313

286314
// Mine blocks to ensure commits are included
@@ -292,21 +320,21 @@ async fn test_l1_sync_batch_revert() -> eyre::Result<()> {
292320
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
293321

294322
// Verify safe head advanced after processing commits
295-
let new_status = fixture.get_sequencer_status().await?;
323+
let new_status = fixture.get_status(0).await?;
296324
assert!(
297325
new_status.l2.fcs.safe_block_info().number > initial_safe,
298326
"Safe head should advance after BatchCommit when L1Synced"
299327
);
300328

301329
// Step 4: Send BatchRevert transaction to revert some batches
302330
let revert_batch_tx = read_test_transaction("revertBatch", "0")?;
303-
fixture.anvil_send_raw_transaction(revert_batch_tx).await?;
331+
fixture.anvil_inject_tx(revert_batch_tx).await?;
304332
fixture.anvil_mine_blocks(10).await?;
305333

306334
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
307335

308336
// Step 5: Verify safe head decreased after revert
309-
let revert_status = fixture.get_sequencer_status().await?;
337+
let revert_status = fixture.get_status(0).await?;
310338
assert!(
311339
revert_status.l2.fcs.safe_block_info().number < new_status.l2.fcs.safe_block_info().number,
312340
"Safe head should decrease after BatchRevert to reflect rolled-back state"
@@ -355,27 +383,27 @@ async fn test_l1_reorg_batch_commit() -> eyre::Result<()> {
355383
// Step 2: Send first batch of commits (batches 0-3)
356384
for i in 0..=3 {
357385
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
358-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
386+
fixture.anvil_inject_tx(commit_batch_tx).await?;
359387
if i != 0 {
360388
fixture.expect_event().batch_consolidated().await?;
361389
}
362390
}
363391

364392
// Record safe head after batch 3
365-
let status_after_batch_3 = fixture.get_sequencer_status().await?;
393+
let status_after_batch_3 = fixture.get_status(0).await?;
366394
let safe_after_batch_3 = status_after_batch_3.l2.fcs.safe_block_info().number;
367395
tracing::info!("Safe head after batch 3: {}", safe_after_batch_3);
368396

369397
// Step 3: Send more commits (batches 4-6) to advance safe head
370398
for i in 4..=6 {
371399
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
372-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
400+
fixture.anvil_inject_tx(commit_batch_tx).await?;
373401
}
374402

375403
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
376404

377405
// Record advanced safe head after batch 6
378-
let status_after_batch_6 = fixture.get_sequencer_status().await?;
406+
let status_after_batch_6 = fixture.get_status(0).await?;
379407
let safe_after_batch_6 = status_after_batch_6.l2.fcs.safe_block_info().number;
380408
tracing::info!("Safe head after batch 6: {}", safe_after_batch_6);
381409
assert!(
@@ -391,7 +419,7 @@ async fn test_l1_reorg_batch_commit() -> eyre::Result<()> {
391419
fixture.expect_event().l1_reorg().await?;
392420

393421
// Step 5: Verify safe head reverted to state after batch 3
394-
let status_after_reorg = fixture.get_sequencer_status().await?;
422+
let status_after_reorg = fixture.get_status(0).await?;
395423
let safe_after_reorg = status_after_reorg.l2.fcs.safe_block_info().number;
396424
tracing::info!("Safe head after reorg: {}", safe_after_reorg);
397425
assert_eq!(
@@ -437,13 +465,13 @@ async fn test_l1_reorg_batch_finalized() -> eyre::Result<()> {
437465
// Step 2: Send BatchCommit transactions (batches 0-6)
438466
for i in 0..=6 {
439467
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
440-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
468+
fixture.anvil_inject_tx(commit_batch_tx).await?;
441469
}
442470

443471
// Step 3: Send BatchFinalized transactions (batches 1-2)
444472
for i in 1..=2 {
445473
let finalize_batch_tx = read_test_transaction("finalizeBatch", &i.to_string())?;
446-
fixture.anvil_send_raw_transaction(finalize_batch_tx).await?;
474+
fixture.anvil_inject_tx(finalize_batch_tx).await?;
447475
}
448476

449477
// Step 4: Complete L1 sync
@@ -455,7 +483,7 @@ async fn test_l1_reorg_batch_finalized() -> eyre::Result<()> {
455483
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
456484

457485
// Record finalized head after finalization
458-
let status_after_finalize = fixture.get_sequencer_status().await?;
486+
let status_after_finalize = fixture.get_status(0).await?;
459487
let finalized_after = status_after_finalize.l2.fcs.finalized_block_info().number;
460488
tracing::info!("Finalized head after batch finalized: {}", finalized_after);
461489

@@ -467,7 +495,7 @@ async fn test_l1_reorg_batch_finalized() -> eyre::Result<()> {
467495
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
468496

469497
// Step 6: Verify finalized head hasn't changed (reorg has no effect)
470-
let status_after_reorg = fixture.get_sequencer_status().await?;
498+
let status_after_reorg = fixture.get_status(0).await?;
471499
let finalized_after_reorg = status_after_reorg.l2.fcs.finalized_block_info().number;
472500
tracing::info!("Finalized head after reorg: {}", finalized_after_reorg);
473501
assert_eq!(
@@ -520,31 +548,28 @@ async fn test_l1_reorg_batch_revert() -> eyre::Result<()> {
520548
// Step 2: Send BatchCommit transactions (batches 0-6)
521549
for i in 0..=6 {
522550
let commit_batch_tx = read_test_transaction("commitBatch", &i.to_string())?;
523-
fixture.anvil_send_raw_transaction(commit_batch_tx).await?;
551+
fixture.anvil_inject_tx(commit_batch_tx).await?;
524552
}
525553

526554
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
527555

528556
// Record safe head after all commits are processed
529-
let status_after_commits = fixture.get_sequencer_status().await?;
557+
let status_after_commits = fixture.get_status(0).await?;
530558
let safe_after_commits = status_after_commits.l2.fcs.safe_block_info().number;
531559
tracing::info!("Safe head after all commits: {}", safe_after_commits);
532560

533561
// Step 3: Send BatchRevert transaction to roll back some batches
534562
let revert_batch_tx = read_test_transaction("revertBatch", "0")?;
535-
fixture.anvil_send_raw_transaction(revert_batch_tx).await?;
563+
fixture.anvil_inject_tx(revert_batch_tx).await?;
536564
fixture.anvil_mine_blocks(1).await?;
537565

538566
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
539567

540568
// Step 4: Verify safe head decreased after revert
541-
let status_after_revert = fixture.get_sequencer_status().await?;
569+
let status_after_revert = fixture.get_status(0).await?;
542570
let safe_after_revert = status_after_revert.l2.fcs.safe_block_info().number;
543571
tracing::info!("Safe head after revert: {}", safe_after_revert);
544-
assert!(
545-
safe_after_revert < safe_after_commits,
546-
"Safe head should decrease after BatchRevert"
547-
);
572+
assert!(safe_after_revert < safe_after_commits, "Safe head should decrease after BatchRevert");
548573

549574
// Step 5: Perform L1 reorg to remove the BatchRevert event (reorg depth 2)
550575
fixture.anvil_reorg(2).await?;
@@ -554,7 +579,7 @@ async fn test_l1_reorg_batch_revert() -> eyre::Result<()> {
554579

555580
// Step 6: Verify safe head restored to pre-revert state
556581
// The batches are no longer reverted, so safe head should be back to full height
557-
let status_after_reorg = fixture.get_sequencer_status().await?;
582+
let status_after_reorg = fixture.get_status(0).await?;
558583
let safe_after_reorg = status_after_reorg.l2.fcs.safe_block_info().number;
559584
tracing::info!("Safe head after reorg: {}", safe_after_reorg);
560585
assert_eq!(

0 commit comments

Comments
 (0)