|
1 | 1 | use std::sync::Arc; |
2 | 2 |
|
| 3 | +use alloy::primitives::U256; |
| 4 | +use apollo_base_layer_tests::anvil_base_layer::AnvilBaseLayer; |
3 | 5 | use apollo_batcher_types::communication::MockBatcherClient; |
4 | 6 | use apollo_infra::component_client::LocalComponentClient; |
5 | | -use apollo_infra::component_definitions::RequestWrapper; |
6 | | -use apollo_infra::component_server::{LocalComponentServer, LocalServerConfig}; |
| 7 | +use apollo_infra::component_definitions::{ComponentStarter, RequestWrapper}; |
| 8 | +use apollo_infra::component_server::{ |
| 9 | + ComponentServerStarter, |
| 10 | + LocalComponentServer, |
| 11 | + LocalServerConfig, |
| 12 | +}; |
7 | 13 | use apollo_l1_provider::l1_provider::L1ProviderBuilder; |
8 | 14 | use apollo_l1_provider::l1_scraper::L1Scraper; |
9 | 15 | use apollo_l1_provider::metrics::L1_PROVIDER_INFRA_METRICS; |
10 | | -use apollo_l1_provider::L1ProviderConfig; |
11 | | -use apollo_l1_provider_types::{L1ProviderRequest, L1ProviderResponse, MockL1ProviderClient}; |
| 16 | +use apollo_l1_provider::{event_identifiers_to_track, L1ProviderConfig}; |
| 17 | +use apollo_l1_provider_types::{L1ProviderRequest, L1ProviderResponse}; |
12 | 18 | use apollo_l1_scraper_config::config::L1ScraperConfig; |
13 | 19 | use apollo_state_sync_types::communication::MockStateSyncClient; |
14 | | -use papyrus_base_layer::{L1BlockReference, MockBaseLayerContract}; |
15 | | -use starknet_api::block::{BlockHashAndNumber, BlockNumber}; |
| 20 | +use apollo_state_sync_types::state_sync_types::SyncBlock; |
| 21 | +use papyrus_base_layer::test_utils::anvil_mine_blocks; |
| 22 | +use papyrus_base_layer::{BaseLayerContract, L1BlockNumber, L1BlockReference}; |
| 23 | +use starknet_api::block::{BlockNumber, BlockTimestamp}; |
| 24 | +use starknet_api::core::ChainId; |
16 | 25 | use tokio::sync::mpsc::channel; |
17 | 26 |
|
18 | 27 | #[tokio::test] |
19 | 28 | async fn flow_tests() { |
20 | 29 | // Setup. |
21 | | - let start_block = L1BlockReference::default(); |
22 | | - let historical_block = BlockHashAndNumber::default(); |
| 30 | + const NUMBER_OF_BLOCKS_TO_MINE: u64 = 100; |
| 31 | + let chain_id = ChainId::Mainnet; |
| 32 | + let start_l1_block = L1BlockReference::default(); |
| 33 | + let start_l1_block_number: L1BlockNumber = start_l1_block.number; |
| 34 | + let start_l2_height = BlockNumber(0); |
| 35 | + let target_l2_height = BlockNumber(1); |
23 | 36 |
|
24 | | - // Setup the base layer. |
25 | | - let mut base_layer = MockBaseLayerContract::default(); // TODO(guyn): replace this with Anvil. |
26 | | - base_layer.expect_latest_l1_block().returning(move |_| Ok(Some(start_block))); |
27 | | - base_layer.expect_latest_proved_block().returning(move |_| Ok(Some(historical_block))); |
| 37 | + // Setup the state sync client. |
| 38 | + let mut state_sync_client = MockStateSyncClient::default(); |
| 39 | + state_sync_client.expect_get_block().returning(move |_| Ok(SyncBlock::default())); |
28 | 40 |
|
29 | | - // L1 provider setup. |
30 | | - let mut l1_provider = L1ProviderBuilder::new( |
31 | | - L1ProviderConfig::default(), |
32 | | - Arc::new(MockL1ProviderClient::default()), // This isn't right |
33 | | - Arc::new(MockBatcherClient::default()), // Consider saving a copy of this to interact |
34 | | - Arc::new(MockStateSyncClient::default()), /* We'll need a copy of this if we do |
35 | | - * bootstrapping */ |
| 41 | + // Setup the base layer. |
| 42 | + let base_layer = AnvilBaseLayer::new(None).await; |
| 43 | + let contract = &base_layer.ethereum_base_layer.contract; |
| 44 | + anvil_mine_blocks( |
| 45 | + base_layer.ethereum_base_layer.config.clone(), |
| 46 | + NUMBER_OF_BLOCKS_TO_MINE, |
| 47 | + &base_layer.ethereum_base_layer.get_url().await.expect("Failed to get anvil url."), |
36 | 48 | ) |
37 | | - .startup_height(BlockNumber(start_block.number)) |
38 | | - .catchup_height(historical_block.number) |
39 | | - .build(); |
| 49 | + .await; |
| 50 | + |
| 51 | + // Send message from L1 to L2. |
| 52 | + let l2_contract_address = "0x12"; |
| 53 | + let l2_entry_point = "0x34"; |
| 54 | + let call_data = vec![U256::from(1_u8), U256::from(2_u8)]; |
| 55 | + let fee = 1_u8; |
| 56 | + let message_to_l2 = contract |
| 57 | + .sendMessageToL2( |
| 58 | + l2_contract_address.parse().unwrap(), |
| 59 | + l2_entry_point.parse().unwrap(), |
| 60 | + call_data, |
| 61 | + ) |
| 62 | + .value(U256::from(fee)); |
| 63 | + message_to_l2.call().await.unwrap(); // Query for errors. |
| 64 | + let receipt = message_to_l2.send().await.unwrap().get_receipt().await.unwrap(); |
| 65 | + let message_timestamp = base_layer |
| 66 | + .get_block_header(receipt.block_number.unwrap()) |
| 67 | + .await |
| 68 | + .unwrap() |
| 69 | + .unwrap() |
| 70 | + .timestamp; |
| 71 | + assert!(message_timestamp > BlockTimestamp(0)); |
| 72 | + |
| 73 | + // Make sure the L1 event was posted to Anvil |
| 74 | + let finality = 0; |
| 75 | + let last_l1_block_number = |
| 76 | + base_layer.ethereum_base_layer.latest_l1_block_number(finality).await.unwrap(); |
| 77 | + assert!(last_l1_block_number > start_l1_block_number + NUMBER_OF_BLOCKS_TO_MINE); |
| 78 | + let event_filter = event_identifiers_to_track(); |
| 79 | + let events = base_layer |
| 80 | + .ethereum_base_layer |
| 81 | + .events( |
| 82 | + // Include last block with message. |
| 83 | + start_l1_block_number..=last_l1_block_number + 1, |
| 84 | + event_filter, |
| 85 | + ) |
| 86 | + .await |
| 87 | + .unwrap(); |
| 88 | + assert!(events.len() == 1); |
40 | 89 |
|
| 90 | + // Set up the L1 provider client and server. |
41 | 91 | // This channel connects the L1Provider client to the server. |
42 | 92 | let (tx, rx) = channel::<RequestWrapper<L1ProviderRequest, L1ProviderResponse>>(32); |
43 | 93 |
|
44 | | - // Create the client. |
| 94 | + // Create the provider client. |
45 | 95 | let l1_provider_client = |
46 | 96 | LocalComponentClient::new(tx, L1_PROVIDER_INFRA_METRICS.get_local_client_metrics()); |
47 | 97 |
|
| 98 | + // L1 provider setup. |
| 99 | + let l1_provider = L1ProviderBuilder::new( |
| 100 | + L1ProviderConfig::default(), |
| 101 | + Arc::new(l1_provider_client.clone()), |
| 102 | + Arc::new(MockBatcherClient::default()), // Consider saving a copy of this to interact |
| 103 | + Arc::new(state_sync_client), |
| 104 | + ) |
| 105 | + .startup_height(start_l2_height) |
| 106 | + .catchup_height(target_l2_height) |
| 107 | + .build(); |
| 108 | + |
48 | 109 | // Create the server. |
49 | | - l1_provider.initialize(vec![]).await.unwrap(); |
50 | | - let _l1_provider_server = LocalComponentServer::new( |
| 110 | + let mut l1_provider_server = LocalComponentServer::new( |
51 | 111 | l1_provider, |
52 | 112 | &LocalServerConfig::default(), |
53 | 113 | rx, |
54 | 114 | L1_PROVIDER_INFRA_METRICS.get_local_server_metrics(), |
55 | 115 | ); |
| 116 | + // Start the server: |
| 117 | + tokio::spawn(async move { |
| 118 | + l1_provider_server.start().await; |
| 119 | + }); |
56 | 120 |
|
57 | | - // Setup the scraper. |
| 121 | + // Set up the L1 scraper and run it as a server. |
| 122 | + let l1_scraper_config = L1ScraperConfig { chain_id, ..Default::default() }; |
58 | 123 | let mut scraper = L1Scraper::new( |
59 | | - L1ScraperConfig::default(), |
| 124 | + l1_scraper_config, |
60 | 125 | Arc::new(l1_provider_client.clone()), |
61 | 126 | base_layer, |
62 | 127 | &[], |
63 | | - start_block, |
| 128 | + start_l1_block, |
64 | 129 | ) |
65 | 130 | .await |
66 | 131 | .expect("Should be able to create the scraper"); |
67 | 132 |
|
68 | 133 | // Run the scraper in a separate task. |
69 | | - let _scraper_task = tokio::spawn(async move { |
70 | | - scraper.run().await.unwrap_or_else(|e| panic!("Error running scraper: {e:?}")); |
| 134 | + tokio::spawn(async move { |
| 135 | + scraper.start().await; |
71 | 136 | }); |
| 137 | + // TODO(guyn): add the actual test here. |
72 | 138 | } |
0 commit comments