From af5047e9e458ef9bb0470ada80ce22261a2b21b8 Mon Sep 17 00:00:00 2001 From: Tjemmmic Date: Thu, 22 Aug 2024 15:12:57 -0500 Subject: [PATCH] Update Tests --- Cargo.lock | 1 + avs/incredible-squaring-avs/build.rs | 7 +- avs/incredible-squaring-avs/src/operator.rs | 53 +++++---- avs/tangle-avs/build.rs | 7 +- avs/tangle-avs/src/operator.rs | 91 +++++++++------ test-utils/Cargo.toml | 3 +- test-utils/build.rs | 56 --------- test-utils/src/anvil/anvil_node.rs | 2 +- test-utils/src/anvil/testnet/tangle.rs | 123 ++++++++++++++------ test-utils/src/bin/incredible_squaring.rs | 34 +++--- test-utils/src/bin/tangle.rs | 34 +++--- 11 files changed, 212 insertions(+), 199 deletions(-) delete mode 100644 test-utils/build.rs diff --git a/Cargo.lock b/Cargo.lock index a77ca10..61107a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11714,6 +11714,7 @@ dependencies = [ "hyper 1.4.1", "incredible-squaring-avs", "k256", + "lazy_static", "log", "nix 0.28.0", "prometheus", diff --git a/avs/incredible-squaring-avs/build.rs b/avs/incredible-squaring-avs/build.rs index 9f8b1b2..122809f 100644 --- a/avs/incredible-squaring-avs/build.rs +++ b/avs/incredible-squaring-avs/build.rs @@ -4,12 +4,7 @@ use std::process::Command; fn main() { // List of directories containing Solidity contracts - let contract_dirs = vec![ - // "./../../contracts/lib/eigenlayer-middleware/lib/eigenlayer-contracts", - // "./../../contracts/lib/eigenlayer-middleware", - // "./../../contracts/", - "./contracts", - ]; + let contract_dirs = vec!["./contracts"]; // Get the project root directory let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); diff --git a/avs/incredible-squaring-avs/src/operator.rs b/avs/incredible-squaring-avs/src/operator.rs index 8a5d93e..0e84bd0 100644 --- a/avs/incredible-squaring-avs/src/operator.rs +++ b/avs/incredible-squaring-avs/src/operator.rs @@ -277,28 +277,6 @@ impl Operator { .get_operator_id(operator_address) .await?; - log::info!( - "Operator info: operatorId={}, operatorAddr={}, operatorG1Pubkey={:?}, operatorG2Pubkey={:?}", - hex::encode(operator_id), - operator_address, - bls_keypair.clone().get_pub_key_g1(), - bls_keypair.clone().get_pub_key_g2(), - ); - - let operator = Operator { - config: config.clone(), - node_api, - avs_registry_contract_manager: avs_registry_contract_manager.clone(), - incredible_squaring_contract_manager, - eigenlayer_contract_manager: eigenlayer_contract_manager.clone(), - bls_keypair: bls_keypair.clone(), - operator_id, - operator_addr: operator_address, - aggregator_server_ip_port_addr: config.server_ip_port_address.clone(), - aggregator_server: aggregator_service, - aggregator_rpc_client, - }; - // Register Operator with EigenLayer let register_operator = eigen_utils::types::Operator { address: operator_address, @@ -335,9 +313,40 @@ impl Operator { .unwrap(); log::info!("Is operator registered: {:?}", answer); + log::info!( + "Operator info: operatorId={}, operatorAddr={}, operatorG1Pubkey={:?}, operatorG2Pubkey={:?}", + hex::encode(operator_id), + operator_address, + bls_keypair.clone().get_pub_key_g1(), + bls_keypair.clone().get_pub_key_g2(), + ); + + let operator = Operator { + config: config.clone(), + node_api, + avs_registry_contract_manager: avs_registry_contract_manager.clone(), + incredible_squaring_contract_manager, + eigenlayer_contract_manager: eigenlayer_contract_manager.clone(), + bls_keypair, + operator_id, + operator_addr: operator_address, + aggregator_server_ip_port_addr: config.server_ip_port_address.clone(), + aggregator_server: aggregator_service, + aggregator_rpc_client, + }; + Ok(operator) } + pub async fn is_registered(&self) -> Result { + let operator_is_registered = self + .avs_registry_contract_manager + .is_operator_registered(self.operator_addr) + .await?; + log::info!("Operator registration status: {:?}", operator_is_registered); + Ok(operator_is_registered) + } + pub async fn start(self) -> Result<(), OperatorError> { log::info!("Starting operator."); let operator_is_registered = self diff --git a/avs/tangle-avs/build.rs b/avs/tangle-avs/build.rs index 9f8b1b2..122809f 100644 --- a/avs/tangle-avs/build.rs +++ b/avs/tangle-avs/build.rs @@ -4,12 +4,7 @@ use std::process::Command; fn main() { // List of directories containing Solidity contracts - let contract_dirs = vec![ - // "./../../contracts/lib/eigenlayer-middleware/lib/eigenlayer-contracts", - // "./../../contracts/lib/eigenlayer-middleware", - // "./../../contracts/", - "./contracts", - ]; + let contract_dirs = vec!["./contracts"]; // Get the project root directory let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); diff --git a/avs/tangle-avs/src/operator.rs b/avs/tangle-avs/src/operator.rs index 5b11fc7..b3c6d2f 100644 --- a/avs/tangle-avs/src/operator.rs +++ b/avs/tangle-avs/src/operator.rs @@ -1,5 +1,5 @@ use alloy_contract::private::Ethereum; -use alloy_primitives::{Address, ChainId, Signature, B256}; +use alloy_primitives::{Address, Bytes, ChainId, Signature, B256}; use alloy_provider::{Provider, RootProvider}; use alloy_signer_local::PrivateKeySigner; use alloy_transport::BoxTransport; @@ -7,6 +7,8 @@ use eigen_utils::avs_registry::reader::AvsRegistryChainReaderTrait; use eigen_utils::avs_registry::writer::AvsRegistryChainWriterTrait; use eigen_utils::avs_registry::AvsRegistryContractManager; use eigen_utils::crypto::bls::KeyPair; +use eigen_utils::el_contracts::writer::ElWriter; +use eigen_utils::el_contracts::ElChainContractManager; use eigen_utils::node_api::NodeApi; use eigen_utils::types::AvsError; use eigen_utils::Config; @@ -42,6 +44,8 @@ pub enum OperatorError { OperatorIdError(String), #[error("Error in Operator Address: {0}")] OperatorAddressError(String), + #[error("Error while Starting Operator: {0}")] + OperatorStartError(String), #[error( "Operator is not registered. Register using the operator-cli before starting operator." )] @@ -146,15 +150,6 @@ impl Config for NodeConfig { type S = EigenTangleSigner; } -#[derive(Clone)] -pub struct TangleValidatorContractManager { - pub task_manager_addr: Address, - pub service_manager_addr: Address, - pub eth_client_http: T::PH, - pub eth_client_ws: T::PW, - pub signer: T::S, -} - #[derive(Debug, Clone)] pub struct SetupConfig { pub registry_coordinator_addr: Address, @@ -229,30 +224,52 @@ impl Operator { Address::from_str(&config.tangle_validator_service_manager_address) .map_err(|err| OperatorError::ServiceManagerAddressError(err.to_string()))?; - // let tangle_validator_contract_manager = TangleValidatorContractManager::build( - // setup_config.registry_coordinator_addr, - // setup_config.operator_state_retriever_addr, - // eth_client_http.clone(), - // eth_client_ws.clone(), - // signer.clone(), - // ) - // .await?; - - // if config.register_operator_on_startup { - // operator.register_operator_on_startup( - // operator_ecdsa_private_key, - // config.token_strategy_addr.parse()?, - // ); - // } - - let _register_result = avs_registry_contract_manager + log::info!("Building Eigenlayer Contract Manager..."); + let eigenlayer_contract_manager: ElChainContractManager = ElChainContractManager::build( + setup_config.delegate_manager_addr, + setup_config.avs_directory_addr, + eth_client_http.clone(), + eth_client_ws.clone(), + signer.clone(), + ) + .await + .unwrap(); + + // Register Operator with EigenLayer + let register_operator = eigen_utils::types::Operator { + address: operator_addr, + earnings_receiver_address: operator_addr, + delegation_approver_address: Address::from([0u8; 20]), + staker_opt_out_window_blocks: 50400u32, // About 7 days in blocks on Ethereum + metadata_url: "https://github.com/webb-tools/eigensdk-rs/blob/donovan/eigen/test-utils/metadata.json".to_string(), + }; + let eigenlayer_register_result = eigenlayer_contract_manager + .register_as_operator(register_operator) + .await + .unwrap() + .status(); + log::info!( + "Eigenlayer Registration result: {:?}", + eigenlayer_register_result + ); + + // Register Operator with AVS + let quorum_nums = Bytes::from([0x00]); + let register_result = avs_registry_contract_manager .register_operator( &ecdsa_signing_key, &bls_keypair, - alloy_primitives::Bytes::from(vec![0]), - "127.0.0.1:8545".to_string(), + quorum_nums, + config.eth_rpc_url.clone(), ) .await; + log::info!("AVS Registration result: {:?}", register_result); + + let answer = avs_registry_contract_manager + .is_operator_registered(operator_addr) + .await + .unwrap(); + log::info!("Is operator registered: {:?}", answer); let operator = Operator { config: config.clone(), @@ -274,17 +291,19 @@ impl Operator { Ok(operator) } - pub async fn start(&self) -> Result<(), OperatorError> { - log::info!("Starting operator."); + pub async fn is_registered(&self) -> Result { let operator_is_registered = self .avs_registry_contract_manager .is_operator_registered(self.operator_addr) .await?; log::info!("Operator registration status: {:?}", operator_is_registered); + Ok(operator_is_registered) + } + + pub async fn start(&self) -> Result<(), OperatorError> { + log::info!("Starting operator."); + self.is_registered().await?; - if !operator_is_registered { - return Err(OperatorError::OperatorNotRegistered); - } if self.config.enable_node_api { if let Err(e) = self.node_api.start().await { return Err(OperatorError::NodeApiError(e.to_string())); @@ -292,7 +311,9 @@ impl Operator { } log::info!("Starting Tangle Validator..."); - gadget_executor::run_tangle_validator().await.unwrap(); + gadget_executor::run_tangle_validator() + .await + .map_err(|e| OperatorError::OperatorStartError(e.to_string()))?; Ok(()) } diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index e5d19ed..7fd52ba 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -75,4 +75,5 @@ url.workspace = true #ark-ff.workspace = true ark-bn254.workspace = true sha3 = "0.10.8" -nix = "0.28.0" \ No newline at end of file +nix = "0.28.0" +lazy_static = "1.5.0" \ No newline at end of file diff --git a/test-utils/build.rs b/test-utils/build.rs deleted file mode 100644 index bd228f9..0000000 --- a/test-utils/build.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::env; -use std::path::PathBuf; -use std::process::Command; - -fn main() { - // List of directories containing Solidity contracts - let contract_dirs: Vec<&str> = vec![ - // "./../../contracts/lib/eigenlayer-middleware/lib/eigenlayer-contracts", - // "./../../contracts/lib/eigenlayer-middleware", - // "./../../contracts/", - ]; - - // Get the project root directory - let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); - - // Try to find the `forge` executable dynamically - let forge_executable = match Command::new("which").arg("forge").output() { - Ok(output) => { - let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); - if path.is_empty() { - panic!("Forge executable not found. Make sure Foundry is installed."); - } - path - } - Err(_) => panic!("Failed to locate `forge` executable. Make sure Foundry is installed."), - }; - - for dir in contract_dirs { - let full_path = root.join(dir).canonicalize().unwrap_or_else(|_| { - println!( - "Directory not found or inaccessible: {}", - root.join(dir).display() - ); - root.join(dir) - }); - - if full_path.exists() { - println!("cargo:rerun-if-changed={}", full_path.display()); - - let status = Command::new(&forge_executable) - .current_dir(&full_path) - .arg("build") - .status() - .expect("Failed to execute Forge build"); - - if !status.success() { - panic!("Forge build failed for directory: {}", full_path.display()); - } - } else { - println!( - "Directory not found or does not exist: {}", - full_path.display() - ); - } - } -} diff --git a/test-utils/src/anvil/anvil_node.rs b/test-utils/src/anvil/anvil_node.rs index e3c3f2b..bd5257a 100644 --- a/test-utils/src/anvil/anvil_node.rs +++ b/test-utils/src/anvil/anvil_node.rs @@ -309,7 +309,7 @@ mod tests { #[test] fn assert_chain_id_without_rpc() { - let anvil = Anvil::new().spawn(); + let anvil = Anvil::new().chain_id(31337u64).spawn(); assert_eq!(anvil.chain_id(), 31337); } } diff --git a/test-utils/src/anvil/testnet/tangle.rs b/test-utils/src/anvil/testnet/tangle.rs index cbb7c14..8a3796b 100644 --- a/test-utils/src/anvil/testnet/tangle.rs +++ b/test-utils/src/anvil/testnet/tangle.rs @@ -27,6 +27,8 @@ pub struct ContractAddresses { } /// Spawns and runs an Anvil node, deploying the Smart Contracts that are relevant to the Tangle AVS to it. +/// +/// NOTE: This function will Panic upon contract deployment failure. pub async fn run_tangle_testnet() -> ContractAddresses { // Initialize the logger let _ = env_logger::try_init(); @@ -54,13 +56,13 @@ pub async fn run_tangle_testnet() -> ContractAddresses { // Deploy initial contracts that don't depend on others let istrategy_manager = IStrategyManager::deploy(provider.clone()).await.unwrap(); - let &strategy_manager_addr = istrategy_manager.address(); + let &_strategy_manager_addr = istrategy_manager.address(); let idelegation_manager = IDelegationManager::deploy(provider.clone()).await.unwrap(); let &delegation_manager_addr = idelegation_manager.address(); let iavs_directory = IAVSDirectory::deploy(provider.clone()).await.unwrap(); - let &avs_directory_addr = iavs_directory.address(); + let &_avs_directory_addr = iavs_directory.address(); let proxy_admin = ProxyAdmin::deploy_builder(provider.clone()) .from(dev_account) @@ -92,11 +94,14 @@ pub async fn run_tangle_testnet() -> ContractAddresses { // Function with signature initialize(uint256,uint256,address,address) and selector 0x019e2729. let function_signature = "initialize(uint256,uint256,address,address)"; - let mut hasher = Keccak256::new(); - hasher.update(function_signature); - let function_selector = &hasher.finalize()[..4]; - let encoded_data = encode_params!(function_selector, 1, 100, ierc20_addr, pauser_registry_addr); + let encoded_data = encode_params!( + function_signature, + 1, + 100, + ierc20_addr, + pauser_registry_addr + ); let strategy_proxy = TransparentUpgradeableProxy::deploy( provider.clone(), @@ -127,6 +132,7 @@ pub async fn run_tangle_testnet() -> ContractAddresses { // Deploy Incredible Squaring Contracts let number_of_strategies = strategies.len(); + println!("Number of Strategies: {:?}", number_of_strategies); let tangle_validator_proxy_admin = ProxyAdmin::deploy_builder(provider.clone()) .from(dev_account) @@ -240,6 +246,83 @@ pub async fn run_tangle_testnet() -> ContractAddresses { .unwrap(); let &operator_state_retriever_addr = operator_state_retriever.address(); + let eth_pos = IETHPOSDeposit::deploy(provider.clone()).await.unwrap(); + let ð_pos_addr = eth_pos.address(); + + let eigen_pod_beacon = IBeacon::deploy(provider.clone()).await.unwrap(); + let &eigen_pod_beacon_addr = eigen_pod_beacon.address(); + + let strategy_manager = StrategyManager::new( + *TransparentUpgradeableProxy::deploy( + provider.clone(), + empty_contract_addr, + tangle_validator_proxy_admin_addr, + Bytes::from(""), + ) + .await + .unwrap() + .address(), + provider.clone(), + ); + let &strategy_manager_addr = strategy_manager.address(); + + let eigen_pod_manager = EigenPodManager::deploy( + provider.clone(), + eth_pos_addr, + eigen_pod_beacon_addr, + strategy_manager_addr, + from, + delegation_manager_addr, + ) + .await + .unwrap(); + let &eigen_pod_manager_addr = eigen_pod_manager.address(); + + let slasher_addr = dev_account; + let delegation_manager = DelegationManager::deploy( + provider.clone(), + strategy_manager_addr, + slasher_addr, + eigen_pod_manager_addr, + ) + .await + .unwrap(); + let &delegation_manager_addr = delegation_manager.address(); + + let strategy_manager_implementation = StrategyManager::deploy( + provider.clone(), + delegation_manager_addr, + eigen_pod_manager_addr, + slasher_addr, + ) + .await + .unwrap(); + let &strategy_manager_implementation_addr = strategy_manager_implementation.address(); + let strategy_manager_upgrade = tangle_validator_proxy_admin + .upgrade(strategy_manager_addr, strategy_manager_implementation_addr) + .send() + .await + .unwrap() + .get_receipt() + .await + .unwrap(); + assert!(strategy_manager_upgrade.status()); + + let strategy_manager_initialization = strategy_manager + .initialize(pausers[0], pausers[0], pauser_registry_addr, U256::from(0)) + .send() + .await + .unwrap() + .get_receipt() + .await + .unwrap(); + assert!(strategy_manager_initialization.status()); + + let avs_directory = AVSDirectory::deploy(provider.clone(), delegation_manager_addr) + .await + .unwrap(); + let &avs_directory_addr = avs_directory.address(); + // Now, deploy the implementation contracts using the proxy contracts as inputs let stake_registry_implementation = StakeRegistry::deploy( provider.clone(), @@ -428,34 +511,6 @@ pub async fn run_tangle_testnet() -> ContractAddresses { .unwrap(); assert!(tangle_validator_task_manager_upgrade.status()); - let eigen_pod_manager = EigenPodManager::deploy( - provider.clone(), - empty_contract_addr, - empty_contract_addr, - strategy_manager_addr, - from, - delegation_manager_addr, - ) - .await - .unwrap(); - let &eigen_pod_manager_addr = eigen_pod_manager.address(); - - let slasher_addr = dev_account; - let delegation_manager = DelegationManager::deploy( - provider.clone(), - strategy_manager_addr, - slasher_addr, - eigen_pod_manager_addr, - ) - .await - .unwrap(); - let &delegation_manager_addr = delegation_manager.address(); - - let avs_directory = AVSDirectory::deploy(provider.clone(), delegation_manager_addr) - .await - .unwrap(); - let &avs_directory_addr = avs_directory.address(); - log::info!("ERC20MOCK ADDRESS: {:?}", erc20_mock_addr); log::info!("ERC20MOCK STRATEGY ADDRESS: {:?}", erc20_mock_strategy_addr); log::info!( diff --git a/test-utils/src/bin/incredible_squaring.rs b/test-utils/src/bin/incredible_squaring.rs index 252b55c..7c51667 100644 --- a/test-utils/src/bin/incredible_squaring.rs +++ b/test-utils/src/bin/incredible_squaring.rs @@ -11,7 +11,7 @@ use test_utils::anvil::testnet::incredible_squaring::*; #[tokio::main] async fn main() { let _ = env_logger::try_init(); - run_full_incredible_squaring_test().await; + run_incredible_squaring_testnet().await; } /// Sets up an Operator, given the [ContractAddresses] for the running Testnet you would like utilize @@ -85,20 +85,6 @@ async fn operator_setup( .unwrap() } -/// THIS FUNCTION IS FOR TESTING ONLY -/// -/// Runs the Incredible Squaring Testnet and then creates an Operator that connects and registers. -async fn run_full_incredible_squaring_test() { - let _ = env_logger::try_init(); - - // Runs new Anvil Testnet - used for deploying programmatically in rust - let contract_addresses = run_incredible_squaring_testnet().await; - - let operator = operator_setup(contract_addresses).await; - - operator.start().await.unwrap(); -} - #[cfg(test)] mod tests { use super::*; @@ -114,14 +100,24 @@ mod tests { } #[tokio::test] - async fn test_full_incredible_squaring() { + async fn test_incredible_squaring_deployment() { env_init(); - run_full_incredible_squaring_test().await; + let _ = run_incredible_squaring_testnet().await; } #[tokio::test] - async fn test_incredible_squaring_deployment() { + async fn test_incredible_squaring_full() { env_init(); - let _ = run_incredible_squaring_testnet().await; + + // Runs new Anvil Testnet - used for deploying programmatically in rust + let contract_addresses = run_incredible_squaring_testnet().await; + + // Sets up the Operator + let operator = operator_setup(contract_addresses).await; + + // Check that the operator has registered successfully + assert!(operator.is_registered().await.unwrap()); + + log::info!("Operator Successfully Registered. The Tangle Validator would now start."); } } diff --git a/test-utils/src/bin/tangle.rs b/test-utils/src/bin/tangle.rs index 97a5e85..8b5c4f3 100644 --- a/test-utils/src/bin/tangle.rs +++ b/test-utils/src/bin/tangle.rs @@ -11,7 +11,7 @@ use test_utils::anvil::testnet::tangle::*; #[tokio::main] async fn main() { let _ = env_logger::try_init(); - run_full_tangle_test().await; + run_tangle_testnet().await; } /// Sets up an Operator, given the [ContractAddresses] for the running Testnet you would like utilize @@ -79,20 +79,6 @@ async fn operator_setup(contract_addresses: ContractAddresses) -> Operator