|
| 1 | +use eyre::Result; |
| 2 | +use tests::*; |
| 3 | + |
| 4 | +/// |
| 5 | +/// This integration test validates that blocks can be successfully propagated between |
| 6 | +/// different Ethereum client implementations (l2geth and rollup-node) in various |
| 7 | +/// network topologies. The test exercises: |
| 8 | +/// |
| 9 | +/// 1. **Isolated Network Segments**: Initially runs l2geth nodes in isolation, verifying they can |
| 10 | +/// produce and sync blocks independently |
| 11 | +/// - Topology: `l2geth_follower -> l2geth_sequencer` |
| 12 | +/// - l2geth_sequencer produces blocks, l2geth_follower syncs |
| 13 | +/// - Rollup nodes remain disconnected at block 0 |
| 14 | +/// |
| 15 | +/// 2. **Cross-Client Synchronization**: Connects rollup nodes to the l2geth network, ensuring they |
| 16 | +/// can catch up to the current chain state |
| 17 | +/// - Topology: `[rn_follower, rn_sequencer, l2geth_follower] -> l2geth_sequencer` |
| 18 | +/// - All nodes connect to l2geth_sequencer as the single source of truth |
| 19 | +/// - Rollup nodes sync from block 0 to current height |
| 20 | +/// |
| 21 | +/// 3. **Sequencer Handoff**: Transitions block production from l2geth to rollup-node, testing that |
| 22 | +/// all nodes stay synchronized during the transition |
| 23 | +/// - Topology remains: `[rn_follower, rn_sequencer, l2geth_follower] -> l2geth_sequencer` |
| 24 | +/// - Block production switches from l2geth_sequencer to rn_sequencer |
| 25 | +/// - All nodes receive new blocks from rn_sequencer via l2geth_sequencer relay |
| 26 | +/// |
| 27 | +/// 4. **Network Partition Recovery**: Disconnects l2geth nodes, continues production on rollup |
| 28 | +/// nodes, then reconnects to verify successful resynchronization |
| 29 | +/// - Initial partition: `rn_follower -> rn_sequencer` (isolated rollup network) |
| 30 | +/// - l2geth nodes disconnected, fall behind in block height |
| 31 | +/// - Reconnection topology: `[l2geth_follower, l2geth_sequencer] -> rn_sequencer` |
| 32 | +/// - l2geth nodes catch up by syncing from rn_sequencer |
| 33 | +/// |
| 34 | +/// 5. **Bidirectional Compatibility**: Returns block production to l2geth after rollup nodes have |
| 35 | +/// extended the chain, ensuring backward compatibility |
| 36 | +/// - Final topology: `[rn_follower, l2geth_follower, l2geth_sequencer] -> rn_sequencer` |
| 37 | +/// - Block production returns to l2geth_sequencer |
| 38 | +/// - Validates that l2geth can continue the chain after rollup node blocks |
| 39 | +/// |
| 40 | +/// The test validates that both client implementations maintain consensus despite |
| 41 | +/// network topology changes, sequencer transitions, and temporary network partitions. |
| 42 | +/// Each topology change tests different aspects of peer discovery, block gossip, |
| 43 | +/// and chain synchronization across heterogeneous client implementations. |
| 44 | +#[tokio::test] |
| 45 | +async fn docker_test_migrate_sequencer() -> Result<()> { |
| 46 | + reth_tracing::init_test_tracing(); |
| 47 | + |
| 48 | + tracing::info!("=== STARTING docker_test_migrate_sequencer ==="); |
| 49 | + let env = DockerComposeEnv::new("docker_test_migrate_sequencer").await?; |
| 50 | + |
| 51 | + let rn_sequencer = env.get_rn_sequencer_provider().await?; |
| 52 | + let rn_follower = env.get_rn_follower_provider().await?; |
| 53 | + let l2geth_sequencer = env.get_l2geth_sequencer_provider().await?; |
| 54 | + let l2geth_follower = env.get_l2geth_follower_provider().await?; |
| 55 | + |
| 56 | + let nodes = [&rn_sequencer, &rn_follower, &l2geth_sequencer, &l2geth_follower]; |
| 57 | + |
| 58 | + // Connect all nodes to each other. |
| 59 | + // topology: |
| 60 | + // l2geth_follower -> l2geth_sequencer |
| 61 | + // l2geth_follower -> rn_sequencer |
| 62 | + // rn_follower -> l2geth_sequencer |
| 63 | + // rn_follower -> rn_sequencer |
| 64 | + // rn_sequencer -> l2geth_sequencer |
| 65 | + utils::admin_add_peer(&l2geth_follower, &env.l2geth_sequencer_enode()?).await?; |
| 66 | + utils::admin_add_peer(&l2geth_follower, &env.rn_sequencer_enode()?).await?; |
| 67 | + utils::admin_add_peer(&rn_follower, &env.l2geth_sequencer_enode()?).await?; |
| 68 | + utils::admin_add_peer(&rn_follower, &env.rn_sequencer_enode()?).await?; |
| 69 | + utils::admin_add_peer(&rn_sequencer, &env.l2geth_sequencer_enode()?).await?; |
| 70 | + |
| 71 | + // Enable block production on l2geth sequencer |
| 72 | + utils::miner_start(&l2geth_sequencer).await?; |
| 73 | + |
| 74 | + // Wait for at least 60 blocks to be produced |
| 75 | + let target_block = 30; |
| 76 | + utils::wait_for_block(&[&l2geth_sequencer], target_block).await?; |
| 77 | + |
| 78 | + let target_block = 60; |
| 79 | + utils::wait_for_block(&nodes, target_block).await?; |
| 80 | + utils::assert_blocks_match(&nodes, target_block).await?; |
| 81 | + |
| 82 | + let target_block = 90; |
| 83 | + utils::wait_for_block(&nodes, target_block).await?; |
| 84 | + utils::assert_blocks_match(&nodes, target_block).await?; |
| 85 | + |
| 86 | + let target_block = 120; |
| 87 | + utils::wait_for_block(&nodes, target_block).await?; |
| 88 | + utils::assert_blocks_match(&nodes, target_block).await?; |
| 89 | + |
| 90 | + Ok(()) |
| 91 | +} |
0 commit comments