diff --git a/Cargo.lock b/Cargo.lock index d3eb617cdc8..3f04d21ef62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -866,11 +866,13 @@ version = "0.0.0" dependencies = [ "alloy", "apollo_config", + "apollo_infra_utils", "async-trait", "colored 3.0.0", "papyrus_base_layer", "starknet_api", "tokio", + "tracing", "url", ] diff --git a/crates/apollo_base_layer_tests/Cargo.toml b/crates/apollo_base_layer_tests/Cargo.toml index 6b4f9784614..8f5ea914571 100644 --- a/crates/apollo_base_layer_tests/Cargo.toml +++ b/crates/apollo_base_layer_tests/Cargo.toml @@ -19,6 +19,8 @@ colored.workspace = true papyrus_base_layer = { workspace = true, features = ["testing"] } starknet_api.workspace = true tokio.workspace = true +tracing.workspace = true url.workspace = true [dev-dependencies] +apollo_infra_utils.workspace = true diff --git a/crates/apollo_base_layer_tests/src/anvil_base_layer.rs b/crates/apollo_base_layer_tests/src/anvil_base_layer.rs index b34fb6fcfa4..4c47ac60c16 100644 --- a/crates/apollo_base_layer_tests/src/anvil_base_layer.rs +++ b/crates/apollo_base_layer_tests/src/anvil_base_layer.rs @@ -1,5 +1,6 @@ use std::ops::RangeInclusive; use std::process::Command; +use std::time::Duration; use alloy::node_bindings::NodeError as AnvilError; use alloy::primitives::{I256, U256}; @@ -28,6 +29,7 @@ use papyrus_base_layer::{ use starknet_api::block::BlockHashAndNumber; use starknet_api::hash::StarkHash; use starknet_api::transaction::L1HandlerTransaction; +use tracing::info; use url::Url; /// Initialize an anvil instance under the default port and deploy the Starknet contract. @@ -96,8 +98,22 @@ curl -L \ _ => panic!("Failed to spawn Anvil: {}", error.to_string().red()), }); - Starknet::deploy(anvil_client.clone()).await.unwrap(); - + info!("Deploying Starknet contract to Anvil with port: {}", port); + let mut retries = 0; + for _ in 0..100 { + let result = Starknet::deploy(anvil_client.clone()).await; + if result.is_ok() { + break; + } + retries += 1; + tokio::time::sleep(Duration::from_millis(10)).await; + } + Starknet::deploy(anvil_client.clone()).await.unwrap_or_else(|error| { + panic!( + "Failed to deploy Starknet contract to Anvil on port {port} after {retries} \ + retries: {error:?}" + ); + }); let config = Self::config(Self::url_static(port)); let url_iterator = CircularUrlIterator::new(config.ordered_l1_endpoint_urls.clone()); let root_client = anvil_client.root().clone(); diff --git a/crates/apollo_base_layer_tests/tests/anvil_starts_with_no_contract.rs b/crates/apollo_base_layer_tests/tests/anvil_starts_with_no_contract.rs index 3d177d637b0..ac183100ca0 100644 --- a/crates/apollo_base_layer_tests/tests/anvil_starts_with_no_contract.rs +++ b/crates/apollo_base_layer_tests/tests/anvil_starts_with_no_contract.rs @@ -1,4 +1,5 @@ use alloy::node_bindings::Anvil; +use apollo_infra_utils::test_utils::{AvailablePortsGenerator, TestIdentifier}; use papyrus_base_layer::ethereum_base_layer_contract::{ EthereumBaseLayerConfig, EthereumBaseLayerContract, @@ -10,14 +11,20 @@ use papyrus_base_layer::test_utils::{ OTHER_ARBITRARY_ANVIL_L1_ACCOUNT_ADDRESS, }; use papyrus_base_layer::BaseLayerContract; +use tracing::info; #[tokio::test] async fn anvil_starts_with_no_contract() { const NUM_L1_TRANSACTIONS: usize = 10; - // TODO(GuyNir/Shahak): avoid this hard-coded port number, and align port usages throughout the - // anvil instances. + let mut ports_gen = + AvailablePortsGenerator::new(TestIdentifier::AnvilStartsWithNoContractTest.into()); + let mut available_ports = ports_gen + .next() + .expect("Failed to get an AvailablePorts instance for anvil_starts_with_no_contract"); + let port = available_ports.get_next_port(); + info!("Starting Anvil with port: {}", port); let anvil = Anvil::new() - .port(9999_u16) + .port(port) .try_spawn() .expect("Anvil not installed, see anvil base layer for installation instructions."); let base_layer_config = EthereumBaseLayerConfig { diff --git a/crates/apollo_infra_utils/src/test_utils.rs b/crates/apollo_infra_utils/src/test_utils.rs index 451ec483b50..8799b9c76b8 100644 --- a/crates/apollo_infra_utils/src/test_utils.rs +++ b/crates/apollo_infra_utils/src/test_utils.rs @@ -44,6 +44,12 @@ pub enum TestIdentifier { SyncFlowIntegrationTest, StorageReaderServerUnitTests, StorageReaderTypesUnitTests, + L1EventsScraperEndToEndTest, + MockedStarknetStateUpdateTest, + LatestProvedBlockEthereumTest, + EventsFromOtherContractsTest, + L1ProviderUnitTests, + AnvilStartsWithNoContractTest, } #[derive(Debug)] diff --git a/crates/apollo_integration_tests/tests/events_from_other_contracts.rs b/crates/apollo_integration_tests/tests/events_from_other_contracts.rs index dc0cea733aa..4e748ebe45b 100644 --- a/crates/apollo_integration_tests/tests/events_from_other_contracts.rs +++ b/crates/apollo_integration_tests/tests/events_from_other_contracts.rs @@ -1,4 +1,5 @@ use apollo_base_layer_tests::anvil_base_layer::{send_message_to_l2, AnvilBaseLayer}; +use apollo_infra_utils::test_utils::{AvailablePortsGenerator, TestIdentifier}; use assert_matches::assert_matches; use papyrus_base_layer::constants::{EventIdentifier, LOG_MESSAGE_TO_L2_EVENT_IDENTIFIER}; use papyrus_base_layer::ethereum_base_layer_contract::Starknet; @@ -14,7 +15,13 @@ use starknet_api::{calldata, contract_address, felt}; async fn events_from_other_contract() { const EVENT_IDENTIFIERS: &[EventIdentifier] = &[LOG_MESSAGE_TO_L2_EVENT_IDENTIFIER]; - let mut anvil_base_layer = AnvilBaseLayer::new(None, Some(8888)).await; + let mut ports_gen = + AvailablePortsGenerator::new(TestIdentifier::EventsFromOtherContractsTest.into()); + let mut available_ports = ports_gen + .next() + .expect("Failed to get an AvailablePorts instance for events_from_other_contract"); + let mut anvil_base_layer = + AnvilBaseLayer::new(None, Some(available_ports.get_next_port())).await; // Anvil base layer already auto-deployed a starknet contract. let this_contract = &anvil_base_layer.ethereum_base_layer.contract; diff --git a/crates/apollo_integration_tests/tests/l1_events_scraper_end_to_end.rs b/crates/apollo_integration_tests/tests/l1_events_scraper_end_to_end.rs index 6e4a2d51d45..add96a11ee0 100644 --- a/crates/apollo_integration_tests/tests/l1_events_scraper_end_to_end.rs +++ b/crates/apollo_integration_tests/tests/l1_events_scraper_end_to_end.rs @@ -3,6 +3,7 @@ use std::time::Duration; use alloy::primitives::U256; use apollo_base_layer_tests::anvil_base_layer::AnvilBaseLayer; +use apollo_infra_utils::test_utils::{AvailablePortsGenerator, TestIdentifier}; use apollo_l1_provider::event_identifiers_to_track; use apollo_l1_provider::l1_scraper::L1Scraper; use apollo_l1_provider_types::{Event, MockL1ProviderClient}; @@ -22,7 +23,12 @@ use starknet_api::transaction::{L1HandlerTransaction, TransactionHasher, Transac #[tokio::test] async fn scraper_end_to_end() { // Setup. - let mut base_layer = AnvilBaseLayer::new(None, None).await; + let mut ports_gen = + AvailablePortsGenerator::new(TestIdentifier::L1EventsScraperEndToEndTest.into()); + let mut available_ports = ports_gen + .next() + .expect("Failed to get an AvailablePorts instance for l1_events_scraper_end_to_end"); + let mut base_layer = AnvilBaseLayer::new(None, Some(available_ports.get_next_port())).await; let contract = &base_layer.ethereum_base_layer.contract; let mut l1_provider_client = MockL1ProviderClient::default(); diff --git a/crates/apollo_integration_tests/tests/latest_proved_block_ethereum.rs b/crates/apollo_integration_tests/tests/latest_proved_block_ethereum.rs index 2ea347e229e..00e480a9de6 100644 --- a/crates/apollo_integration_tests/tests/latest_proved_block_ethereum.rs +++ b/crates/apollo_integration_tests/tests/latest_proved_block_ethereum.rs @@ -1,5 +1,6 @@ use alloy::providers::Provider; use apollo_base_layer_tests::anvil_base_layer::{AnvilBaseLayer, MockedStateUpdate}; +use apollo_infra_utils::test_utils::{AvailablePortsGenerator, TestIdentifier}; use papyrus_base_layer::BaseLayerContract; use pretty_assertions::assert_eq; use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockNumber}; @@ -49,7 +50,12 @@ async fn latest_proved_block_ethereum() { ))), }; - let mut base_layer = AnvilBaseLayer::new(None, None).await; + let mut ports_gen = + AvailablePortsGenerator::new(TestIdentifier::LatestProvedBlockEthereumTest.into()); + let mut available_ports = ports_gen + .next() + .expect("Failed to get an AvailablePorts instance for latest_proved_block_ethereum"); + let mut base_layer = AnvilBaseLayer::new(None, Some(available_ports.get_next_port())).await; let provider = &base_layer.anvil_provider; let mut current_block = provider.get_block_number().await.expect("Failed to get block number"); diff --git a/crates/apollo_integration_tests/tests/mocked_starknet_state_update_test.rs b/crates/apollo_integration_tests/tests/mocked_starknet_state_update_test.rs index 95c197d5da7..8b516475f37 100644 --- a/crates/apollo_integration_tests/tests/mocked_starknet_state_update_test.rs +++ b/crates/apollo_integration_tests/tests/mocked_starknet_state_update_test.rs @@ -3,6 +3,7 @@ use alloy::providers::Provider; use alloy::rpc::types::eth::Filter as EthEventFilter; use alloy::sol_types::SolEventInterface; use apollo_base_layer_tests::anvil_base_layer::{AnvilBaseLayer, MockedStateUpdate}; +use apollo_infra_utils::test_utils::{AvailablePortsGenerator, TestIdentifier}; use papyrus_base_layer::ethereum_base_layer_contract::Starknet; use papyrus_base_layer::BaseLayerContract; use pretty_assertions::assert_eq; @@ -10,7 +11,12 @@ use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockNumber}; #[tokio::test] async fn test_mocked_starknet_state_update() { - let mut base_layer = AnvilBaseLayer::new(None, None).await; + let mut ports_gen = + AvailablePortsGenerator::new(TestIdentifier::MockedStarknetStateUpdateTest.into()); + let mut available_ports = ports_gen + .next() + .expect("Failed to get an AvailablePorts instance for mocked_starknet_state_update_test"); + let mut base_layer = AnvilBaseLayer::new(None, Some(available_ports.get_next_port())).await; // Check that the contract was initialized (during the construction above). let genesis_block_number = 1; diff --git a/crates/apollo_l1_provider/tests/utils/mod.rs b/crates/apollo_l1_provider/tests/utils/mod.rs index f9a60d9d347..97191f02a96 100644 --- a/crates/apollo_l1_provider/tests/utils/mod.rs +++ b/crates/apollo_l1_provider/tests/utils/mod.rs @@ -17,6 +17,7 @@ use apollo_infra::component_server::{ LocalComponentServer, LocalServerConfig, }; +use apollo_infra_utils::test_utils::{AvailablePortsGenerator, TestIdentifier}; use apollo_l1_provider::l1_provider::L1Provider; use apollo_l1_provider::l1_scraper::L1Scraper; use apollo_l1_provider::metrics::L1_PROVIDER_INFRA_METRICS; @@ -67,7 +68,11 @@ fn convert_call_data_to_u256(call_data: &[u8]) -> Vec> { // Need to allow dead code as this is only used in some of the test crates. #[allow(dead_code)] pub(crate) async fn setup_anvil_base_layer() -> AnvilBaseLayer { - let mut base_layer = AnvilBaseLayer::new(None, None).await; + let mut ports_gen = AvailablePortsGenerator::new(TestIdentifier::L1ProviderUnitTests.into()); + let mut available_ports = ports_gen + .next() + .expect("Failed to get an AvailablePorts instance for L1 provider unit tests"); + let mut base_layer = AnvilBaseLayer::new(None, Some(available_ports.get_next_port())).await; anvil_mine_blocks(base_layer.ethereum_base_layer.config.clone(), NUMBER_OF_BLOCKS_TO_MINE) .await; // We use a really long timeout because in the tests we sometimes advance the fake time by large