From f3a9f3299a26366931c6b25761abdb1c8cfc72cd Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 23 Oct 2024 18:26:00 -0300 Subject: [PATCH] Fix TxManager, InstrumentedClient, Signer tests (#150) As foundry is no longer required, this PR updates some tests to run using an Anvil container. Also, changed Anvil version on tests to `latest`. NOTE: this version works fine for AMD architectures but is not listed for ARM, so to run tests locally the image needs to be build manually, due to [this foundry issue](https://github.com/foundry-rs/foundry/issues/8039) --- Cargo.lock | 6 +-- crates/chainio/clients/eth/Cargo.toml | 1 - .../clients/eth/src/instrumented_client.rs | 26 ++++----- crates/chainio/txmanager/Cargo.toml | 4 +- .../txmanager/src/simple_tx_manager.rs | 53 +++++++------------ crates/signer/Cargo.toml | 1 - crates/signer/src/signer.rs | 15 +++--- testing/testing-utils/src/anvil.rs | 2 +- 8 files changed, 40 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44295128..68f5bb5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2258,11 +2258,9 @@ name = "eigen-chainio-txmanager" version = "0.1.0" dependencies = [ "alloy", - "alloy-consensus", - "alloy-node-bindings", - "alloy-primitives", "eigen-logging", "eigen-signer", + "eigen-testing-utils", "k256", "once_cell", "reqwest 0.12.7", @@ -2355,7 +2353,6 @@ version = "0.1.0" dependencies = [ "alloy", "alloy-json-rpc", - "alloy-node-bindings", "alloy-primitives", "alloy-rlp", "async-trait", @@ -2580,7 +2577,6 @@ dependencies = [ "alloy", "alloy-consensus", "alloy-network", - "alloy-node-bindings", "alloy-primitives", "alloy-rpc-client", "alloy-signer", diff --git a/crates/chainio/clients/eth/Cargo.toml b/crates/chainio/clients/eth/Cargo.toml index 23f2ecb3..fac702eb 100644 --- a/crates/chainio/clients/eth/Cargo.toml +++ b/crates/chainio/clients/eth/Cargo.toml @@ -20,7 +20,6 @@ thiserror.workspace = true url.workspace = true [dev-dependencies] -alloy-node-bindings.workspace = true eigen-signer.workspace = true eigen-testing-utils.workspace = true eigen-utils.workspace = true diff --git a/crates/chainio/clients/eth/src/instrumented_client.rs b/crates/chainio/clients/eth/src/instrumented_client.rs index 9c5c101d..ffcef19e 100644 --- a/crates/chainio/clients/eth/src/instrumented_client.rs +++ b/crates/chainio/clients/eth/src/instrumented_client.rs @@ -834,12 +834,12 @@ mod tests { use alloy::rpc::types::eth::{ pubsub::SubscriptionResult, BlockId, BlockNumberOrTag, BlockTransactionsKind, }; - use alloy_node_bindings::Anvil; + use alloy_primitives::address; use eigen_signer::signer::Config; use eigen_testing_utils::anvil::start_anvil_container; use eigen_utils::get_provider; - use std::{thread, time}; - use tokio; + use tokio::time::sleep; + use tokio::{self, time}; #[tokio::test] async fn test_suggest_gas_tip_cap() { @@ -1006,29 +1006,23 @@ mod tests { /// * `transaction_in_block` #[tokio::test] 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(); - + let (_container, rpc_url, _ws_endpoint) = start_anvil_container().await; let instrumented_client = InstrumentedClient::new(&rpc_url).await.unwrap(); - let addresses = anvil.addresses().to_vec(); - let private_key = anvil.keys().first().unwrap(); - let to = addresses.first().unwrap(); // build the transaction + let to = address!("a0Ee7A142d267C1f36714E4a8F75612F20a79720"); let mut tx = TxLegacy { - to: Call(*to), + to: Call(to), value: U256::from(0), gas_limit: 2_000_000, - nonce: 0, + nonce: 0x69, // nonce queried from the sender account gas_price: 21_000_000_000, input: bytes!(), chain_id: Some(31337), }; - let private_key_hex = hex::encode(private_key.to_bytes()); + let private_key_hex = + "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".to_string(); let config = Config::PrivateKey(private_key_hex); let signer = Config::signer_from_config(config).unwrap(); let signature = signer.sign_transaction_sync(&mut tx).unwrap(); @@ -1045,7 +1039,7 @@ mod tests { assert!(tx_by_hash.is_ok()); // this sleep is needed because we have to wait since the transaction is not ready yet - thread::sleep(time::Duration::from_secs(1)); + sleep(time::Duration::from_secs(1)).await; // test transaction_receipt let receipt = instrumented_client.transaction_receipt(tx_hash).await; diff --git a/crates/chainio/txmanager/Cargo.toml b/crates/chainio/txmanager/Cargo.toml index 10b6e9dc..38079ddf 100644 --- a/crates/chainio/txmanager/Cargo.toml +++ b/crates/chainio/txmanager/Cargo.toml @@ -16,8 +16,6 @@ reqwest.workspace = true thiserror.workspace = true [dev-dependencies] -alloy-primitives.workspace = true -alloy-consensus.workspace = true -alloy-node-bindings.workspace = true +eigen-testing-utils.workspace = true once_cell.workspace = true tokio.workspace = true diff --git a/crates/chainio/txmanager/src/simple_tx_manager.rs b/crates/chainio/txmanager/src/simple_tx_manager.rs index 814cebaf..c7ca490b 100644 --- a/crates/chainio/txmanager/src/simple_tx_manager.rs +++ b/crates/chainio/txmanager/src/simple_tx_manager.rs @@ -293,41 +293,34 @@ mod tests { use super::SimpleTxManager; use alloy::consensus::TxLegacy; use alloy::network::TransactionBuilder; + use alloy::primitives::{address, bytes, TxKind::Call, U256}; use alloy::rpc::types::eth::TransactionRequest; - use alloy_node_bindings::Anvil; - use alloy_primitives::{bytes, TxKind::Call, U256}; use eigen_logging::get_test_logger; - use tokio; + use eigen_testing_utils::anvil::start_anvil_container; #[tokio::test] async fn test_send_transaction_from_legacy() { - let anvil = Anvil::new().try_spawn().unwrap(); - let rpc_url: String = anvil.endpoint().parse().unwrap(); + let (_container, rpc_url, _ws_endpoint) = start_anvil_container().await; let logger = get_test_logger(); - let private_key = anvil.keys().first().unwrap(); - let simple_tx_manager = SimpleTxManager::new( - logger, - 1.0, - private_key.as_scalar_primitive().to_string().as_str(), - rpc_url.as_str(), - ) - .unwrap(); - - let addresses = anvil.addresses().to_vec(); - let to = addresses.first().cloned().unwrap(); + let private_key = + "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".to_string(); + let simple_tx_manager = + SimpleTxManager::new(logger, 1.0, private_key.as_str(), rpc_url.as_str()).unwrap(); + let to = address!("a0Ee7A142d267C1f36714E4a8F75612F20a79720"); + let account_nonce = 0x69; // nonce queried from the sender account let tx = TxLegacy { to: Call(to), value: U256::from(1_000_000_000), gas_limit: 2_000_000, - nonce: 0, + nonce: account_nonce, gas_price: 21_000_000_000, input: bytes!(), chain_id: Some(31337), }; - let mut tx_request: TransactionRequest = tx.clone().into(); + let mut tx_request: TransactionRequest = tx.into(); // send transaction and wait for receipt let receipt = simple_tx_manager.send_tx(&mut tx_request).await.unwrap(); let block_number = receipt.block_number.unwrap(); @@ -338,32 +331,26 @@ mod tests { #[tokio::test] async fn test_send_transaction_from_eip1559() { - let anvil = Anvil::new().try_spawn().unwrap(); - let rpc_url: String = anvil.endpoint().parse().unwrap(); + let (_container, rpc_url, _ws_endpoint) = start_anvil_container().await; let logger = get_test_logger(); - let private_key = anvil.keys().first().unwrap(); - let simple_tx_manager = SimpleTxManager::new( - logger, - 1.0, - private_key.as_scalar_primitive().to_string().as_str(), - rpc_url.as_str(), - ) - .unwrap(); - - let addresses = anvil.addresses().to_vec(); - let to = addresses.first().cloned().unwrap(); + let private_key = + "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".to_string(); + let simple_tx_manager = + SimpleTxManager::new(logger, 1.0, private_key.as_str(), rpc_url.as_str()).unwrap(); + let to = address!("a0Ee7A142d267C1f36714E4a8F75612F20a79720"); + let account_nonce = 0x69; // nonce queried from the sender account let mut tx = TransactionRequest::default() .with_to(to) - .with_nonce(0) + .with_nonce(account_nonce) .with_chain_id(31337) .with_value(U256::from(100)) .with_gas_limit(21_000) .with_max_priority_fee_per_gas(1_000_000_000) .with_max_fee_per_gas(20_000_000_000); - tx.set_gas_price(21_000_000_000); + // send transaction and wait for receipt let receipt = simple_tx_manager.send_tx(&mut tx).await.unwrap(); let block_number = receipt.block_number.unwrap(); diff --git a/crates/signer/Cargo.toml b/crates/signer/Cargo.toml index 62596774..87b15426 100644 --- a/crates/signer/Cargo.toml +++ b/crates/signer/Cargo.toml @@ -24,7 +24,6 @@ thiserror.workspace = true url.workspace = true [dev-dependencies] -alloy-node-bindings.workspace = true aws-config.workspace = true eigen-testing-utils.workspace = true testcontainers.workspace = true diff --git a/crates/signer/src/signer.rs b/crates/signer/src/signer.rs index 10468892..6106dec2 100644 --- a/crates/signer/src/signer.rs +++ b/crates/signer/src/signer.rs @@ -70,7 +70,6 @@ mod test { use alloy::network::{TxSigner, TxSignerSync}; use alloy::signers::local::PrivateKeySigner; use alloy::signers::Signature; - use alloy_node_bindings::Anvil; use alloy_primitives::{address, bytes, hex_literal::hex, keccak256, Address, U256}; use aws_config::{BehaviorVersion, Region, SdkConfig}; use aws_sdk_kms::{ @@ -78,6 +77,7 @@ mod test { config::{Credentials, SharedCredentialsProvider}, types::KeyMetadata, }; + use eigen_testing_utils::anvil::start_anvil_container; use eigen_testing_utils::test_data::TestData; use std::str::FromStr; use testcontainers::{ @@ -202,25 +202,24 @@ mod test { #[tokio::test] async fn test_sign_legacy_transaction_with_web3_signer() { - let anvil = Anvil::default().spawn(); + let (_container, endpoint, _ws_endpoint) = start_anvil_container().await; - let endpoint = anvil.endpoint(); - let address = anvil.addresses()[0]; + let address = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); let signer = Config::web3_signer(endpoint, address).unwrap(); let mut tx = TxLegacy { - to: anvil.addresses()[1].into(), + to: address!("a0Ee7A142d267C1f36714E4a8F75612F20a79720").into(), value: U256::from(1_000_000_000), gas_limit: 0x76c0, gas_price: 21_000_000_000, nonce: 0, input: bytes!(), - chain_id: Some(anvil.chain_id()), + chain_id: Some(31337), }; let signature = signer.sign_transaction(&mut tx).await.unwrap(); - let private_key = anvil.keys()[0].clone(); - let expected_signer = PrivateKeySigner::from_field_bytes(&private_key.to_bytes()).unwrap(); + let private_key_hex = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + let expected_signer = PrivateKeySigner::from_str(private_key_hex).unwrap(); let expected_signature = expected_signer.sign_transaction_sync(&mut tx).unwrap(); assert_eq!(signature, expected_signature); diff --git a/testing/testing-utils/src/anvil.rs b/testing/testing-utils/src/anvil.rs index c090115f..9390d55b 100644 --- a/testing/testing-utils/src/anvil.rs +++ b/testing/testing-utils/src/anvil.rs @@ -6,7 +6,7 @@ use testcontainers::{ }; const ANVIL_IMAGE: &str = "ghcr.io/foundry-rs/foundry"; -const ANVIL_TAG: &str = "nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a"; +const ANVIL_TAG: &str = "latest"; const ANVIL_STATE_PATH: &str = "./crates/contracts/anvil/contracts_deployed_anvil_state.json"; // relative path from the project root fn workspace_dir() -> PathBuf {