diff --git a/crates/anvil/core/src/eth/transaction/ethers_compat.rs b/crates/anvil/core/src/eth/transaction/ethers_compat.rs index 88e87a9d7cde..50bb60b45981 100644 --- a/crates/anvil/core/src/eth/transaction/ethers_compat.rs +++ b/crates/anvil/core/src/eth/transaction/ethers_compat.rs @@ -26,6 +26,23 @@ use ethers_core::types::{ }; use foundry_common::types::{ToAlloy, ToEthers}; +pub fn to_alloy_signature(signature: ethers_core::types::Signature) -> alloy_rpc_types::Signature { + alloy_rpc_types::Signature { + r: signature.r.to_alloy(), + s: signature.s.to_alloy(), + v: signature.v.to_alloy().to::(), + y_parity: None, + } +} + +pub fn to_ethers_signature(signature: alloy_rpc_types::Signature) -> ethers_core::types::Signature { + ethers_core::types::Signature { + r: signature.r.to_ethers(), + s: signature.s.to_ethers(), + v: signature.v.to::(), + } +} + pub fn to_alloy_proof(proof: AccountProof) -> alloy_rpc_types::EIP1186AccountProofResponse { alloy_rpc_types::EIP1186AccountProofResponse { address: proof.address.to_alloy(), diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs index ef67a4667d71..5fa6d1fc0bfd 100644 --- a/crates/anvil/core/src/eth/transaction/mod.rs +++ b/crates/anvil/core/src/eth/transaction/mod.rs @@ -26,13 +26,18 @@ use std::ops::Deref; mod ethers_compat; pub use ethers_compat::{ - call_to_internal_tx_request, from_ethers_access_list, to_alloy_proof, to_ethers_access_list, + call_to_internal_tx_request, from_ethers_access_list, to_alloy_proof, to_alloy_signature, + to_ethers_access_list, to_ethers_signature, }; /// The signature used to bypass signing via the `eth_sendUnsignedTransaction` cheat RPC #[cfg(feature = "impersonated-tx")] -pub const IMPERSONATED_SIGNATURE: Signature = - Signature { r: U256([0, 0, 0, 0]), s: U256([0, 0, 0, 0]), v: 0 }; +pub const IMPERSONATED_SIGNATURE: alloy_rpc_types::Signature = alloy_rpc_types::Signature { + r: alloy_primitives::U256::ZERO, + s: alloy_primitives::U256::ZERO, + v: alloy_primitives::U256::ZERO, + y_parity: None, +}; /// Container type for various Ethereum transaction requests /// @@ -789,7 +794,7 @@ impl TypedTransaction { /// Returns true if the transaction was impersonated (using the impersonate Signature) #[cfg(feature = "impersonated-tx")] pub fn is_impersonated(&self) -> bool { - self.signature() == IMPERSONATED_SIGNATURE + to_alloy_signature(self.signature()) == IMPERSONATED_SIGNATURE } /// Returns the hash if the transaction is impersonated (using a fake signature) diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs index c90bdc3bc912..a814258d5469 100644 --- a/crates/anvil/src/eth/api.rs +++ b/crates/anvil/src/eth/api.rs @@ -46,8 +46,9 @@ use anvil_core::{ eth::{ block::BlockInfo, transaction::{ - call_to_internal_tx_request, to_alloy_proof, EthTransactionRequest, LegacyTransaction, - PendingTransaction, TransactionKind, TypedTransaction, TypedTransactionRequest, + call_to_internal_tx_request, to_alloy_proof, to_ethers_signature, + EthTransactionRequest, LegacyTransaction, PendingTransaction, TransactionKind, + TypedTransaction, TypedTransactionRequest, }, EthRequest, }, @@ -564,9 +565,15 @@ impl EthApi { pub fn accounts(&self) -> Result> { node_info!("eth_accounts"); let mut unique = HashSet::new(); - let mut accounts = Vec::new(); + let mut accounts: Vec
= Vec::new(); for signer in self.signers.iter() { - accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc))); + accounts.extend( + signer + .accounts() + .into_iter() + .map(|a| a.to_alloy()) + .filter(|acc| unique.insert(*acc)), + ); } accounts.extend( self.backend @@ -575,7 +582,7 @@ impl EthApi { .into_iter() .filter(|acc| unique.insert(*acc)), ); - Ok(accounts.into_iter().map(|acc| acc.to_alloy()).collect()) + Ok(accounts.into_iter().collect()) } /// Returns the number of most recent block. @@ -897,7 +904,8 @@ impl EthApi { // if the sender is currently impersonated we need to "bypass" signing let pending_transaction = if self.is_impersonated(from) { let bypass_signature = self.backend.cheats().bypass_signature(); - let transaction = sign::build_typed_transaction(request, bypass_signature)?; + let transaction = + sign::build_typed_transaction(request, to_ethers_signature(bypass_signature))?; self.ensure_typed_transaction_supported(&transaction)?; trace!(target : "node", ?from, "eth_sendTransaction: impersonating"); PendingTransaction::with_impersonated(transaction, from.to_ethers()) @@ -1993,7 +2001,8 @@ impl EthApi { let request = self.build_typed_tx_request(request, nonce)?; let bypass_signature = self.backend.cheats().bypass_signature(); - let transaction = sign::build_typed_transaction(request, bypass_signature)?; + let transaction = + sign::build_typed_transaction(request, to_ethers_signature(bypass_signature))?; self.ensure_typed_transaction_supported(&transaction)?; @@ -2528,7 +2537,7 @@ impl EthApi { /// Returns true if the `addr` is currently impersonated pub fn is_impersonated(&self, addr: Address) -> bool { - self.backend.cheats().is_impersonated(addr.to_ethers()) + self.backend.cheats().is_impersonated(addr) } /// Returns the nonce of the `address` depending on the `block_number` diff --git a/crates/anvil/src/eth/backend/cheats.rs b/crates/anvil/src/eth/backend/cheats.rs index 68cbd8706ba6..a3cde4ccbd3e 100644 --- a/crates/anvil/src/eth/backend/cheats.rs +++ b/crates/anvil/src/eth/backend/cheats.rs @@ -1,7 +1,8 @@ //! Support for "cheat codes" / bypass functions +use alloy_primitives::Address; +use alloy_rpc_types::Signature; use anvil_core::eth::transaction::IMPERSONATED_SIGNATURE; -use ethers::types::{Address, Signature}; use foundry_evm::hashbrown::HashSet; use parking_lot::RwLock; use std::sync::Arc; diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index d55f06041287..8af81395a726 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -310,20 +310,20 @@ impl Backend { /// /// Returns `true` if the account is already impersonated pub async fn impersonate(&self, addr: Address) -> DatabaseResult { - if self.cheats.impersonated_accounts().contains(&addr.to_ethers()) { + if self.cheats.impersonated_accounts().contains(&addr) { return Ok(true); } // Ensure EIP-3607 is disabled let mut env = self.env.write(); env.cfg.disable_eip3607 = true; - Ok(self.cheats.impersonate(addr.to_ethers())) + Ok(self.cheats.impersonate(addr)) } /// Removes the account that from the impersonated set /// /// If the impersonated `addr` is a contract then we also reset the code here pub async fn stop_impersonating(&self, addr: Address) -> DatabaseResult<()> { - self.cheats.stop_impersonating(&addr.to_ethers()); + self.cheats.stop_impersonating(&addr); Ok(()) }