From 3c0416e4e165240af0c71366ba78b583975b4113 Mon Sep 17 00:00:00 2001 From: Tomas Date: Tue, 24 Sep 2024 17:22:46 -0300 Subject: [PATCH] Use anvil on tests (#129) Changed tests to use anvil from a docker container instead of depending on anvil running externally. This will allow to run tests more easily, removing foundry as a dependency. Also fix some flaky tests that fail due to multiple tests running in parallel and making requests to the same anvil instance. --------- Co-authored-by: Pablo Deymonnaz --- .github/workflows/integration.yml | 3 - Cargo.lock | 3 + Makefile | 9 - .../chainio/clients/avsregistry/src/writer.rs | 77 ++++-- .../chainio/clients/elcontracts/src/reader.rs | 73 +++--- .../chainio/clients/elcontracts/src/writer.rs | 70 +++--- crates/chainio/clients/eth/Cargo.toml | 1 + .../clients/eth/src/instrumented_client.rs | 231 +++++++++++------- crates/eigen-cli/src/lib.rs | 98 ++++---- crates/metrics/collectors/economic/src/lib.rs | 14 +- crates/metrics/src/prometheus.rs | 14 +- crates/services/bls_aggregation/Cargo.toml | 1 + .../services/bls_aggregation/src/bls_agg.rs | 16 +- .../bls_aggregation/src/bls_agg_test.rs | 118 +++++---- .../src/operatorsinfo_inmemory.rs | 93 +++---- .../examples/get_contracts_from_registry.rs | 24 +- .../examples/get_operator_info.rs | 49 ++-- testing/testing-utils/Cargo.toml | 1 + testing/testing-utils/src/anvil.rs | 82 +++++++ testing/testing-utils/src/anvil_constants.rs | 32 +-- testing/testing-utils/src/lib.rs | 5 + testing/testing-utils/src/transaction.rs | 6 +- 22 files changed, 595 insertions(+), 425 deletions(-) create mode 100644 testing/testing-utils/src/anvil.rs diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 49f30ccb..a2fb1c98 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -81,9 +81,6 @@ jobs: with: cache-on-failure: true - - name: Install Foundry - run: cargo install --git https://github.com/foundry-rs/foundry --profile release --locked foundry-cast anvil - - name: docker uses: docker-practice/actions-setup-docker@master diff --git a/Cargo.lock b/Cargo.lock index 57f8c05a..bf5ab8c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2225,6 +2225,7 @@ dependencies = [ "eigen-metrics-collectors-rpc-calls", "eigen-signer", "eigen-testing-utils", + "eigen-utils", "hex", "once_cell", "serial_test", @@ -2403,6 +2404,7 @@ dependencies = [ "serde_json", "serial_test", "sha2", + "testcontainers", "thiserror", "tokio", "tokio-util", @@ -2471,6 +2473,7 @@ dependencies = [ "once_cell", "serde", "serde_json", + "testcontainers", "tokio", ] diff --git a/Makefile b/Makefile index edb6ef0c..f0ee3d6e 100644 --- a/Makefile +++ b/Makefile @@ -14,18 +14,9 @@ reset-anvil: -docker stop anvil -docker rm anvil -pr: - $(MAKE) start-anvil > /dev/null & - sleep 4 # needed to wait for anvil setup to finish - cargo test --workspace - docker stop anvil - coverage: - $(MAKE) start-anvil > /dev/null & - sleep 4 # needed to wait for anvil setup to finish cargo llvm-cov --lcov --output-path lcov.info --workspace --features fireblock-tests cargo llvm-cov report --html - docker stop anvil deps: @if ! command -v cargo-llvm-cov &> /dev/null; then \ diff --git a/crates/chainio/clients/avsregistry/src/writer.rs b/crates/chainio/clients/avsregistry/src/writer.rs index 4b2176a2..e37420ab 100644 --- a/crates/chainio/clients/avsregistry/src/writer.rs +++ b/crates/chainio/clients/avsregistry/src/writer.rs @@ -330,22 +330,28 @@ impl AvsRegistryChainWriter { #[cfg(test)] mod tests { use super::AvsRegistryChainWriter; - use alloy_node_bindings::Anvil; use alloy_primitives::{Address, Bytes, FixedBytes, U256}; use eigen_crypto_bls::BlsKeyPair; use eigen_logging::get_test_logger; + use eigen_testing_utils::anvil::start_anvil_container; use eigen_testing_utils::anvil_constants::{ - get_operator_state_retriever_address, get_registry_coordinator_address, ANVIL_HTTP_URL, + get_operator_state_retriever_address, get_registry_coordinator_address, }; use eigen_testing_utils::transaction::get_transaction_status; + use std::str::FromStr; - async fn build_avs_registry_chain_writer(private_key: String) -> AvsRegistryChainWriter { - let registry_coordinator_address = get_registry_coordinator_address().await; - let operator_state_retriever_address = get_operator_state_retriever_address().await; + async fn build_avs_registry_chain_writer( + http_endpoint: String, + private_key: String, + ) -> AvsRegistryChainWriter { + let registry_coordinator_address = + get_registry_coordinator_address(http_endpoint.clone()).await; + let operator_state_retriever_address = + get_operator_state_retriever_address(http_endpoint.clone()).await; AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - ANVIL_HTTP_URL.to_string(), + http_endpoint, private_key, registry_coordinator_address, operator_state_retriever_address, @@ -356,33 +362,48 @@ mod tests { #[tokio::test] async fn test_avs_writer_methods() { - let account_idx = 5; - let anvil = Anvil::new().try_spawn().unwrap(); - let private_key = anvil.keys().get(account_idx).unwrap(); - let private_key_hex = hex::encode(private_key.to_bytes()); - let private_key_decimal = U256::from_be_bytes(private_key.to_bytes().into()).to_string(); - let avs_writer = build_avs_registry_chain_writer(private_key_hex).await; - let operator_id = anvil.addresses().get(account_idx).unwrap(); - + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + + let bls_key = + "1371012690269088913462269866874713266643928125698382731338806296762673180359922" + .to_string(); + let private_key = + "8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba".to_string(); + let avs_writer = build_avs_registry_chain_writer(http_endpoint.clone(), private_key).await; + let operator_addr = Address::from_str("9965507D1a55bcC2695C58ba16FB37d819B0A4dc").unwrap(); let quorum_nums = Bytes::from([0]); - test_register_operator(&avs_writer, private_key_decimal, quorum_nums.clone()).await; - test_update_stake_of_operator_subset(&avs_writer, *operator_id).await; - test_update_stake_of_entire_operator_set(&avs_writer, *operator_id, quorum_nums.clone()) + + test_register_operator( + &avs_writer, + bls_key, + quorum_nums.clone(), + http_endpoint.clone(), + ) + .await; + test_update_stake_of_operator_subset(&avs_writer, operator_addr, http_endpoint.clone()) .await; - test_deregister_operator(&avs_writer, quorum_nums).await; + test_update_stake_of_entire_operator_set( + &avs_writer, + operator_addr, + quorum_nums.clone(), + http_endpoint.clone(), + ) + .await; + test_deregister_operator(&avs_writer, quorum_nums, http_endpoint).await; } // this function is caller from test_avs_writer_methods async fn test_update_stake_of_operator_subset( avs_writer: &AvsRegistryChainWriter, - operator_id: Address, + operator_addr: Address, + http_url: String, ) { let tx_hash = avs_writer - .update_stakes_of_operator_subset_for_all_quorums(vec![operator_id]) + .update_stakes_of_operator_subset_for_all_quorums(vec![operator_addr]) .await .unwrap(); - let tx_status = get_transaction_status(tx_hash).await; + let tx_status = get_transaction_status(http_url, tx_hash).await; assert!(tx_status); } @@ -391,13 +412,14 @@ mod tests { avs_writer: &AvsRegistryChainWriter, operator_id: Address, quorum_nums: Bytes, + http_url: String, ) { let tx_hash = avs_writer .update_stakes_of_entire_operator_set_for_quorums(vec![vec![operator_id]], quorum_nums) .await .unwrap(); - let tx_status = get_transaction_status(tx_hash).await; + let tx_status = get_transaction_status(http_url, tx_hash).await; assert!(tx_status); } @@ -406,6 +428,7 @@ mod tests { avs_writer: &AvsRegistryChainWriter, private_key_decimal: String, quorum_nums: Bytes, + http_url: String, ) { let bls_key_pair = BlsKeyPair::new(private_key_decimal).unwrap(); let digest_hash: FixedBytes<32> = FixedBytes::from([0x02; 32]); @@ -423,15 +446,19 @@ mod tests { .await .unwrap(); - let tx_status = get_transaction_status(tx_hash).await; + let tx_status = get_transaction_status(http_url, tx_hash).await; assert!(tx_status); } // this function is caller from test_avs_writer_methods - async fn test_deregister_operator(avs_writer: &AvsRegistryChainWriter, quorum_nums: Bytes) { + async fn test_deregister_operator( + avs_writer: &AvsRegistryChainWriter, + quorum_nums: Bytes, + http_url: String, + ) { let tx_hash = avs_writer.deregister_operator(quorum_nums).await.unwrap(); - let tx_status = get_transaction_status(tx_hash).await; + let tx_status = get_transaction_status(http_url, tx_hash).await; assert!(tx_status); } } diff --git a/crates/chainio/clients/elcontracts/src/reader.rs b/crates/chainio/clients/elcontracts/src/reader.rs index b97af92c..a766b0cd 100644 --- a/crates/chainio/clients/elcontracts/src/reader.rs +++ b/crates/chainio/clients/elcontracts/src/reader.rs @@ -391,35 +391,33 @@ mod tests { use alloy_primitives::{address, keccak256, Address, FixedBytes, U256}; use alloy_provider::Provider; use eigen_logging::get_test_logger; - use eigen_testing_utils::anvil_constants::{ - self, get_erc20_mock_strategy, ANVIL_HTTP_URL, ANVIL_RPC_URL, + use eigen_testing_utils::{ + anvil::start_anvil_container, + anvil_constants::{ + get_delegation_manager_address, get_erc20_mock_strategy, get_service_manager_address, + }, }; use eigen_utils::binding::{ mockAvsServiceManager, AVSDirectory, AVSDirectory::calculateOperatorAVSRegistrationDigestHashReturn, DelegationManager, DelegationManager::calculateDelegationApprovalDigestHashReturn, }; - use serial_test::serial; use std::str::FromStr; - use tokio::time::{sleep, Duration}; const OPERATOR_ADDRESS: &str = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"; - async fn build_el_chain_reader() -> ELChainReader { - let delegation_manager_address = anvil_constants::get_delegation_manager_address().await; - let delegation_manager_contract = DelegationManager::new( - delegation_manager_address, - anvil_constants::ANVIL_RPC_URL.clone(), - ); + async fn build_el_chain_reader(http_endpoint: String) -> ELChainReader { + let delegation_manager_address = + get_delegation_manager_address(http_endpoint.clone()).await; + let delegation_manager_contract = + DelegationManager::new(delegation_manager_address, get_provider(&http_endpoint)); let slasher_address_return = delegation_manager_contract.slasher().call().await.unwrap(); let DelegationManager::slasherReturn { _0: slasher_address, } = slasher_address_return; - let service_manager_address = anvil_constants::get_service_manager_address().await; - let service_manager_contract = mockAvsServiceManager::new( - service_manager_address, - get_provider("http://localhost:8545"), - ); + let service_manager_address = get_service_manager_address(http_endpoint.clone()).await; + let service_manager_contract = + mockAvsServiceManager::new(service_manager_address, get_provider(&http_endpoint)); let avs_directory_address_return = service_manager_contract .avsDirectory() .call() @@ -434,14 +432,15 @@ mod tests { slasher_address, delegation_manager_address, avs_directory_address, - ANVIL_HTTP_URL.to_string(), + http_endpoint, ) } #[tokio::test] - #[serial] async fn test_calculate_delegation_approval_digest_hash() { - let el_chain_reader = build_el_chain_reader().await; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + let el_chain_reader = build_el_chain_reader(http_endpoint.clone()).await; let operator: Address = address!("5eb15C0992734B5e77c888D713b4FC67b3D679A2"); let staker = operator; @@ -449,9 +448,8 @@ mod tests { let delegation_approver = Address::ZERO; let approve_salt: FixedBytes<32> = FixedBytes::from([0x02; 32]); - let current_block_number = ANVIL_RPC_URL.clone().get_block_number().await.unwrap(); - let block_info = ANVIL_RPC_URL - .clone() + let current_block_number = provider.get_block_number().await.unwrap(); + let block_info = provider .get_block_by_number(Number(current_block_number), true) .await .unwrap(); @@ -471,11 +469,9 @@ mod tests { .unwrap(); // Directly calling the function through bindings to compare with the sdk . - let delegation_manager_address = anvil_constants::get_delegation_manager_address().await; - let delegation_manager_contract = DelegationManager::new( - delegation_manager_address, - anvil_constants::ANVIL_RPC_URL.clone(), - ); + let delegation_manager_address = get_delegation_manager_address(http_endpoint).await; + let delegation_manager_contract = + DelegationManager::new(delegation_manager_address, provider); let hash = delegation_manager_contract .calculateDelegationApprovalDigestHash( @@ -495,16 +491,15 @@ mod tests { } #[tokio::test] - #[serial] async fn test_calculate_operator_avs_registration_digest_hash() { - sleep(Duration::from_secs(2)).await; - let el_chain_reader = build_el_chain_reader().await; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + let el_chain_reader = build_el_chain_reader(http_endpoint.clone()).await; let operator: Address = address!("5eb15C0992734B5e77c888D713b4FC67b3D679A2"); let avs = Address::from_slice(&keccak256("avs ")[0..20]); let salt: FixedBytes<32> = FixedBytes::from([0x02; 32]); - let current_block_number = ANVIL_RPC_URL.clone().get_block_number().await.unwrap(); - let block_info = ANVIL_RPC_URL - .clone() + let current_block_number = provider.get_block_number().await.unwrap(); + let block_info = provider .get_block_by_number(Number(current_block_number), true) .await .unwrap(); @@ -519,7 +514,7 @@ mod tests { // Using bindings directly to compare with sdk's output let avs_registry_contract = - AVSDirectory::new(el_chain_reader.avs_directory, ANVIL_RPC_URL.clone()); + AVSDirectory::new(el_chain_reader.avs_directory, provider.clone()); let operator_hash_from_bindings = avs_registry_contract .calculateOperatorAVSRegistrationDigestHash(operator, avs, salt, expiry) .call() @@ -533,12 +528,12 @@ mod tests { } #[tokio::test] - #[serial] async fn check_strategy_shares_and_operator_frozen() { + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; let operator_addr = Address::from_str(OPERATOR_ADDRESS).unwrap(); - let strategy_addr = get_erc20_mock_strategy().await; + let strategy_addr = get_erc20_mock_strategy(http_endpoint.clone()).await; - let chain_reader = build_el_chain_reader().await; + let chain_reader = build_el_chain_reader(http_endpoint.clone()).await; let shares = chain_reader .get_operator_shares_in_strategy(operator_addr, strategy_addr) .await @@ -554,7 +549,7 @@ mod tests { .unwrap(); assert!(!frozen); - let service_manager_address = anvil_constants::get_service_manager_address().await; + let service_manager_address = get_service_manager_address(http_endpoint).await; let ret_can_slash = chain_reader .service_manager_can_slash_operator_until_block(operator_addr, service_manager_address) .await @@ -565,10 +560,10 @@ mod tests { } #[tokio::test] - #[serial] async fn test_get_operator_details() { + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; let operator_addr = Address::from_str(OPERATOR_ADDRESS).unwrap(); - let chain_reader = build_el_chain_reader().await; + let chain_reader = build_el_chain_reader(http_endpoint).await; let operator = chain_reader .get_operator_details(operator_addr) diff --git a/crates/chainio/clients/elcontracts/src/writer.rs b/crates/chainio/clients/elcontracts/src/writer.rs index 9c58b698..7d9606a0 100644 --- a/crates/chainio/clients/elcontracts/src/writer.rs +++ b/crates/chainio/clients/elcontracts/src/writer.rs @@ -192,17 +192,23 @@ mod tests { use alloy_primitives::{Address, U256}; use alloy_provider::Provider; use alloy_signer_local::PrivateKeySigner; - use anvil_constants::{ANVIL_RPC_URL, CONTRACTS_REGISTRY}; + use anvil_constants::CONTRACTS_REGISTRY; use eigen_logging::get_test_logger; - use eigen_testing_utils::anvil_constants::{ - self, get_delegation_manager_address, get_erc20_mock_strategy, get_service_manager_address, - get_strategy_manager_address, ANVIL_HTTP_URL, + use eigen_testing_utils::{ + anvil::start_anvil_container, + anvil_constants::{ + self, get_delegation_manager_address, get_erc20_mock_strategy, + get_service_manager_address, get_strategy_manager_address, + }, }; use eigen_types::operator::Operator; - use eigen_utils::binding::{ - mockAvsServiceManager, - ContractsRegistry::{self, get_test_valuesReturn}, - DelegationManager, + use eigen_utils::{ + binding::{ + mockAvsServiceManager, + ContractsRegistry::{self, get_test_valuesReturn}, + DelegationManager, + }, + get_provider, }; use std::str::FromStr; @@ -211,21 +217,22 @@ mod tests { /// # Returns /// /// A tuple containing an instance of ELChainWriter and the address of the delegation manager contract - async fn setup_el_chain_reader() -> (ELChainReader, Address) { - let delegation_manager_address = get_delegation_manager_address().await; + async fn setup_el_chain_reader(http_endpoint: String) -> (ELChainReader, Address) { + let delegation_manager_address = + get_delegation_manager_address(http_endpoint.clone()).await; let delegation_manager_contract = DelegationManager::new( delegation_manager_address, - anvil_constants::ANVIL_RPC_URL.clone(), + get_provider(http_endpoint.as_str()), ); let slasher_address_return = delegation_manager_contract.slasher().call().await.unwrap(); let DelegationManager::slasherReturn { _0: slasher_address, } = slasher_address_return; - let service_manager_address = get_service_manager_address().await; + let service_manager_address = get_service_manager_address(http_endpoint.clone()).await; let service_manager_contract = mockAvsServiceManager::new( service_manager_address, - anvil_constants::ANVIL_RPC_URL.clone(), + get_provider(http_endpoint.as_str()), ); let avs_directory_address_return = service_manager_contract .avsDirectory() @@ -243,7 +250,7 @@ mod tests { slasher_address, delegation_manager_address, avs_directory_address, - ANVIL_HTTP_URL.to_string(), + http_endpoint, ), delegation_manager_address, ) @@ -251,14 +258,18 @@ mod tests { #[tokio::test] async fn test_register_operator() { - let (el_chain_reader, _delegation_manager_address) = setup_el_chain_reader().await; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let (el_chain_reader, _delegation_manager_address) = + setup_el_chain_reader(http_endpoint).await; let operator_pvt_key = "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; let operator: PrivateKeySigner = (operator_pvt_key) .parse() .expect("failed to generate wallet"); - let contract_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, ANVIL_RPC_URL.clone()); + let contract_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, provider); // Use these value in tests when needed let operator_index = "1".parse().unwrap(); let get_test_values_return = contract_registry @@ -282,18 +293,20 @@ mod tests { #[tokio::test] async fn test_chain_writer() { - let (el_chain_reader, _) = setup_el_chain_reader().await; - let http_endpoint = "http://localhost:8545".to_string(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let (el_chain_reader, _) = setup_el_chain_reader(http_endpoint.clone()).await; let operator_addr = Address::from_str("90F79bf6EB2c4f870365E785982E1f101E93b906").unwrap(); let operator_private_key = "7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6".to_string(); - let strategy_manager = get_strategy_manager_address().await; + let strategy_manager = get_strategy_manager_address(http_endpoint.clone()).await; let el_chain_writer = ELChainWriter::new( operator_addr, strategy_manager, el_chain_reader, - http_endpoint, + http_endpoint.clone(), operator_private_key, ); @@ -319,10 +332,7 @@ mod tests { // this sleep is needed so that we wait for the tx to be processed tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let receipt = ANVIL_RPC_URL - .get_transaction_receipt(tx_hash) - .await - .unwrap(); + let receipt = provider.get_transaction_receipt(tx_hash).await.unwrap(); assert!(receipt.unwrap().status()); let wallet_modified = PrivateKeySigner::from_str( @@ -346,15 +356,12 @@ mod tests { // this sleep is needed so that we wait for the tx to be processed tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let receipt = ANVIL_RPC_URL - .get_transaction_receipt(tx_hash) - .await - .unwrap(); + let receipt = provider.get_transaction_receipt(tx_hash).await.unwrap(); assert!(receipt.unwrap().status()); // Third test: deposit_erc20_into_strategy let amount = U256::from_str("100").unwrap(); - let strategy_addr = get_erc20_mock_strategy().await; + let strategy_addr = get_erc20_mock_strategy(http_endpoint).await; let tx_hash = el_chain_writer .deposit_erc20_into_strategy(strategy_addr, amount) .await @@ -362,10 +369,7 @@ mod tests { // this sleep is needed so that we wait for the tx to be processed tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let receipt = ANVIL_RPC_URL - .get_transaction_receipt(tx_hash) - .await - .unwrap(); + let receipt = provider.get_transaction_receipt(tx_hash).await.unwrap(); assert!(receipt.unwrap().status()); } } diff --git a/crates/chainio/clients/eth/Cargo.toml b/crates/chainio/clients/eth/Cargo.toml index 8472803a..103f5d16 100644 --- a/crates/chainio/clients/eth/Cargo.toml +++ b/crates/chainio/clients/eth/Cargo.toml @@ -30,6 +30,7 @@ url.workspace = true alloy-node-bindings.workspace = true eigen-signer.workspace = true eigen-testing-utils.workspace = true +eigen-utils.workspace = true once_cell.workspace = true serial_test.workspace = true tokio.workspace = true diff --git a/crates/chainio/clients/eth/src/instrumented_client.rs b/crates/chainio/clients/eth/src/instrumented_client.rs index 6120cd8c..c184cbe4 100644 --- a/crates/chainio/clients/eth/src/instrumented_client.rs +++ b/crates/chainio/clients/eth/src/instrumented_client.rs @@ -836,18 +836,18 @@ mod tests { pubsub::SubscriptionResult, BlockId, BlockNumberOrTag, BlockTransactionsKind, }; use eigen_signer::signer::Config; - use eigen_testing_utils::anvil_constants::{ANVIL_HTTP_URL, ANVIL_RPC_URL, ANVIL_WS_URL}; - use serial_test::serial; + use eigen_testing_utils::anvil::start_anvil_container; + use eigen_utils::get_provider; use std::{thread, time}; use tokio; #[tokio::test] - #[serial] async fn test_suggest_gas_tip_cap() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); let fee_per_gas = instrumented_client.suggest_gas_tip_cap().await.unwrap(); - let expected_fee_per_gas = ANVIL_RPC_URL - .clone() + let expected_fee_per_gas = get_provider(&http_endpoint) .get_max_priority_fee_per_gas() .await .unwrap(); @@ -855,41 +855,49 @@ mod tests { } #[tokio::test] - #[serial] async fn test_gas_price() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); let gas_price = instrumented_client.suggest_gas_price().await.unwrap(); - let expected_gas_price = ANVIL_RPC_URL.clone().get_gas_price().await.unwrap(); + let expected_gas_price = provider.clone().get_gas_price().await.unwrap(); assert_eq!(gas_price, expected_gas_price as u64); } #[tokio::test] - #[serial] async fn test_sync_status() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); let sync_status = instrumented_client.sync_progress().await.unwrap(); - let expected_sync_status = ANVIL_RPC_URL.clone().syncing().await.unwrap(); + let expected_sync_status = provider.clone().syncing().await.unwrap(); assert_eq!(expected_sync_status, sync_status); } #[tokio::test] - #[serial] async fn test_chain_id() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); - let expected_chain_id = ANVIL_RPC_URL.clone().get_chain_id().await.unwrap(); + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + + let expected_chain_id = provider.clone().get_chain_id().await.unwrap(); let chain_id = instrumented_client.chain_id().await.unwrap(); assert_eq!(expected_chain_id, chain_id); } #[tokio::test] - #[serial] async fn test_balance_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; - let expected_balance_at = ANVIL_RPC_URL.get_balance(address).await.unwrap(); + let expected_balance_at = provider.get_balance(address).await.unwrap(); let balance_at = instrumented_client .balance_at(address, BlockNumberOrTag::Latest) .await @@ -899,19 +907,22 @@ mod tests { } #[tokio::test] - #[serial] async fn test_subscribe_new_head() { - let instrumented_client = InstrumentedClient::new_ws(ANVIL_WS_URL).await.unwrap(); + let (_container, _http_endpoint, ws_endpoint) = start_anvil_container().await; + + let instrumented_client = InstrumentedClient::new_ws(&ws_endpoint).await.unwrap(); let subscription: TransportResult> = instrumented_client.subscribe_new_head().await; assert!(subscription.is_ok()) } #[tokio::test] - #[serial] async fn test_subscribe_filter_logs() { - let instrumented_client = InstrumentedClient::new_ws(ANVIL_WS_URL).await.unwrap(); - let address = ANVIL_RPC_URL.clone().get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new_ws(&ws_endpoint).await.unwrap(); + let address = provider.clone().get_accounts().await.unwrap()[0]; let filter = Filter::new().address(address.to_string().parse::
().unwrap()); let subscription: TransportResult> = @@ -921,12 +932,14 @@ mod tests { } #[tokio::test] - #[serial] async fn test_block_by_hash() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); // get the hash from the last block - let hash = ANVIL_RPC_URL + let hash = provider .get_block(BlockId::latest(), BlockTransactionsKind::Hashes) .await .unwrap() @@ -935,7 +948,7 @@ mod tests { .hash .unwrap(); - let expected_block = ANVIL_RPC_URL + let expected_block = provider .get_block_by_hash(hash, BlockTransactionsKind::Full) .await .unwrap(); @@ -945,12 +958,14 @@ mod tests { } #[tokio::test] - #[serial] async fn test_block_by_number() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); let block_number = 1; - let expected_block = ANVIL_RPC_URL + let expected_block = provider .get_block_by_number(block_number.into(), true) .await .unwrap(); @@ -963,11 +978,13 @@ mod tests { } #[tokio::test] - #[serial] async fn test_transaction_count() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); - let block = ANVIL_RPC_URL + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + + let block = provider .get_block(BlockId::latest(), BlockTransactionsKind::Hashes) .await .unwrap() @@ -989,8 +1006,9 @@ mod tests { /// * `transaction_receipt` /// * `transaction_in_block` #[tokio::test] - #[serial] async fn test_transaction_methods() { + let (_container, _http_endpoint, _ws_endpoint) = start_anvil_container().await; + // create a new anvil instance because otherwise it fails with "nonce too low" error. let anvil = Anvil::new().try_spawn().unwrap(); let rpc_url: String = anvil.endpoint().parse().unwrap(); @@ -1046,13 +1064,12 @@ mod tests { } #[tokio::test] - #[serial] async fn test_estimate_gas() { - let instrumented_client = InstrumentedClient::new("http:/localhost:8545") - .await - .unwrap(); - let anvil = ANVIL_RPC_URL.clone(); - let accounts = anvil.get_accounts().await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let accounts = provider.get_accounts().await.unwrap(); let from = accounts.first().unwrap(); let to = accounts.get(1).unwrap(); @@ -1069,17 +1086,19 @@ mod tests { let tx_request: TransactionRequest = tx.clone().into(); let tx_request = tx_request.from(*from); - let expected_estimated_gas = anvil.clone().estimate_gas(&tx_request).await.unwrap(); + let expected_estimated_gas = provider.clone().estimate_gas(&tx_request).await.unwrap(); let estimated_gas = instrumented_client.estimate_gas(tx_request).await.unwrap(); assert_eq!(expected_estimated_gas, estimated_gas.into()); } #[tokio::test] - #[serial] async fn test_call_contract_and_pending_call_contract() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); - let anvil = ANVIL_RPC_URL.clone(); + let anvil = provider.clone(); let accounts = anvil.get_accounts().await.unwrap(); let from = accounts.first().unwrap(); let to = accounts.get(1).unwrap(); @@ -1116,25 +1135,29 @@ mod tests { } #[tokio::test] - #[serial] async fn test_filter_logs() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.clone().get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.clone().get_accounts().await.unwrap()[0]; let filter = Filter::new().address(address.to_string().parse::
().unwrap()); - let expected_logs = ANVIL_RPC_URL.clone().get_logs(&filter).await.unwrap(); + let expected_logs = provider.clone().get_logs(&filter).await.unwrap(); let logs = instrumented_client.filter_logs(filter).await.unwrap(); assert_eq!(expected_logs, logs); } #[tokio::test] - #[serial] async fn test_storage_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); - let account = ANVIL_RPC_URL.clone().get_accounts().await.unwrap()[0]; - let expected_storage = ANVIL_RPC_URL + let account = provider.clone().get_accounts().await.unwrap()[0]; + let expected_storage = provider .clone() .get_storage_at(account, U256::ZERO) .await @@ -1149,23 +1172,27 @@ mod tests { } #[tokio::test] - #[serial] async fn test_block_number() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); - let expected_block_number = ANVIL_RPC_URL.clone().get_block_number().await.unwrap(); + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + + let expected_block_number = provider.clone().get_block_number().await.unwrap(); let block_number = instrumented_client.block_number().await.unwrap(); assert_eq!(expected_block_number, block_number); } #[tokio::test] - #[serial] async fn test_code_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; - let expected_code = ANVIL_RPC_URL.get_code_at(address).await.unwrap(); + let expected_code = provider.get_code_at(address).await.unwrap(); let code = instrumented_client .code_at(address, BlockNumberOrTag::Latest) .await @@ -1175,14 +1202,16 @@ mod tests { } #[tokio::test] - #[serial] async fn test_fee_history() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); let block_count = 4; let last_block = BlockNumberOrTag::Latest; let reward_percentiles = [0.2, 0.3]; - let expected_fee_history = ANVIL_RPC_URL + let expected_fee_history = provider .get_fee_history(block_count, last_block, &reward_percentiles) .await .unwrap(); @@ -1195,10 +1224,12 @@ mod tests { } #[tokio::test] - #[serial] async fn test_header_by_hash() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let hash = ANVIL_RPC_URL + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let hash = provider .get_block(BlockId::latest(), BlockTransactionsKind::Hashes) .await .unwrap() @@ -1207,7 +1238,7 @@ mod tests { .hash .unwrap(); - let expected_header = ANVIL_RPC_URL + let expected_header = provider .get_block_by_hash(hash, BlockTransactionsKind::Hashes) .await .unwrap() @@ -1219,9 +1250,11 @@ mod tests { } #[tokio::test] - #[serial] async fn test_header_by_number() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); let block_number = BlockNumberOrTag::Earliest; let header = instrumented_client @@ -1229,7 +1262,7 @@ mod tests { .await .unwrap(); - let expected_header = ANVIL_RPC_URL + let expected_header = provider .get_block_by_number(block_number, false) .await .unwrap() @@ -1240,12 +1273,14 @@ mod tests { } #[tokio::test] - #[serial] async fn test_nonce_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; - let expected_nonce = ANVIL_RPC_URL.get_transaction_count(address).await.unwrap(); + let expected_nonce = provider.get_transaction_count(address).await.unwrap(); let nonce = instrumented_client .nonce_at(address, BlockNumberOrTag::Latest) .await @@ -1255,13 +1290,15 @@ mod tests { } #[tokio::test] - #[serial] async fn test_pending_balance_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; // TODO: currently comparing "pending" balance with "latest" balance. Check for pending transactions? - let expected_balance = ANVIL_RPC_URL.get_balance(address).await.unwrap(); + let expected_balance = provider.get_balance(address).await.unwrap(); let balance = instrumented_client .pending_balance_at(address) .await @@ -1271,41 +1308,47 @@ mod tests { } #[tokio::test] - #[serial] async fn test_pending_code_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; // TODO: currently comparing "pending" with "latest". Check for pending transactions? - let expected_code = ANVIL_RPC_URL.get_code_at(address).await.unwrap(); + let expected_code = provider.get_code_at(address).await.unwrap(); let code = instrumented_client.pending_code_at(address).await.unwrap(); assert_eq!(expected_code, code); } #[tokio::test] - #[serial] async fn test_pending_nonce_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; // TODO: currently comparing "pending" with "latest". Check for pending transactions? - let expected_pending_nonce_at = ANVIL_RPC_URL.get_transaction_count(address).await.unwrap(); + let expected_pending_nonce_at = provider.get_transaction_count(address).await.unwrap(); let pending_nonce_at = instrumented_client.pending_nonce_at(address).await.unwrap(); assert_eq!(expected_pending_nonce_at, pending_nonce_at); } #[tokio::test] - #[serial] async fn test_pending_storage_at() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); - let address = ANVIL_RPC_URL.get_accounts().await.unwrap()[0]; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); + let address = provider.get_accounts().await.unwrap()[0]; let key = U256::from(10); // TODO: currently comparing "pending" with "latest". Check for pending transactions? // TODO: set storage and check change - let expected_pending_storage_at = ANVIL_RPC_URL.get_storage_at(address, key).await.unwrap(); + let expected_pending_storage_at = provider.get_storage_at(address, key).await.unwrap(); let pending_storage_at = instrumented_client .pending_storage_at(address, key) .await @@ -1315,11 +1358,13 @@ mod tests { } #[tokio::test] - #[serial] async fn test_pending_transaction_count() { - let instrumented_client = InstrumentedClient::new(ANVIL_HTTP_URL).await.unwrap(); + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let provider = get_provider(&http_endpoint); + + let instrumented_client = InstrumentedClient::new(&http_endpoint).await.unwrap(); - let expected_transaction_count: u64 = ANVIL_RPC_URL + let expected_transaction_count: u64 = provider .get_block_by_number(BlockNumberOrTag::Pending, false) .await .unwrap() diff --git a/crates/eigen-cli/src/lib.rs b/crates/eigen-cli/src/lib.rs index facf71fb..18cd6afe 100644 --- a/crates/eigen-cli/src/lib.rs +++ b/crates/eigen-cli/src/lib.rs @@ -195,8 +195,9 @@ mod test { operator_id::derive_operator_id, }; use alloy_primitives::Address; + use eigen_testing_utils::anvil::start_anvil_container; use eigen_testing_utils::anvil_constants::{ - get_registry_coordinator_address, get_service_manager_address, ANVIL_HTTP_URL, + get_registry_coordinator_address, get_service_manager_address, }; use eigen_testing_utils::test_data::TestData; use eth_keystore::decrypt_key; @@ -281,30 +282,32 @@ mod test { #[tokio::test] async fn test_egn_addrs_with_service_manager_flag() { + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let test_data = TestData::new(Input { - service_manager_address: get_service_manager_address().await, - rpc_url: ANVIL_HTTP_URL.into(), + service_manager_address: get_service_manager_address(http_endpoint.clone()).await, + rpc_url: http_endpoint.clone(), }); - let expected_addresses: ContractAddresses = serde_json::from_str( - r#"{ - "avs": { - "bls-apk-registry": "0x84ea74d481ee0a5332c457a4d796187f6ba67feb", - "index-registry": "0x9e545e3c0baab3e08cdfd552c960a1050f373042", - "registry-coordinator": "0xc3e53f4d16ae77db1c982e75a937b9f60fe63690", - "service-manager": "0x67d269191c92caf3cd7723f116c85e6e9bf55933", - "stake-registry": "0xa82ff9afd8f496c3d6ac40e2a0f282e47488cfc9" - }, - "eigenlayer": { - "delegation-manager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "slasher": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", - "strategy-manager": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - }, - "network": { - "chain-id": "31337", - "rpc-url": "http://localhost:8545" - } - }"#, - ) + let expected_addresses: ContractAddresses = serde_json::from_str(&format!( + r#"{{ + "avs": {{ + "bls-apk-registry": "0x84ea74d481ee0a5332c457a4d796187f6ba67feb", + "index-registry": "0x9e545e3c0baab3e08cdfd552c960a1050f373042", + "registry-coordinator": "0xc3e53f4d16ae77db1c982e75a937b9f60fe63690", + "service-manager": "0x67d269191c92caf3cd7723f116c85e6e9bf55933", + "stake-registry": "0xa82ff9afd8f496c3d6ac40e2a0f282e47488cfc9" + }}, + "eigenlayer": {{ + "delegation-manager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "slasher": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "strategy-manager": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" + }}, + "network": {{ + "chain-id": "31337", + "rpc-url": "{http_endpoint}" + }} + }}"# + )) .unwrap(); let addresses = ContractAddresses::get_addresses( Some(test_data.input.service_manager_address), @@ -319,34 +322,37 @@ mod test { #[tokio::test] async fn test_egn_addrs_with_registry_coordinator_flag() { - let registry_coordinator_address = get_registry_coordinator_address().await; - - let expected_addresses: ContractAddresses = serde_json::from_str( - r#"{ - "avs": { - "bls-apk-registry": "0x84ea74d481ee0a5332c457a4d796187f6ba67feb", - "index-registry": "0x9e545e3c0baab3e08cdfd552c960a1050f373042", - "registry-coordinator": "0xc3e53f4d16ae77db1c982e75a937b9f60fe63690", - "service-manager": "0x67d269191c92caf3cd7723f116c85e6e9bf55933", - "stake-registry": "0xa82ff9afd8f496c3d6ac40e2a0f282e47488cfc9" - }, - "eigenlayer": { - "delegation-manager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "slasher": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", - "strategy-manager": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - }, - "network": { - "chain-id": "31337", - "rpc-url": "http://localhost:8545" - } - }"#, - ) + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + + let registry_coordinator_address = + get_registry_coordinator_address(http_endpoint.clone()).await; + + let expected_addresses: ContractAddresses = serde_json::from_str(&format!( + r#"{{ + "avs": {{ + "bls-apk-registry": "0x84ea74d481ee0a5332c457a4d796187f6ba67feb", + "index-registry": "0x9e545e3c0baab3e08cdfd552c960a1050f373042", + "registry-coordinator": "0xc3e53f4d16ae77db1c982e75a937b9f60fe63690", + "service-manager": "0x67d269191c92caf3cd7723f116c85e6e9bf55933", + "stake-registry": "0xa82ff9afd8f496c3d6ac40e2a0f282e47488cfc9" + }}, + "eigenlayer": {{ + "delegation-manager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "slasher": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "strategy-manager": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" + }}, + "network": {{ + "chain-id": "31337", + "rpc-url": "{http_endpoint}" + }} + }}"#, + )) .unwrap(); let addresses = ContractAddresses::get_addresses( None, Some(registry_coordinator_address), - ANVIL_HTTP_URL.into(), + http_endpoint, ) .await .unwrap(); diff --git a/crates/metrics/collectors/economic/src/lib.rs b/crates/metrics/collectors/economic/src/lib.rs index 3b889289..aae189d5 100644 --- a/crates/metrics/collectors/economic/src/lib.rs +++ b/crates/metrics/collectors/economic/src/lib.rs @@ -155,20 +155,24 @@ mod tests { use alloy_primitives::{Address, FixedBytes}; use eigen_client_avsregistry::reader::AvsRegistryChainReader; use eigen_logging::get_test_logger; - use eigen_testing_utils::anvil_constants; + use eigen_testing_utils::{ + anvil::start_anvil_container, + anvil_constants::{get_operator_state_retriever_address, get_registry_coordinator_address}, + }; use crate::fake_collector::FakeCollector; #[tokio::test] async fn test_init_operator_id() { + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + let operator_addr = Address::ZERO; let operator_id = FixedBytes::<32>::default(); - let http_anvil = "http://localhost:8545"; let avs_registry_reader = AvsRegistryChainReader::new( get_test_logger(), - anvil_constants::get_registry_coordinator_address().await, - anvil_constants::get_operator_state_retriever_address().await, - http_anvil.to_string(), + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, + http_endpoint, ) .await .unwrap(); diff --git a/crates/metrics/src/prometheus.rs b/crates/metrics/src/prometheus.rs index 4e47e776..f4a05841 100644 --- a/crates/metrics/src/prometheus.rs +++ b/crates/metrics/src/prometheus.rs @@ -26,25 +26,29 @@ mod tests { use eigen_client_avsregistry::reader::AvsRegistryChainReader; use eigen_metrics_collectors_economic::fake_collector::FakeCollector; use eigen_metrics_collectors_rpc_calls::RpcCallsMetrics; - use eigen_testing_utils::anvil_constants; + use eigen_testing_utils::anvil::start_anvil_container; + use eigen_testing_utils::anvil_constants::{ + get_operator_state_retriever_address, get_registry_coordinator_address, + }; use num_bigint::BigInt; use tokio::time::sleep; use tokio::time::Duration; #[tokio::test] async fn test_prometheus_server() { + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + use eigen_logging::get_test_logger; let socket: SocketAddr = "127.0.0.1:9091".parse().unwrap(); init_registry(socket); let operator_addr = Address::ZERO; let operator_id = FixedBytes::<32>::default(); - let http_anvil = "http://localhost:8545"; let avs_registry_reader = AvsRegistryChainReader::new( get_test_logger(), - anvil_constants::get_registry_coordinator_address().await, - anvil_constants::get_operator_state_retriever_address().await, - http_anvil.to_string(), + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, + http_endpoint.to_string(), ) .await .unwrap(); diff --git a/crates/services/bls_aggregation/Cargo.toml b/crates/services/bls_aggregation/Cargo.toml index 2db9f5a1..36b9475e 100644 --- a/crates/services/bls_aggregation/Cargo.toml +++ b/crates/services/bls_aggregation/Cargo.toml @@ -32,4 +32,5 @@ eigen-utils.workspace = true eigen-services-operatorsinfo.workspace = true serial_test = "3.1" sha2 = "0.10.8" +testcontainers.workspace = true tokio-util = "0.7.11" diff --git a/crates/services/bls_aggregation/src/bls_agg.rs b/crates/services/bls_aggregation/src/bls_agg.rs index 3c8f9c5a..28b7de9f 100644 --- a/crates/services/bls_aggregation/src/bls_agg.rs +++ b/crates/services/bls_aggregation/src/bls_agg.rs @@ -175,6 +175,14 @@ impl BlsAggregatorService bls_signature: Signature, operator_id: FixedBytes<32>, ) -> Result<(), BlsAggregationServiceError> { + let (tx, rx) = mpsc::channel(1); + let task = SignedTaskResponseDigest { + task_response_digest, + bls_signature, + operator_id, + signature_verification_channel: tx, + }; + let mut rx = { let task_channel = self.signed_task_response.read(); @@ -182,14 +190,6 @@ impl BlsAggregatorService .get(&task_index) .ok_or(BlsAggregationServiceError::TaskNotFound)?; - let (tx, rx) = mpsc::channel(1); - let task = SignedTaskResponseDigest { - task_response_digest, - bls_signature, - operator_id, - signature_verification_channel: tx, - }; - // send the task to the aggregator thread sender .send(task) diff --git a/crates/services/bls_aggregation/src/bls_agg_test.rs b/crates/services/bls_aggregation/src/bls_agg_test.rs index 08380674..dd229d8a 100644 --- a/crates/services/bls_aggregation/src/bls_agg_test.rs +++ b/crates/services/bls_aggregation/src/bls_agg_test.rs @@ -12,11 +12,14 @@ pub mod integration_test { use eigen_logging::get_test_logger; use eigen_services_avsregistry::chaincaller::AvsRegistryServiceChainCaller; use eigen_services_operatorsinfo::operatorsinfo_inmemory::OperatorInfoServiceInMemory; - use eigen_testing_utils::anvil_constants::{ - get_erc20_mock_strategy, get_operator_state_retriever_address, - get_registry_coordinator_address, get_service_manager_address, + use eigen_testing_utils::{ + anvil::{mine_anvil_blocks, start_anvil_container}, + anvil_constants::{ + get_erc20_mock_strategy, get_operator_state_retriever_address, + get_registry_coordinator_address, get_service_manager_address, + }, + test_data::TestData, }; - use eigen_testing_utils::test_data::TestData; use eigen_types::{ avs::TaskIndex, operator::{QuorumNum, QuorumThresholdPercentages}, @@ -29,14 +32,9 @@ pub mod integration_test { get_provider, get_signer, }; use serde::Deserialize; - use serial_test::serial; use sha2::{Digest, Sha256}; - use std::{ - process::{Command, Stdio}, - thread::sleep, - time::Duration, - }; - use tokio::task; + use std::time::Duration; + use tokio::{task, time::sleep}; use tokio_util::sync::CancellationToken; const PRIVATE_KEY_1: &str = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; // the owner addr @@ -46,9 +44,6 @@ pub mod integration_test { const BLS_KEY_2: &str = "14610126902690889134622698668747132666439281256983827313388062967626731803500"; - const HTTP_ENDPOINT: &str = "http://localhost:8545"; - const WS_ENDPOINT: &str = "ws://localhost:8545"; - fn hash(task_response: u64) -> B256 { let mut hasher = Sha256::new(); hasher.update(task_response.to_be_bytes()); @@ -82,14 +77,6 @@ pub mod integration_test { } } - fn mine_anvil_block() { - Command::new("cast") - .args(["rpc", "anvil_mine", "1", "--rpc-url", HTTP_ENDPOINT]) - .stdout(Stdio::null()) - .output() - .expect("Failed to execute command"); - } - #[derive(Deserialize, Debug)] struct Input { bls_key: String, @@ -98,9 +85,10 @@ pub mod integration_test { } #[tokio::test] - #[serial] async fn test_bls_agg() { // test 1 quorum, 1 operator + let (container, http_endpoint, ws_endpoint) = start_anvil_container().await; + // if TEST_DATA_PATH is set, load the test data from the json file let default_input = Input { bls_key: BLS_KEY_1.to_string(), @@ -109,10 +97,12 @@ pub mod integration_test { }; let test_data: TestData = TestData::new(default_input); - let registry_coordinator_address = get_registry_coordinator_address().await; - let operator_state_retriever_address = get_operator_state_retriever_address().await; - let service_manager_address = get_service_manager_address().await; - let provider = get_provider(HTTP_ENDPOINT); + let registry_coordinator_address = + get_registry_coordinator_address(http_endpoint.clone()).await; + let operator_state_retriever_address = + get_operator_state_retriever_address(http_endpoint.clone()).await; + let service_manager_address = get_service_manager_address(http_endpoint.clone()).await; + let provider = get_provider(http_endpoint.as_str()); let salt: FixedBytes<32> = FixedBytes::from([0x02; 32]); let quorum_nums = Bytes::from(test_data.input.quorum_numbers); let quorum_threshold_percentages: QuorumThresholdPercentages = @@ -127,13 +117,13 @@ pub mod integration_test { get_test_logger(), registry_coordinator_address, operator_state_retriever_address, - HTTP_ENDPOINT.to_string(), + http_endpoint.clone(), ) .await .unwrap(); let avs_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - HTTP_ENDPOINT.to_string(), + http_endpoint.clone(), PRIVATE_KEY_1.to_string(), registry_coordinator_address, operator_state_retriever_address, @@ -144,7 +134,7 @@ pub mod integration_test { let operators_info = OperatorInfoServiceInMemory::new( get_test_logger(), avs_registry_reader.clone(), - WS_ENDPOINT.to_string(), + ws_endpoint, ) .await; @@ -156,7 +146,7 @@ pub mod integration_test { // Create quorum let contract_registry_coordinator = RegistryCoordinator::new( registry_coordinator_address, - get_signer(PRIVATE_KEY_1.to_string(), HTTP_ENDPOINT), + get_signer(PRIVATE_KEY_1.to_string(), http_endpoint.as_str()), ); let operator_set_params = OperatorSetParam { maxOperatorCount: 10, @@ -164,7 +154,7 @@ pub mod integration_test { kickBIPsOfTotalStake: 1000, }; let strategy_params = StrategyParams { - strategy: get_erc20_mock_strategy().await, + strategy: get_erc20_mock_strategy(http_endpoint.clone()).await, multiplier: 1, }; let _ = contract_registry_coordinator @@ -186,7 +176,7 @@ pub mod integration_test { .unwrap(); // Sleep is needed so registered operators are accesible to the OperatorInfoServiceInMemory - sleep(Duration::from_millis(500)); + sleep(Duration::from_secs(3)).await; // Create aggregation service let avs_registry_service = @@ -194,7 +184,7 @@ pub mod integration_test { let bls_agg_service = BlsAggregatorService::new(avs_registry_service); let current_block_num = provider.get_block_number().await.unwrap(); - mine_anvil_block(); + mine_anvil_blocks(&container, 1).await; // Create the task related parameters let task_index: TaskIndex = 0; @@ -249,12 +239,15 @@ pub mod integration_test { } #[tokio::test] - #[serial] async fn test_1_quorum_2_operators() { - let registry_coordinator_address = get_registry_coordinator_address().await; - let operator_state_retriever_address = get_operator_state_retriever_address().await; - let service_manager_address = get_service_manager_address().await; - let provider = get_provider(HTTP_ENDPOINT); + let (container, http_endpoint, ws_endpoint) = start_anvil_container().await; + + let registry_coordinator_address = + get_registry_coordinator_address(http_endpoint.clone()).await; + let operator_state_retriever_address = + get_operator_state_retriever_address(http_endpoint.clone()).await; + let service_manager_address = get_service_manager_address(http_endpoint.clone()).await; + let provider = get_provider(http_endpoint.as_str()); let salt: FixedBytes<32> = FixedBytes::from([0x02; 32]); let bls_key_pair_1 = BlsKeyPair::new(BLS_KEY_1.to_string()).unwrap(); @@ -270,7 +263,7 @@ pub mod integration_test { let contract_registry_coordinator = RegistryCoordinator::new( registry_coordinator_address, - get_signer(PRIVATE_KEY_1.to_string(), HTTP_ENDPOINT), + get_signer(PRIVATE_KEY_1.to_string(), http_endpoint.as_str()), ); // Create quorum @@ -280,7 +273,7 @@ pub mod integration_test { kickBIPsOfTotalStake: 1000, }; let strategy_params = vec![StrategyParams { - strategy: get_erc20_mock_strategy().await, + strategy: get_erc20_mock_strategy(http_endpoint.clone()).await, multiplier: 1, }]; let _ = contract_registry_coordinator @@ -294,14 +287,14 @@ pub mod integration_test { get_test_logger(), registry_coordinator_address, operator_state_retriever_address, - HTTP_ENDPOINT.to_string(), + http_endpoint.clone(), ) .await .unwrap(); let avs_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - HTTP_ENDPOINT.to_string(), + http_endpoint.clone(), PRIVATE_KEY_1.to_string(), registry_coordinator_address, operator_state_retriever_address, @@ -311,7 +304,7 @@ pub mod integration_test { let operators_info = OperatorInfoServiceInMemory::new( get_test_logger(), avs_registry_reader.clone(), - WS_ENDPOINT.to_string(), + ws_endpoint, ) .await; @@ -339,7 +332,7 @@ pub mod integration_test { let avs_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - HTTP_ENDPOINT.to_string(), + http_endpoint, PRIVATE_KEY_2.to_string(), registry_coordinator_address, operator_state_retriever_address, @@ -358,7 +351,7 @@ pub mod integration_test { .unwrap(); // Sleep is needed so registered operators are accesible to the OperatorInfoServiceInMemory - sleep(Duration::from_millis(500)); + sleep(Duration::from_secs(3)).await; // Create aggregation service let avs_registry_service = @@ -368,11 +361,11 @@ pub mod integration_test { let current_block_num = provider.get_block_number().await.unwrap(); - mine_anvil_block(); + mine_anvil_blocks(&container, 1).await; // Create the task related parameters let task_index: TaskIndex = 0; - let time_to_expiry = Duration::from_secs(1); + let time_to_expiry = Duration::from_secs(3); // Initialize the task bls_agg_service @@ -440,14 +433,17 @@ pub mod integration_test { } #[tokio::test] - #[serial] async fn test_2_quorums_2_operators_separated() { // operator 1 stakes on quorum 2 // operator 2 stakes on quorum 3 - let registry_coordinator_address = get_registry_coordinator_address().await; - let operator_state_retriever_address = get_operator_state_retriever_address().await; - let service_manager_address = get_service_manager_address().await; - let provider = get_provider(HTTP_ENDPOINT); + let (container, http_endpoint, ws_endpoint) = start_anvil_container().await; + + let registry_coordinator_address = + get_registry_coordinator_address(http_endpoint.clone()).await; + let operator_state_retriever_address = + get_operator_state_retriever_address(http_endpoint.clone()).await; + let service_manager_address = get_service_manager_address(http_endpoint.clone()).await; + let provider = get_provider(http_endpoint.as_str()); let salt: FixedBytes<32> = FixedBytes::from([0x02; 32]); let bls_key_pair_1 = BlsKeyPair::new(BLS_KEY_1.to_string()).unwrap(); @@ -463,7 +459,7 @@ pub mod integration_test { let contract_registry_coordinator = RegistryCoordinator::new( registry_coordinator_address, - get_signer(PRIVATE_KEY_1.to_string(), HTTP_ENDPOINT), + get_signer(PRIVATE_KEY_1.to_string(), http_endpoint.as_str()), ); // Create quorums @@ -473,7 +469,7 @@ pub mod integration_test { kickBIPsOfTotalStake: 1000, }; let strategy_params = vec![StrategyParams { - strategy: get_erc20_mock_strategy().await, + strategy: get_erc20_mock_strategy(http_endpoint.clone()).await, multiplier: 1, }]; let _ = contract_registry_coordinator @@ -497,14 +493,14 @@ pub mod integration_test { get_test_logger(), registry_coordinator_address, operator_state_retriever_address, - HTTP_ENDPOINT.to_string(), + http_endpoint.clone(), ) .await .unwrap(); let avs_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - HTTP_ENDPOINT.to_string(), + http_endpoint.clone(), PRIVATE_KEY_1.to_string(), registry_coordinator_address, operator_state_retriever_address, @@ -515,7 +511,7 @@ pub mod integration_test { let operators_info = OperatorInfoServiceInMemory::new( get_test_logger(), avs_registry_reader.clone(), - WS_ENDPOINT.to_string(), + ws_endpoint, ) .await; @@ -539,7 +535,7 @@ pub mod integration_test { let avs_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( // TODO: check if needed get_test_logger(), - HTTP_ENDPOINT.to_string(), + http_endpoint, PRIVATE_KEY_2.to_string(), registry_coordinator_address, operator_state_retriever_address, @@ -558,7 +554,7 @@ pub mod integration_test { .unwrap(); // Sleep is needed so registered operators are accesible to the OperatorInfoServiceInMemory - sleep(Duration::from_millis(500)); + sleep(Duration::from_secs(3)).await; // Create aggregation service let avs_registry_service = @@ -568,7 +564,7 @@ pub mod integration_test { let current_block_num = provider.get_block_number().await.unwrap(); - mine_anvil_block(); + mine_anvil_blocks(&container, 1).await; // Create the task related parameters let task_index: TaskIndex = 0; diff --git a/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs b/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs index 9d5d8366..54d98ede 100644 --- a/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs +++ b/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs @@ -290,6 +290,7 @@ mod tests { use eigen_client_elcontracts::{reader::ELChainReader, writer::ELChainWriter}; use eigen_crypto_bls::BlsKeyPair; use eigen_logging::get_test_logger; + use eigen_testing_utils::anvil::start_anvil_container; use eigen_testing_utils::anvil_constants::{ get_avs_directory_address, get_delegation_manager_address, get_operator_state_retriever_address, get_registry_coordinator_address, @@ -297,17 +298,15 @@ mod tests { }; use eigen_types::operator::Operator; use eigen_utils::get_provider; - use serial_test::serial; use std::str::FromStr; - use std::time::{Duration, SystemTime, UNIX_EPOCH}; + use std::time::{SystemTime, UNIX_EPOCH}; #[tokio::test] - #[serial] async fn test_query_past_registered_operator_events_and_fill_db() { - let anvil_ws_url = "ws://localhost:8545"; - let anvil_http_url = "http://localhost:8545"; + let (_container, http_endpoint, ws_endpoint) = start_anvil_container().await; let test_logger = get_test_logger(); register_operator( + http_endpoint.clone(), "0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6", "202646553755999769005569871314544341631930435075911377994162443131009480062", ) @@ -315,9 +314,9 @@ mod tests { let avs_registry_chain_reader = AvsRegistryChainReader::new( test_logger.clone(), - get_registry_coordinator_address().await, - get_operator_state_retriever_address().await, - anvil_http_url.to_string(), + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, + http_endpoint.clone(), ) .await .unwrap(); @@ -325,18 +324,16 @@ mod tests { let operators_info_service_in_memory = OperatorInfoServiceInMemory::new( test_logger.clone(), avs_registry_chain_reader, - anvil_ws_url.to_string(), + ws_endpoint, ) .await; + let end_block = get_provider(http_endpoint.as_str()) + .get_block_number() + .await + .unwrap(); let _ = operators_info_service_in_memory - .query_past_registered_operator_events_and_fill_db( - 0, - get_provider(anvil_http_url) - .get_block_number() - .await - .unwrap(), - ) + .query_past_registered_operator_events_and_fill_db(0, end_block) .await; let address = address!("90f79bf6eb2c4f870365e785982e1f101e93b906"); @@ -347,47 +344,53 @@ mod tests { } #[tokio::test] - #[serial] async fn test_start_service_1_operator_register() { - let anvil_ws_url = "ws://localhost:8545"; - let anvil_http_url = "http://localhost:8545"; + // start anvil in a container + let (_container, http_endpoint, ws_endpoint) = start_anvil_container().await; let test_logger = get_test_logger(); let avs_registry_chain_reader = AvsRegistryChainReader::new( test_logger.clone(), - get_registry_coordinator_address().await, - get_operator_state_retriever_address().await, - anvil_http_url.to_string(), + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, + http_endpoint.clone(), ) .await .unwrap(); + let operators_info_service_in_memory = OperatorInfoServiceInMemory::new( test_logger.clone(), avs_registry_chain_reader, - anvil_ws_url.to_string(), + ws_endpoint, ) .await; let clone_operators_info = operators_info_service_in_memory.clone(); let token = tokio_util::sync::CancellationToken::new().clone(); let cancel_token = token.clone(); + let cloned_http_endpoint = http_endpoint.clone(); + tokio::spawn(async move { let _ = clone_operators_info .start_service( &token, 0, - get_provider(anvil_http_url) + get_provider(cloned_http_endpoint.as_str()) .get_block_number() .await .unwrap(), ) .await; }); + register_operator( + http_endpoint, "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", "12248929636257230549931416853095037629726205319386239410403476017439825112537", ) .await; - tokio::time::sleep(Duration::from_secs(1)).await; // need to wait atleast 1 second to get the event processed + + // need to wait at least 3 seconds to get the event processed + tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; cancel_token.clone().cancel(); @@ -399,35 +402,34 @@ mod tests { } #[tokio::test] - #[serial] async fn test_start_service_2_operator_register() { - let anvil_ws_url = "ws://localhost:8545"; - let anvil_http_url = "http://localhost:8545"; + let (_container, http_endpoint, ws_endpoint) = start_anvil_container().await; let test_logger = get_test_logger(); let avs_registry_chain_reader = AvsRegistryChainReader::new( test_logger.clone(), - get_registry_coordinator_address().await, - get_operator_state_retriever_address().await, - anvil_http_url.to_string(), + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, + http_endpoint.clone(), ) .await .unwrap(); let operators_info_service_in_memory = OperatorInfoServiceInMemory::new( test_logger.clone(), avs_registry_chain_reader, - anvil_ws_url.to_string(), + ws_endpoint, ) .await; let clone_operators_info = operators_info_service_in_memory.clone(); let token = tokio_util::sync::CancellationToken::new().clone(); let cancel_token = token.clone(); + let cloned_http_endpoint = http_endpoint.clone(); tokio::spawn(async move { let _ = clone_operators_info .start_service( &token, 0, - get_provider(anvil_http_url) + get_provider(cloned_http_endpoint.as_str()) .get_block_number() .await .unwrap(), @@ -435,16 +437,18 @@ mod tests { .await; }); register_operator( + http_endpoint.clone(), "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", "1328790040692576325258580129229001772890358018148159309458854770206210226319", ) .await; register_operator( + http_endpoint, "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a", "8949062771264691130193054363356855357736539613420316273398900351143637925935", ) .await; - tokio::time::sleep(Duration::from_secs(1)).await; // need to wait atleast 1 second to get the event processed + tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; // need to wait atleast 3 second to get the event processed cancel_token.clone().cancel(); @@ -461,18 +465,17 @@ mod tests { assert!(operator_info_2.unwrap().is_some()); } - pub async fn register_operator(pvt_key: &str, bls_key: &str) { - let anvil_http_url = "http://localhost:8545"; - - let delegation_manager_address = get_delegation_manager_address().await; - let avs_directory_address = get_avs_directory_address().await; - let strategy_manager_address = get_strategy_manager_address().await; + pub async fn register_operator(http_endpoint: String, pvt_key: &str, bls_key: &str) { + let delegation_manager_address = + get_delegation_manager_address(http_endpoint.clone()).await; + let avs_directory_address = get_avs_directory_address(http_endpoint.clone()).await; + let strategy_manager_address = get_strategy_manager_address(http_endpoint.clone()).await; let el_chain_reader = ELChainReader::new( get_test_logger(), Address::ZERO, delegation_manager_address, avs_directory_address, - anvil_http_url.to_string(), + http_endpoint.to_string(), ); let signer = PrivateKeySigner::from_str(pvt_key).unwrap(); @@ -480,7 +483,7 @@ mod tests { delegation_manager_address, strategy_manager_address, el_chain_reader, - anvil_http_url.to_string(), + http_endpoint.to_string(), pvt_key.to_string(), ); @@ -499,10 +502,10 @@ mod tests { let avs_registry_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - anvil_http_url.to_string(), + http_endpoint.to_string(), pvt_key.to_string(), - get_registry_coordinator_address().await, - get_operator_state_retriever_address().await, + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, ) .await .unwrap(); diff --git a/examples/anvil-utils/examples/get_contracts_from_registry.rs b/examples/anvil-utils/examples/get_contracts_from_registry.rs index ab60fde4..546a4065 100644 --- a/examples/anvil-utils/examples/get_contracts_from_registry.rs +++ b/examples/anvil-utils/examples/get_contracts_from_registry.rs @@ -1,18 +1,24 @@ //! Example to showcase testing EL contracts using anvil -use eigen_testing_utils::anvil_constants::{ - get_delegation_manager_address, get_erc20_mock_strategy, get_operator_state_retriever_address, - get_registry_coordinator_address, get_service_manager_address, get_strategy_manager_address, +use eigen_testing_utils::{ + anvil::start_anvil_container, + anvil_constants::{ + get_delegation_manager_address, get_erc20_mock_strategy, + get_operator_state_retriever_address, get_registry_coordinator_address, + get_service_manager_address, get_strategy_manager_address, + }, }; use eyre::Result; /// Calling ContractsRegistry contract to extract the El contract addresses on anvil #[tokio::main] pub async fn main() -> Result<()> { - get_service_manager_address().await; - get_registry_coordinator_address().await; - get_operator_state_retriever_address().await; - get_delegation_manager_address().await; - get_strategy_manager_address().await; - get_erc20_mock_strategy().await; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; + + get_service_manager_address(http_endpoint.clone()).await; + get_registry_coordinator_address(http_endpoint.clone()).await; + get_operator_state_retriever_address(http_endpoint.clone()).await; + get_delegation_manager_address(http_endpoint.clone()).await; + get_strategy_manager_address(http_endpoint.clone()).await; + get_erc20_mock_strategy(http_endpoint).await; Ok(()) } diff --git a/examples/info-operator-service/examples/get_operator_info.rs b/examples/info-operator-service/examples/get_operator_info.rs index ff56c8d0..b23ca529 100644 --- a/examples/info-operator-service/examples/get_operator_info.rs +++ b/examples/info-operator-service/examples/get_operator_info.rs @@ -10,10 +10,13 @@ use eigen_logging::get_test_logger; use eigen_services_operatorsinfo::{ operator_info::OperatorInfoService, operatorsinfo_inmemory::OperatorInfoServiceInMemory, }; -use eigen_testing_utils::anvil_constants::{ - get_avs_directory_address, get_delegation_manager_address, - get_operator_state_retriever_address, get_registry_coordinator_address, - get_strategy_manager_address, +use eigen_testing_utils::{ + anvil::start_anvil_container, + anvil_constants::{ + get_avs_directory_address, get_delegation_manager_address, + get_operator_state_retriever_address, get_registry_coordinator_address, + get_strategy_manager_address, + }, }; use std::{ str::FromStr, @@ -22,26 +25,22 @@ use std::{ use tokio::{task, time::Duration}; use tokio_util::sync::CancellationToken; -const ANVIL_HTTP_URL: &str = "http://localhost:8545"; -const ANVIL_WS_URL: &str = "ws://localhost:8545"; - #[tokio::main] async fn main() { + let (_container, http_endpoint, ws_endpoint) = start_anvil_container().await; + let avs_registry_chain_reader = AvsRegistryChainReader::new( get_test_logger().clone(), - get_registry_coordinator_address().await, - get_operator_state_retriever_address().await, - ANVIL_HTTP_URL.to_string(), + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint.clone()).await, + http_endpoint, ) .await .expect("failed to build avs registry chain reader"); - let operators_info = OperatorInfoServiceInMemory::new( - get_test_logger(), - avs_registry_chain_reader, - ANVIL_WS_URL.to_string(), - ) - .await; + let operators_info = + OperatorInfoServiceInMemory::new(get_test_logger(), avs_registry_chain_reader, ws_endpoint) + .await; let operators_info_clone = operators_info.clone(); let cancellation_token: CancellationToken = CancellationToken::new(); @@ -69,17 +68,17 @@ async fn main() { } pub async fn register_operator(pvt_key: &str, bls_key: &str) { - let anvil_http_url = "http://localhost:8545"; + let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await; - let delegation_manager_address = get_delegation_manager_address().await; - let avs_directory_address = get_avs_directory_address().await; - let strategy_manager_address = get_strategy_manager_address().await; + let delegation_manager_address = get_delegation_manager_address(http_endpoint.clone()).await; + let avs_directory_address = get_avs_directory_address(http_endpoint.clone()).await; + let strategy_manager_address = get_strategy_manager_address(http_endpoint.clone()).await; let el_chain_reader = ELChainReader::new( get_test_logger(), Address::ZERO, delegation_manager_address, avs_directory_address, - anvil_http_url.to_string(), + http_endpoint.clone(), ); let signer = PrivateKeySigner::from_str(pvt_key).unwrap(); @@ -87,7 +86,7 @@ pub async fn register_operator(pvt_key: &str, bls_key: &str) { delegation_manager_address, strategy_manager_address, el_chain_reader, - anvil_http_url.to_string(), + http_endpoint.to_string(), pvt_key.to_string(), ); @@ -106,10 +105,10 @@ pub async fn register_operator(pvt_key: &str, bls_key: &str) { let avs_registry_writer = AvsRegistryChainWriter::build_avs_registry_chain_writer( get_test_logger(), - anvil_http_url.to_string(), + http_endpoint.to_string(), pvt_key.to_string(), - get_registry_coordinator_address().await, - get_operator_state_retriever_address().await, + get_registry_coordinator_address(http_endpoint.clone()).await, + get_operator_state_retriever_address(http_endpoint).await, ) .await .unwrap(); diff --git a/testing/testing-utils/Cargo.toml b/testing/testing-utils/Cargo.toml index 8ad3c079..33c0c6e4 100644 --- a/testing/testing-utils/Cargo.toml +++ b/testing/testing-utils/Cargo.toml @@ -21,3 +21,4 @@ once_cell.workspace = true serde.workspace = true serde_json.workspace = true tokio.workspace = true +testcontainers.workspace = true diff --git a/testing/testing-utils/src/anvil.rs b/testing/testing-utils/src/anvil.rs new file mode 100644 index 00000000..c090115f --- /dev/null +++ b/testing/testing-utils/src/anvil.rs @@ -0,0 +1,82 @@ +use std::path::{Path, PathBuf}; +use testcontainers::{ + core::{ExecCommand, IntoContainerPort, WaitFor}, + runners::AsyncRunner, + ContainerAsync, GenericImage, ImageExt, +}; + +const ANVIL_IMAGE: &str = "ghcr.io/foundry-rs/foundry"; +const ANVIL_TAG: &str = "nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a"; +const ANVIL_STATE_PATH: &str = "./crates/contracts/anvil/contracts_deployed_anvil_state.json"; // relative path from the project root + +fn workspace_dir() -> PathBuf { + let output = std::process::Command::new(env!("CARGO")) + .arg("locate-project") + .arg("--workspace") + .arg("--message-format=plain") + .output() + .unwrap() + .stdout; + let cargo_path = Path::new(std::str::from_utf8(&output).unwrap().trim()); + cargo_path.parent().unwrap().to_path_buf() +} + +/// Start an Anvil container for testing with contract state loaded. +pub async fn start_anvil_container() -> (ContainerAsync, String, String) { + let relative_path = PathBuf::from(ANVIL_STATE_PATH); + let absolute_path = workspace_dir().join(relative_path); + let absolute_path_str = absolute_path.to_str().unwrap(); + + let container = GenericImage::new(ANVIL_IMAGE, ANVIL_TAG) + .with_wait_for(WaitFor::message_on_stdout("Listening on")) + .with_exposed_port(8545.tcp()) + .with_entrypoint("anvil") + .with_mount(testcontainers::core::Mount::bind_mount( + absolute_path_str, + "/contracts_deployed_anvil_state.json", + )) + .with_cmd([ + "--host", + "0.0.0.0", + "--load-state", + "/contracts_deployed_anvil_state.json", + "--base-fee", + "0", + "--gas-price", + "0", + ]) + .start() + .await + .expect("Error starting anvil container"); + + let port = container + .ports() + .await + .unwrap() + .map_to_host_port_ipv4(8545) + .unwrap(); + + let http_endpoint = format!("http://localhost:{}", port); + let ws_endpoint = format!("ws://localhost:{}", port); + + mine_anvil_blocks(&container, 200).await; + + (container, http_endpoint, ws_endpoint) +} + +/// Mine Anvil blocks. +pub async fn mine_anvil_blocks(container: &ContainerAsync, n: u32) { + let mut output = container + .exec(ExecCommand::new([ + "cast", + "rpc", + "anvil_mine", + n.to_string().as_str(), + ])) + .await + .expect("Failed to mine anvil blocks"); + + // blocking operation until the mining execution finishes + output.stdout_to_vec().await.unwrap(); + assert_eq!(output.exit_code().await.unwrap().unwrap(), 0); +} diff --git a/testing/testing-utils/src/anvil_constants.rs b/testing/testing-utils/src/anvil_constants.rs index 7d7bafbd..d86efb62 100644 --- a/testing/testing-utils/src/anvil_constants.rs +++ b/testing/testing-utils/src/anvil_constants.rs @@ -36,8 +36,8 @@ pub static ANVIL_RPC_URL: Lazy< > = Lazy::new(|| get_provider(ANVIL_HTTP_URL)); /// Service Manager contract address -pub async fn get_service_manager_address() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_service_manager_address(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("mockAvsServiceManager".to_string()) @@ -50,8 +50,8 @@ pub async fn get_service_manager_address() -> Address { } /// Registry Coordinator contract address -pub async fn get_registry_coordinator_address() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_registry_coordinator_address(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("mockAvsRegistryCoordinator".to_string()) @@ -65,8 +65,8 @@ pub async fn get_registry_coordinator_address() -> Address { } /// Operator state retriever contract address -pub async fn get_operator_state_retriever_address() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_operator_state_retriever_address(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("mockAvsOperatorStateRetriever".to_string()) @@ -80,8 +80,8 @@ pub async fn get_operator_state_retriever_address() -> Address { } /// Delegation Manager contract address -pub async fn get_delegation_manager_address() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_delegation_manager_address(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("delegationManager".to_string()) @@ -95,8 +95,8 @@ pub async fn get_delegation_manager_address() -> Address { } /// Strategy Mananger contract address -pub async fn get_strategy_manager_address() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_strategy_manager_address(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("strategyManager".to_string()) @@ -110,8 +110,8 @@ pub async fn get_strategy_manager_address() -> Address { } /// Avs Directory contract address -pub async fn get_avs_directory_address() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_avs_directory_address(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("avsDirectory".to_string()) @@ -125,8 +125,8 @@ pub async fn get_avs_directory_address() -> Address { } /// erc20 mock strategy contract address -pub async fn get_erc20_mock_strategy() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_erc20_mock_strategy(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("erc20MockStrategy".to_string()) @@ -140,8 +140,8 @@ pub async fn get_erc20_mock_strategy() -> Address { } /// proxy admin contract address -pub async fn get_proxy_admin() -> Address { - let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, (*ANVIL_RPC_URL).clone()); +pub async fn get_proxy_admin(rpc_url: String) -> Address { + let contracts_registry = ContractsRegistry::new(CONTRACTS_REGISTRY, get_provider(&rpc_url)); let val = contracts_registry .contracts("ProxyAdmin".to_string()) diff --git a/testing/testing-utils/src/lib.rs b/testing/testing-utils/src/lib.rs index ffa6d32c..c2874a92 100644 --- a/testing/testing-utils/src/lib.rs +++ b/testing/testing-utils/src/lib.rs @@ -21,3 +21,8 @@ pub mod test_data; /// Transaction utilities for testing. pub mod transaction; + +/// Anvil utilities for testing. +#[allow(clippy::unwrap_used)] +#[allow(clippy::expect_used)] +pub mod anvil; diff --git a/testing/testing-utils/src/transaction.rs b/testing/testing-utils/src/transaction.rs index 34b1dd06..f2ff357c 100644 --- a/testing/testing-utils/src/transaction.rs +++ b/testing/testing-utils/src/transaction.rs @@ -1,6 +1,6 @@ -use super::anvil_constants::ANVIL_RPC_URL; use alloy_primitives::FixedBytes; use alloy_provider::Provider; +use eigen_utils::get_provider; use tokio::time::{sleep, Duration}; /// Retrieves the status of a transaction from its hash. @@ -12,10 +12,10 @@ use tokio::time::{sleep, Duration}; /// # Returns /// /// A bool indicating wether the transaction was successful or not. -pub async fn get_transaction_status(tx_hash: FixedBytes<32>) -> bool { +pub async fn get_transaction_status(rpc_url: String, tx_hash: FixedBytes<32>) -> bool { // this sleep is needed so that we wait for the tx to be processed sleep(Duration::from_millis(500)).await; - ANVIL_RPC_URL + get_provider(&rpc_url) .clone() .get_transaction_receipt(tx_hash) .await