From f032cc87f8fc7949d3f34b2199bf885ade6fe91c Mon Sep 17 00:00:00 2001 From: Maxim Shishmarev Date: Fri, 17 Nov 2023 14:16:04 +1100 Subject: [PATCH 1/5] refactor: split eth rpc client into signing and non-signing --- engine/src/eth/retry_rpc.rs | 8 +- engine/src/eth/rpc.rs | 177 +++++++++++++----- engine/src/eth/rpc/address_checker.rs | 4 +- engine/src/witness/eth/contract_common.rs | 6 +- engine/src/witness/eth/key_manager.rs | 4 +- engine/src/witness/eth/state_chain_gateway.rs | 4 +- engine/src/witness/eth/vault.rs | 4 +- 7 files changed, 141 insertions(+), 66 deletions(-) diff --git a/engine/src/eth/retry_rpc.rs b/engine/src/eth/retry_rpc.rs index 1fc02a584f..2fbb09a730 100644 --- a/engine/src/eth/retry_rpc.rs +++ b/engine/src/eth/retry_rpc.rs @@ -9,7 +9,7 @@ use utilities::task_scope::Scope; use crate::{ common::option_inner, - eth::rpc::EthRpcApi, + eth::rpc::{EthRpcApi, EthSigningRpcApi}, retrier::{Attempt, RequestLog, RetrierClient}, settings::{NodeContainer, WsHttpEndpoints}, witness::common::chain_source::{ChainClient, Header}, @@ -17,7 +17,7 @@ use crate::{ use std::{path::PathBuf, time::Duration}; use super::{ - rpc::{EthRpcClient, ReconnectSubscriptionClient}, + rpc::{EthRpcSigningClient, ReconnectSubscriptionClient}, ConscientiousEthWebsocketBlockHeaderStream, }; use crate::eth::rpc::ReconnectSubscribeApi; @@ -27,7 +27,7 @@ use anyhow::{Context, Result}; #[derive(Clone)] pub struct EthersRetryRpcClient { - rpc_retry_client: RetrierClient, + rpc_retry_client: RetrierClient, sub_retry_client: RetrierClient, } @@ -45,7 +45,7 @@ impl EthersRetryRpcClient { ) -> Result { let f_create_clients = |endpoints: WsHttpEndpoints| { Result::<_, anyhow::Error>::Ok(( - EthRpcClient::new( + EthRpcSigningClient::new( private_key_file.clone(), endpoints.http_endpoint, expected_chain_id.as_u64(), diff --git a/engine/src/eth/rpc.rs b/engine/src/eth/rpc.rs index c6c9a73547..ee5e32759e 100644 --- a/engine/src/eth/rpc.rs +++ b/engine/src/eth/rpc.rs @@ -20,25 +20,17 @@ struct NonceInfo { #[derive(Clone)] pub struct EthRpcClient { - signer: SignerMiddleware>, LocalWallet>, - nonce_info: Arc>>, + provider: Arc>, } impl EthRpcClient { pub fn new( - private_key_file: PathBuf, http_endpoint: SecretUrl, expected_chain_id: u64, - ) -> Result> { + ) -> anyhow::Result> { let provider = Arc::new(Provider::::try_from(http_endpoint.as_ref())?); - let wallet = - read_clean_and_decode_hex_str_file(&private_key_file, "Ethereum Private Key", |key| { - ethers::signers::Wallet::from_str(key).map_err(anyhow::Error::new) - })?; - let signer = SignerMiddleware::new(provider, wallet.with_chain_id(expected_chain_id)); - - let client = Self { signer, nonce_info: Arc::new(Mutex::new(None)) }; + let client = EthRpcClient { provider }; Ok(async move { // We don't want to return an error here. Returning an error means that we'll exit the @@ -64,6 +56,93 @@ impl EthRpcClient { } }) } +} + +#[async_trait::async_trait] +impl EthRpcApi for EthRpcClient { + async fn estimate_gas(&self, req: &Eip1559TransactionRequest) -> Result { + Ok(self + .provider + .estimate_gas(&TypedTransaction::Eip1559(req.clone()), None) + .await?) + } + + async fn get_logs(&self, filter: Filter) -> Result> { + Ok(self.provider.get_logs(&filter).await?) + } + + async fn chain_id(&self) -> Result { + Ok(self.provider.get_chainid().await?) + } + + async fn transaction_receipt(&self, tx_hash: TxHash) -> Result { + self.provider.get_transaction_receipt(tx_hash).await?.ok_or_else(|| { + anyhow!("Getting ETH transaction receipt for tx hash {tx_hash} returned None") + }) + } + + /// Gets block, returning error when either: + /// - Request fails + /// - Request succeeds, but doesn't return a block + async fn block(&self, block_number: U64) -> Result> { + self.provider.get_block(block_number).await?.ok_or_else(|| { + anyhow!("Getting ETH block for block number {} returned None", block_number) + }) + } + + async fn block_with_txs(&self, block_number: U64) -> Result> { + self.provider.get_block_with_txs(block_number).await?.ok_or_else(|| { + anyhow!("Getting ETH block with txs for block number {} returned None", block_number) + }) + } + + async fn fee_history( + &self, + block_count: U256, + last_block: BlockNumber, + reward_percentiles: &[f64], + ) -> Result { + Ok(self.provider.fee_history(block_count, last_block, reward_percentiles).await?) + } + + async fn get_transaction(&self, tx_hash: H256) -> Result { + self.provider + .get_transaction(tx_hash) + .await? + .ok_or_else(|| anyhow!("Getting ETH transaction for tx hash {} returned None", tx_hash)) + } +} + +#[derive(Clone)] +pub struct EthRpcSigningClient { + signer: SignerMiddleware>, LocalWallet>, + rpc_client: EthRpcClient, + nonce_info: Arc>>, +} + +impl EthRpcSigningClient { + pub fn new( + private_key_file: PathBuf, + http_endpoint: SecretUrl, + expected_chain_id: u64, + ) -> Result> { + let rpc_client_fut = EthRpcClient::new(http_endpoint, expected_chain_id)?; + + let wallet = + read_clean_and_decode_hex_str_file(&private_key_file, "Ethereum Private Key", |key| { + ethers::signers::Wallet::from_str(key).map_err(anyhow::Error::new) + })?; + + Ok(async move { + let rpc_client = rpc_client_fut.await; + + let signer = SignerMiddleware::new( + rpc_client.provider.clone(), + wallet.with_chain_id(expected_chain_id), + ); + Self { signer, nonce_info: Arc::new(Mutex::new(None)), rpc_client } + }) + } async fn get_next_nonce(&self) -> Result { let mut nonce_info_lock = self.nonce_info.lock().await; @@ -100,12 +179,8 @@ impl EthRpcClient { #[async_trait::async_trait] pub trait EthRpcApi: Send { - fn address(&self) -> H160; - async fn estimate_gas(&self, req: &Eip1559TransactionRequest) -> Result; - async fn send_transaction(&self, tx: Eip1559TransactionRequest) -> Result; - async fn get_logs(&self, filter: Filter) -> Result>; async fn chain_id(&self) -> Result; @@ -130,56 +205,39 @@ pub trait EthRpcApi: Send { } #[async_trait::async_trait] -impl EthRpcApi for EthRpcClient { - fn address(&self) -> H160 { - self.signer.address() - } - - async fn estimate_gas(&self, req: &Eip1559TransactionRequest) -> Result { - Ok(self.signer.estimate_gas(&TypedTransaction::Eip1559(req.clone()), None).await?) - } - - async fn send_transaction(&self, mut tx: Eip1559TransactionRequest) -> Result { - tx.nonce = Some(self.get_next_nonce().await?); - - let res = self.signer.send_transaction(tx, None).await; +pub trait EthSigningRpcApi: EthRpcApi { + fn address(&self) -> H160; - if res.is_err() { - // Reset the nonce just in case (it will be re-requested during next broadcast) - tracing::warn!("Resetting eth broadcaster nonce due to error"); - *self.nonce_info.lock().await = None; - } + async fn send_transaction(&self, tx: Eip1559TransactionRequest) -> Result; +} - Ok(res?.tx_hash()) +#[async_trait::async_trait] +impl EthRpcApi for EthRpcSigningClient { + async fn estimate_gas(&self, req: &Eip1559TransactionRequest) -> Result { + self.rpc_client.estimate_gas(req).await } async fn get_logs(&self, filter: Filter) -> Result> { - Ok(self.signer.get_logs(&filter).await?) + self.rpc_client.get_logs(filter).await } async fn chain_id(&self) -> Result { - Ok(self.signer.get_chainid().await?) + self.rpc_client.chain_id().await } async fn transaction_receipt(&self, tx_hash: TxHash) -> Result { - self.signer.get_transaction_receipt(tx_hash).await?.ok_or_else(|| { - anyhow!("Getting ETH transaction receipt for tx hash {tx_hash} returned None") - }) + self.rpc_client.transaction_receipt(tx_hash).await } /// Gets block, returning error when either: /// - Request fails /// - Request succeeds, but doesn't return a block async fn block(&self, block_number: U64) -> Result> { - self.signer.get_block(block_number).await?.ok_or_else(|| { - anyhow!("Getting ETH block for block number {block_number} returned None") - }) + self.rpc_client.block(block_number).await } async fn block_with_txs(&self, block_number: U64) -> Result> { - self.signer.get_block_with_txs(block_number).await?.ok_or_else(|| { - anyhow!("Getting ETH block with txs for block number {block_number} returned None") - }) + self.rpc_client.block_with_txs(block_number).await } async fn fee_history( @@ -188,14 +246,31 @@ impl EthRpcApi for EthRpcClient { last_block: BlockNumber, reward_percentiles: &[f64], ) -> Result { - Ok(self.signer.fee_history(block_count, last_block, reward_percentiles).await?) + self.rpc_client.fee_history(block_count, last_block, reward_percentiles).await } async fn get_transaction(&self, tx_hash: H256) -> Result { - self.signer - .get_transaction(tx_hash) - .await? - .ok_or_else(|| anyhow!("Getting ETH transaction for tx hash {tx_hash} returned None")) + self.rpc_client.get_transaction(tx_hash).await + } +} + +#[async_trait::async_trait] +impl EthSigningRpcApi for EthRpcSigningClient { + fn address(&self) -> H160 { + self.signer.address() + } + + async fn send_transaction(&self, mut tx: Eip1559TransactionRequest) -> Result { + tx.nonce = Some(self.get_next_nonce().await?); + + let res = self.signer.send_transaction(tx, None).await; + if res.is_err() { + // Reset the nonce just in case (it will be re-requested during next broadcast) + tracing::warn!("Resetting eth broadcaster nonce due to error"); + *self.nonce_info.lock().await = None; + } + + Ok(res?.tx_hash()) } } @@ -266,7 +341,7 @@ mod tests { async fn eth_rpc_test() { let settings = Settings::new_test().unwrap(); - let client = EthRpcClient::new( + let client = EthRpcSigningClient::new( settings.eth.private_key_file, settings.eth.nodes.primary.http_endpoint, 2u64, diff --git a/engine/src/eth/rpc/address_checker.rs b/engine/src/eth/rpc/address_checker.rs index accb41b336..fd267e8ca8 100644 --- a/engine/src/eth/rpc/address_checker.rs +++ b/engine/src/eth/rpc/address_checker.rs @@ -2,7 +2,7 @@ use ethers::prelude::*; use anyhow::{Ok, Result}; -use super::EthRpcClient; +use super::EthRpcSigningClient; abigen!(AddressChecker, "$CF_ETH_CONTRACT_ABI_ROOT/$CF_ETH_CONTRACT_ABI_TAG/IAddressChecker.json"); @@ -24,7 +24,7 @@ pub trait AddressCheckerRpcApi { } #[async_trait::async_trait] -impl AddressCheckerRpcApi for EthRpcClient { +impl AddressCheckerRpcApi for EthRpcSigningClient { async fn address_states( &self, block_hash: H256, diff --git a/engine/src/witness/eth/contract_common.rs b/engine/src/witness/eth/contract_common.rs index d3aa0bb642..0b3412b7d6 100644 --- a/engine/src/witness/eth/contract_common.rs +++ b/engine/src/witness/eth/contract_common.rs @@ -47,14 +47,14 @@ impl Event( +pub async fn events_at_block( header: Header, contract_address: H160, - eth_rpc: &EthRpcClient, + eth_rpc: &EthRpcSigningClient, ) -> Result>> where EventParameters: std::fmt::Debug + ethers::contract::EthLogDecode + Send + Sync + 'static, - EthRpcClient: EthersRetryRpcApi, + EthRpcSigningClient: EthersRetryRpcApi, { let mut contract_bloom = Bloom::default(); contract_bloom.accrue(BloomInput::Raw(&contract_address.0)); diff --git a/engine/src/witness/eth/key_manager.rs b/engine/src/witness/eth/key_manager.rs index 7a5bb601b6..8404775a55 100644 --- a/engine/src/witness/eth/key_manager.rs +++ b/engine/src/witness/eth/key_manager.rs @@ -48,11 +48,11 @@ impl ChunkedByVaultBuilder { pub fn key_manager_witnessing< ProcessCall, ProcessingFut, - EthRpcClient: EthersRetryRpcApi + ChainClient + Clone, + EthRpcSigningClient: EthersRetryRpcApi + ChainClient + Clone, >( self, process_call: ProcessCall, - eth_rpc: EthRpcClient, + eth_rpc: EthRpcSigningClient, contract_address: H160, ) -> ChunkedByVaultBuilder where diff --git a/engine/src/witness/eth/state_chain_gateway.rs b/engine/src/witness/eth/state_chain_gateway.rs index c31ac8fac3..873fa95102 100644 --- a/engine/src/witness/eth/state_chain_gateway.rs +++ b/engine/src/witness/eth/state_chain_gateway.rs @@ -23,13 +23,13 @@ use anyhow::Result; impl ChunkedByVaultBuilder { pub fn state_chain_gateway_witnessing< - EthRpcClient: EthersRetryRpcApi + ChainClient + Clone, + EthRpcSigningClient: EthersRetryRpcApi + ChainClient + Clone, ProcessCall, ProcessingFut, >( self, process_call: ProcessCall, - eth_rpc: EthRpcClient, + eth_rpc: EthRpcSigningClient, contract_address: H160, ) -> ChunkedByVaultBuilder where diff --git a/engine/src/witness/eth/vault.rs b/engine/src/witness/eth/vault.rs index 09bbb915b1..e7fc013d36 100644 --- a/engine/src/witness/eth/vault.rs +++ b/engine/src/witness/eth/vault.rs @@ -189,13 +189,13 @@ pub fn call_from_event( impl ChunkedByVaultBuilder { pub fn vault_witnessing< - EthRpcClient: EthersRetryRpcApi + ChainClient + Clone, + EthRpcSigningClient: EthersRetryRpcApi + ChainClient + Clone, ProcessCall, ProcessingFut, >( self, process_call: ProcessCall, - eth_rpc: EthRpcClient, + eth_rpc: EthRpcSigningClient, contract_address: EthereumAddress, native_asset: Asset, source_chain: ForeignChain, From 78fd2d9ae2d1b5fb0746f40c8e85e2bfff27b2f0 Mon Sep 17 00:00:00 2001 From: Maxim Shishmarev Date: Fri, 17 Nov 2023 14:25:21 +1100 Subject: [PATCH 2/5] refactor: EthersRetrySigningRpcApi trait --- engine/src/eth/retry_rpc.rs | 139 ++++++++++-------- .../state_chain_observer/sc_observer/mod.rs | 4 +- 2 files changed, 77 insertions(+), 66 deletions(-) diff --git a/engine/src/eth/retry_rpc.rs b/engine/src/eth/retry_rpc.rs index 2fbb09a730..e33a37f0bd 100644 --- a/engine/src/eth/retry_rpc.rs +++ b/engine/src/eth/retry_rpc.rs @@ -81,11 +81,6 @@ impl EthersRetryRpcClient { #[async_trait::async_trait] pub trait EthersRetryRpcApi: Clone { - async fn broadcast_transaction( - &self, - tx: cf_chains::evm::Transaction, - ) -> anyhow::Result; - async fn get_logs(&self, block_hash: H256, contract_address: H160) -> Vec; async fn chain_id(&self) -> U256; @@ -107,68 +102,15 @@ pub trait EthersRetryRpcApi: Clone { } #[async_trait::async_trait] -impl EthersRetryRpcApi for EthersRetryRpcClient { - /// Estimates gas and then sends the transaction to the network. +pub trait EthersRetrySigningRpcApi: EthersRetryRpcApi { async fn broadcast_transaction( &self, tx: cf_chains::evm::Transaction, - ) -> anyhow::Result { - let log = RequestLog::new("broadcast_transaction".to_string(), Some(format!("{tx:?}"))); - self.rpc_retry_client - .request_with_limit( - Box::pin(move |client| { - let tx = tx.clone(); - #[allow(clippy::redundant_async_block)] - Box::pin(async move { - let mut transaction_request = Eip1559TransactionRequest { - to: Some(NameOrAddress::Address(tx.contract)), - data: Some(tx.data.into()), - chain_id: Some(tx.chain_id.into()), - value: Some(tx.value), - max_fee_per_gas: tx.max_fee_per_gas, - max_priority_fee_per_gas: tx.max_priority_fee_per_gas, - // geth uses the latest block gas limit as an upper bound - gas: None, - access_list: AccessList::default(), - from: Some(client.address()), - nonce: None, - }; - - let estimated_gas = client - .estimate_gas(&transaction_request) - .await - .context("Failed to estimate gas")?; - - transaction_request.gas = Some(match tx.gas_limit { - Some(gas_limit) => - if estimated_gas > gas_limit { - return Err(anyhow::anyhow!( - "Estimated gas is greater than the gas limit" - )) - } else { - gas_limit - }, - None => { - // increase the estimate by 33% for normal transactions - estimated_gas - .saturating_mul(U256::from(4u64)) - .checked_div(U256::from(3u64)) - .unwrap() - }, - }); - - client - .send_transaction(transaction_request) - .await - .context("Failed to send ETH transaction") - }) - }), - log, - MAX_BROADCAST_RETRIES, - ) - .await - } + ) -> anyhow::Result; +} +#[async_trait::async_trait] +impl EthersRetryRpcApi for EthersRetryRpcClient { async fn get_logs(&self, block_hash: H256, contract_address: H160) -> Vec { self.rpc_retry_client .request( @@ -275,6 +217,70 @@ impl EthersRetryRpcApi for EthersRetryRpcClient { } } +#[async_trait::async_trait] +impl EthersRetrySigningRpcApi for EthersRetryRpcClient { + /// Estimates gas and then sends the transaction to the network. + async fn broadcast_transaction( + &self, + tx: cf_chains::evm::Transaction, + ) -> anyhow::Result { + let log = RequestLog::new("broadcast_transaction".to_string(), Some(format!("{tx:?}"))); + self.rpc_retry_client + .request_with_limit( + Box::pin(move |client| { + let tx = tx.clone(); + #[allow(clippy::redundant_async_block)] + Box::pin(async move { + let mut transaction_request = Eip1559TransactionRequest { + to: Some(NameOrAddress::Address(tx.contract)), + data: Some(tx.data.into()), + chain_id: Some(tx.chain_id.into()), + value: Some(tx.value), + max_fee_per_gas: tx.max_fee_per_gas, + max_priority_fee_per_gas: tx.max_priority_fee_per_gas, + // geth uses the latest block gas limit as an upper bound + gas: None, + access_list: AccessList::default(), + from: Some(client.address()), + nonce: None, + }; + + let estimated_gas = client + .estimate_gas(&transaction_request) + .await + .context("Failed to estimate gas")?; + + transaction_request.gas = Some(match tx.gas_limit { + Some(gas_limit) => + if estimated_gas > gas_limit { + return Err(anyhow::anyhow!( + "Estimated gas is greater than the gas limit" + )) + } else { + gas_limit + }, + None => { + // increase the estimate by 33% for normal transactions + estimated_gas + .saturating_mul(U256::from(4u64)) + .checked_div(U256::from(3u64)) + .unwrap() + }, + }); + + client + .send_transaction(transaction_request) + .await + .context("Failed to send ETH transaction") + }) + }), + log, + MAX_BROADCAST_RETRIES, + ) + .await + } +} + #[async_trait::async_trait] pub trait EthersRetrySubscribeApi { async fn subscribe_blocks(&self) -> ConscientiousEthWebsocketBlockHeaderStream; @@ -349,12 +355,17 @@ pub mod mocks { } #[async_trait::async_trait] - impl EthersRetryRpcApi for EthRetryRpcClient { + impl EthersRetrySigningRpcApi for EthRetryRpcClient { async fn broadcast_transaction( &self, tx: cf_chains::evm::Transaction, ) -> anyhow::Result; + } + + #[async_trait::async_trait] + impl EthersRetryRpcApi for EthRetryRpcClient { + async fn get_logs(&self, block_hash: H256, contract_address: H160) -> Vec; async fn chain_id(&self) -> U256; diff --git a/engine/src/state_chain_observer/sc_observer/mod.rs b/engine/src/state_chain_observer/sc_observer/mod.rs index 179719f7df..c7c540050d 100644 --- a/engine/src/state_chain_observer/sc_observer/mod.rs +++ b/engine/src/state_chain_observer/sc_observer/mod.rs @@ -26,7 +26,7 @@ use tracing::{debug, error, info, info_span, Instrument}; use crate::{ btc::retry_rpc::BtcRetryRpcApi, dot::retry_rpc::DotRetryRpcApi, - eth::retry_rpc::EthersRetryRpcApi, + eth::retry_rpc::EthersRetrySigningRpcApi, p2p::{PeerInfo, PeerUpdate}, state_chain_observer::client::{ extrinsic_api::{ @@ -238,7 +238,7 @@ pub async fn start< ) -> Result<(), anyhow::Error> where BlockStream: StateChainStreamApi, - EthRpc: EthersRetryRpcApi + Send + Sync + 'static, + EthRpc: EthersRetrySigningRpcApi + Send + Sync + 'static, DotRpc: DotRetryRpcApi + Send + Sync + 'static, BtcRpc: BtcRetryRpcApi + Send + Sync + 'static, EthMultisigClient: MultisigClientApi + Send + Sync + 'static, From bb08904f8880c90905c06b85c13a6afce22ca19c Mon Sep 17 00:00:00 2001 From: Maxim Shishmarev Date: Fri, 17 Nov 2023 15:02:03 +1100 Subject: [PATCH 3/5] refactor: generic eth retry rpc client --- .../src/witnessing/eth.rs | 4 +- engine/src/eth/retry_rpc.rs | 102 ++++++++++++------ engine/src/eth/retry_rpc/address_checker.rs | 7 +- engine/src/eth/rpc.rs | 2 +- engine/src/main.rs | 4 +- engine/src/witness/eth.rs | 4 +- engine/src/witness/eth/contract_common.rs | 6 +- engine/src/witness/eth/ethereum_deposits.rs | 7 +- engine/src/witness/eth/key_manager.rs | 8 +- engine/src/witness/eth/state_chain_gateway.rs | 4 +- engine/src/witness/eth/vault.rs | 4 +- engine/src/witness/start.rs | 4 +- 12 files changed, 102 insertions(+), 54 deletions(-) diff --git a/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs b/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs index c1d116c9a6..81ce50d658 100644 --- a/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs +++ b/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs @@ -4,7 +4,7 @@ use cf_primitives::chains::assets::eth::Asset; use utilities::task_scope; use chainflip_engine::{ - eth::retry_rpc::EthersRetryRpcClient, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, settings::NodeContainer, state_chain_observer::client::{StateChainClient, StateChainStreamApi}, witness::{ @@ -40,7 +40,7 @@ where let eth_client = { let nodes = NodeContainer { primary: settings.eth_node.clone(), backup: None }; - EthersRetryRpcClient::new( + EthersRetryRpcClient::::new( scope, settings.eth_key_path, nodes, diff --git a/engine/src/eth/retry_rpc.rs b/engine/src/eth/retry_rpc.rs index e33a37f0bd..4765a37a3c 100644 --- a/engine/src/eth/retry_rpc.rs +++ b/engine/src/eth/retry_rpc.rs @@ -5,10 +5,10 @@ use ethers::{ types::{transaction::eip2930::AccessList, TransactionReceipt}, }; +use futures_core::Future; use utilities::task_scope::Scope; use crate::{ - common::option_inner, eth::rpc::{EthRpcApi, EthSigningRpcApi}, retrier::{Attempt, RequestLog, RetrierClient}, settings::{NodeContainer, WsHttpEndpoints}, @@ -17,7 +17,7 @@ use crate::{ use std::{path::PathBuf, time::Duration}; use super::{ - rpc::{EthRpcSigningClient, ReconnectSubscriptionClient}, + rpc::{EthRpcClient, EthRpcSigningClient, ReconnectSubscriptionClient}, ConscientiousEthWebsocketBlockHeaderStream, }; use crate::eth::rpc::ReconnectSubscribeApi; @@ -26,8 +26,8 @@ use cf_chains::Ethereum; use anyhow::{Context, Result}; #[derive(Clone)] -pub struct EthersRetryRpcClient { - rpc_retry_client: RetrierClient, +pub struct EthersRetryRpcClient { + rpc_retry_client: RetrierClient, sub_retry_client: RetrierClient, } @@ -36,29 +36,23 @@ const MAX_CONCURRENT_SUBMISSIONS: u32 = 100; const MAX_BROADCAST_RETRIES: Attempt = 2; -impl EthersRetryRpcClient { - pub fn new( +impl EthersRetryRpcClient { + fn from_inner_clients + Send + 'static>( scope: &Scope<'_, anyhow::Error>, - private_key_file: PathBuf, nodes: NodeContainer, expected_chain_id: U256, - ) -> Result { - let f_create_clients = |endpoints: WsHttpEndpoints| { - Result::<_, anyhow::Error>::Ok(( - EthRpcSigningClient::new( - private_key_file.clone(), - endpoints.http_endpoint, - expected_chain_id.as_u64(), - )?, - ReconnectSubscriptionClient::new(endpoints.ws_endpoint, expected_chain_id), - )) - }; - - let (rpc_client, sub_client) = f_create_clients(nodes.primary)?; - let (backup_rpc_client, backup_sub_client) = - option_inner(nodes.backup.map(f_create_clients).transpose()?); - - Ok(Self { + rpc_client: ClientFut, + backup_rpc_client: Option, + ) -> Self { + let sub_client = + ReconnectSubscriptionClient::new(nodes.primary.ws_endpoint, expected_chain_id); + + let backup_sub_client = nodes + .backup + .as_ref() + .map(|ep| ReconnectSubscriptionClient::new(ep.ws_endpoint.clone(), expected_chain_id)); + + Self { rpc_retry_client: RetrierClient::new( scope, "eth_rpc", @@ -75,7 +69,55 @@ impl EthersRetryRpcClient { ETHERS_RPC_TIMEOUT, MAX_CONCURRENT_SUBMISSIONS, ), - }) + } + } +} + +impl EthersRetryRpcClient { + pub fn new( + scope: &Scope<'_, anyhow::Error>, + nodes: NodeContainer, + expected_chain_id: U256, + ) -> Result { + let rpc_client = + EthRpcClient::new(nodes.primary.http_endpoint.clone(), expected_chain_id.as_u64())?; + + let backup_rpc_client = nodes + .backup + .as_ref() + .map(|ep| EthRpcClient::new(ep.http_endpoint.clone(), expected_chain_id.as_u64())) + .transpose()?; + + Ok(Self::from_inner_clients(scope, nodes, expected_chain_id, rpc_client, backup_rpc_client)) + } +} + +impl EthersRetryRpcClient { + pub fn new( + scope: &Scope<'_, anyhow::Error>, + private_key_file: PathBuf, + nodes: NodeContainer, + expected_chain_id: U256, + ) -> Result { + let rpc_client = EthRpcSigningClient::new( + private_key_file.clone(), + nodes.primary.http_endpoint.clone(), + expected_chain_id.as_u64(), + )?; + + let backup_rpc_client = nodes + .backup + .as_ref() + .map(|ep| { + EthRpcSigningClient::new( + private_key_file.clone(), + ep.http_endpoint.clone(), + expected_chain_id.as_u64(), + ) + }) + .transpose()?; + + Ok(Self::from_inner_clients(scope, nodes, expected_chain_id, rpc_client, backup_rpc_client)) } } @@ -110,7 +152,7 @@ pub trait EthersRetrySigningRpcApi: EthersRetryRpcApi { } #[async_trait::async_trait] -impl EthersRetryRpcApi for EthersRetryRpcClient { +impl EthersRetryRpcApi for EthersRetryRpcClient { async fn get_logs(&self, block_hash: H256, contract_address: H160) -> Vec { self.rpc_retry_client .request( @@ -218,7 +260,7 @@ impl EthersRetryRpcApi for EthersRetryRpcClient { } #[async_trait::async_trait] -impl EthersRetrySigningRpcApi for EthersRetryRpcClient { +impl EthersRetrySigningRpcApi for EthersRetryRpcClient { /// Estimates gas and then sends the transaction to the network. async fn broadcast_transaction( &self, @@ -287,7 +329,7 @@ pub trait EthersRetrySubscribeApi { } #[async_trait::async_trait] -impl EthersRetrySubscribeApi for EthersRetryRpcClient { +impl EthersRetrySubscribeApi for EthersRetryRpcClient { async fn subscribe_blocks(&self) -> ConscientiousEthWebsocketBlockHeaderStream { self.sub_retry_client .request( @@ -302,7 +344,7 @@ impl EthersRetrySubscribeApi for EthersRetryRpcClient { } #[async_trait::async_trait] -impl ChainClient for EthersRetryRpcClient { +impl ChainClient for EthersRetryRpcClient { type Index = ::ChainBlockNumber; type Hash = H256; @@ -403,7 +445,7 @@ mod tests { async move { let settings = Settings::new_test().unwrap(); - let retry_client = EthersRetryRpcClient::new( + let retry_client = EthersRetryRpcClient::::new( scope, settings.eth.private_key_file, settings.eth.nodes, diff --git a/engine/src/eth/retry_rpc/address_checker.rs b/engine/src/eth/retry_rpc/address_checker.rs index 2341320076..86ee63b85a 100644 --- a/engine/src/eth/retry_rpc/address_checker.rs +++ b/engine/src/eth/retry_rpc/address_checker.rs @@ -1,6 +1,9 @@ use ethers::prelude::*; -use crate::eth::rpc::address_checker::{AddressCheckerRpcApi, *}; +use crate::eth::rpc::{ + address_checker::{AddressCheckerRpcApi, *}, + EthRpcSigningClient, +}; use super::EthersRetryRpcClient; @@ -24,7 +27,7 @@ pub trait AddressCheckerRetryRpcApi { } #[async_trait::async_trait] -impl AddressCheckerRetryRpcApi for EthersRetryRpcClient { +impl AddressCheckerRetryRpcApi for EthersRetryRpcClient { async fn address_states( &self, block_hash: H256, diff --git a/engine/src/eth/rpc.rs b/engine/src/eth/rpc.rs index ee5e32759e..d628e0730a 100644 --- a/engine/src/eth/rpc.rs +++ b/engine/src/eth/rpc.rs @@ -178,7 +178,7 @@ impl EthRpcSigningClient { } #[async_trait::async_trait] -pub trait EthRpcApi: Send { +pub trait EthRpcApi: Send + Sync + Clone + 'static { async fn estimate_gas(&self, req: &Eip1559TransactionRequest) -> Result; async fn get_logs(&self, filter: Filter) -> Result>; diff --git a/engine/src/main.rs b/engine/src/main.rs index a620fa7dd5..f455c1ae32 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -5,7 +5,7 @@ use chainflip_engine::{ btc::retry_rpc::BtcRetryRpcClient, db::{KeyStore, PersistentKeyDB}, dot::retry_rpc::DotRetryRpcClient, - eth::retry_rpc::EthersRetryRpcClient, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, health, p2p, settings::{CommandLineOptions, Settings, DEFAULT_SETTINGS_DIR}, state_chain_observer::{ @@ -175,7 +175,7 @@ async fn run_main(settings: Settings) -> anyhow::Result<()> { .await .expect(STATE_CHAIN_CONNECTION), ); - EthersRetryRpcClient::new( + EthersRetryRpcClient::::new( scope, settings.eth.private_key_file, settings.eth.nodes, diff --git a/engine/src/witness/eth.rs b/engine/src/witness/eth.rs index 94a89944de..deb5f4582f 100644 --- a/engine/src/witness/eth.rs +++ b/engine/src/witness/eth.rs @@ -16,7 +16,7 @@ use utilities::task_scope::Scope; use crate::{ db::PersistentKeyDB, - eth::retry_rpc::EthersRetryRpcClient, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, state_chain_observer::client::{ chain_api::ChainApi, extrinsic_api::signed::SignedExtrinsicApi, storage_api::StorageApi, StateChainStreamApi, @@ -43,7 +43,7 @@ pub async fn start< PrewitnessFut, >( scope: &Scope<'_, anyhow::Error>, - eth_client: EthersRetryRpcClient, + eth_client: EthersRetryRpcClient, process_call: ProcessCall, prewitness_call: PrewitnessCall, state_chain_client: Arc, diff --git a/engine/src/witness/eth/contract_common.rs b/engine/src/witness/eth/contract_common.rs index 0b3412b7d6..d3aa0bb642 100644 --- a/engine/src/witness/eth/contract_common.rs +++ b/engine/src/witness/eth/contract_common.rs @@ -47,14 +47,14 @@ impl Event( +pub async fn events_at_block( header: Header, contract_address: H160, - eth_rpc: &EthRpcSigningClient, + eth_rpc: &EthRpcClient, ) -> Result>> where EventParameters: std::fmt::Debug + ethers::contract::EthLogDecode + Send + Sync + 'static, - EthRpcSigningClient: EthersRetryRpcApi, + EthRpcClient: EthersRetryRpcApi, { let mut contract_bloom = Bloom::default(); contract_bloom.accrue(BloomInput::Raw(&contract_address.0)); diff --git a/engine/src/witness/eth/ethereum_deposits.rs b/engine/src/witness/eth/ethereum_deposits.rs index 36407e0abf..45c3f6f77d 100644 --- a/engine/src/witness/eth/ethereum_deposits.rs +++ b/engine/src/witness/eth/ethereum_deposits.rs @@ -226,7 +226,10 @@ pub fn eth_ingresses_at_block< #[cfg(test)] mod tests { use crate::{ - eth::retry_rpc::{EthersRetryRpcApi, EthersRetryRpcClient}, + eth::{ + retry_rpc::{EthersRetryRpcApi, EthersRetryRpcClient}, + rpc::EthRpcSigningClient, + }, settings::Settings, witness::common::chain_source::Header, }; @@ -315,7 +318,7 @@ mod tests { "e7f1725E7734CE288F8367e1Bb143E90bb3F0512".parse::
().unwrap(); let settings = Settings::new_test().unwrap(); - let client = EthersRetryRpcClient::new( + let client = EthersRetryRpcClient::::new( scope, settings.eth.private_key_file, settings.eth.nodes, diff --git a/engine/src/witness/eth/key_manager.rs b/engine/src/witness/eth/key_manager.rs index 8404775a55..3d985fed13 100644 --- a/engine/src/witness/eth/key_manager.rs +++ b/engine/src/witness/eth/key_manager.rs @@ -48,11 +48,11 @@ impl ChunkedByVaultBuilder { pub fn key_manager_witnessing< ProcessCall, ProcessingFut, - EthRpcSigningClient: EthersRetryRpcApi + ChainClient + Clone, + EthRpcClient: EthersRetryRpcApi + ChainClient + Clone, >( self, process_call: ProcessCall, - eth_rpc: EthRpcSigningClient, + eth_rpc: EthRpcClient, contract_address: H160, ) -> ChunkedByVaultBuilder where @@ -186,7 +186,7 @@ mod tests { use super::super::eth_source::EthSource; use crate::{ - eth::retry_rpc::EthersRetryRpcClient, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, settings::{self, NodeContainer, WsHttpEndpoints}, state_chain_observer::client::StateChainClient, witness::common::{chain_source::extension::ChainSourceExt, epoch_source::EpochSource}, @@ -208,7 +208,7 @@ mod tests { private_key_file: PathBuf::from_str("/some/key/file").unwrap(), }; - let retry_client = EthersRetryRpcClient::new( + let retry_client = EthersRetryRpcClient::::new( scope, eth_settings.private_key_file, eth_settings.nodes, diff --git a/engine/src/witness/eth/state_chain_gateway.rs b/engine/src/witness/eth/state_chain_gateway.rs index 873fa95102..c31ac8fac3 100644 --- a/engine/src/witness/eth/state_chain_gateway.rs +++ b/engine/src/witness/eth/state_chain_gateway.rs @@ -23,13 +23,13 @@ use anyhow::Result; impl ChunkedByVaultBuilder { pub fn state_chain_gateway_witnessing< - EthRpcSigningClient: EthersRetryRpcApi + ChainClient + Clone, + EthRpcClient: EthersRetryRpcApi + ChainClient + Clone, ProcessCall, ProcessingFut, >( self, process_call: ProcessCall, - eth_rpc: EthRpcSigningClient, + eth_rpc: EthRpcClient, contract_address: H160, ) -> ChunkedByVaultBuilder where diff --git a/engine/src/witness/eth/vault.rs b/engine/src/witness/eth/vault.rs index e7fc013d36..09bbb915b1 100644 --- a/engine/src/witness/eth/vault.rs +++ b/engine/src/witness/eth/vault.rs @@ -189,13 +189,13 @@ pub fn call_from_event( impl ChunkedByVaultBuilder { pub fn vault_witnessing< - EthRpcSigningClient: EthersRetryRpcApi + ChainClient + Clone, + EthRpcClient: EthersRetryRpcApi + ChainClient + Clone, ProcessCall, ProcessingFut, >( self, process_call: ProcessCall, - eth_rpc: EthRpcSigningClient, + eth_rpc: EthRpcClient, contract_address: EthereumAddress, native_asset: Asset, source_chain: ForeignChain, diff --git a/engine/src/witness/start.rs b/engine/src/witness/start.rs index 629868fcd0..ec608e4f0d 100644 --- a/engine/src/witness/start.rs +++ b/engine/src/witness/start.rs @@ -6,7 +6,7 @@ use crate::{ btc::retry_rpc::BtcRetryRpcClient, db::PersistentKeyDB, dot::retry_rpc::DotRetryRpcClient, - eth::retry_rpc::EthersRetryRpcClient, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, state_chain_observer::client::{ extrinsic_api::signed::SignedExtrinsicApi, storage_api::StorageApi, StateChainStreamApi, }, @@ -25,7 +25,7 @@ use anyhow::Result; // point it means that on start up this will block, and the state chain observer will not start. pub async fn start( scope: &Scope<'_, anyhow::Error>, - eth_client: EthersRetryRpcClient, + eth_client: EthersRetryRpcClient, btc_client: BtcRetryRpcClient, dot_client: DotRetryRpcClient, state_chain_client: Arc, From a4eb18defebb5b8d0d217fd10f726788d777a61f Mon Sep 17 00:00:00 2001 From: Maxim Shishmarev Date: Fri, 17 Nov 2023 17:53:50 +1100 Subject: [PATCH 4/5] refactor: only require non-signing client when it is sufficient --- .../src/main.rs | 11 +------ .../src/witnessing/eth.rs | 9 ++---- engine/src/eth/retry_rpc/address_checker.rs | 6 ++-- engine/src/eth/rpc/address_checker.rs | 29 ++++++++++++++++--- engine/src/witness/eth/ethereum_deposits.rs | 7 ++--- engine/src/witness/eth/key_manager.rs | 16 ++++------ 6 files changed, 40 insertions(+), 38 deletions(-) diff --git a/api/bin/chainflip-ingress-egress-tracker/src/main.rs b/api/bin/chainflip-ingress-egress-tracker/src/main.rs index b4830a1c54..89a7c89b8b 100644 --- a/api/bin/chainflip-ingress-egress-tracker/src/main.rs +++ b/api/bin/chainflip-ingress-egress-tracker/src/main.rs @@ -1,7 +1,7 @@ use chainflip_engine::settings::{HttpBasicAuthEndpoint, WsHttpEndpoints}; use futures::FutureExt; use jsonrpsee::{core::Error, server::ServerBuilder, RpcModule}; -use std::{env, io::Write, net::SocketAddr, path::PathBuf}; +use std::{env, net::SocketAddr}; use tracing::log; use utilities::task_scope; @@ -11,7 +11,6 @@ mod witnessing; pub struct DepositTrackerSettings { eth_node: WsHttpEndpoints, // The key shouldn't be necessary, but the current witnesser wants this - eth_key_path: PathBuf, dot_node: WsHttpEndpoints, state_chain_ws_endpoint: String, btc: HttpBasicAuthEndpoint, @@ -83,13 +82,6 @@ async fn start( #[tokio::main] async fn main() -> anyhow::Result<()> { - // Temporary hack: we don't actually use eth key, but the current witnesser is - // expecting a path with a valid key, so we create a temporary dummy key file here: - let mut eth_key_temp_file = tempfile::NamedTempFile::new()?; - eth_key_temp_file - .write_all(b"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") - .unwrap(); - let settings = DepositTrackerSettings { eth_node: WsHttpEndpoints { ws_endpoint: env::var("ETH_WS_ENDPOINT") @@ -99,7 +91,6 @@ async fn main() -> anyhow::Result<()> { .unwrap_or("http://localhost:8545".to_string()) .into(), }, - eth_key_path: eth_key_temp_file.path().into(), dot_node: WsHttpEndpoints { ws_endpoint: env::var("DOT_WS_ENDPOINT") .unwrap_or("ws://localhost:9947".to_string()) diff --git a/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs b/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs index 81ce50d658..7afec31097 100644 --- a/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs +++ b/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs @@ -4,7 +4,7 @@ use cf_primitives::chains::assets::eth::Asset; use utilities::task_scope; use chainflip_engine::{ - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcClient}, settings::NodeContainer, state_chain_observer::client::{StateChainClient, StateChainStreamApi}, witness::{ @@ -40,12 +40,7 @@ where let eth_client = { let nodes = NodeContainer { primary: settings.eth_node.clone(), backup: None }; - EthersRetryRpcClient::::new( - scope, - settings.eth_key_path, - nodes, - env_params.eth_chain_id.into(), - )? + EthersRetryRpcClient::::new(scope, nodes, env_params.eth_chain_id.into())? }; let vaults = epoch_source.vaults().await; diff --git a/engine/src/eth/retry_rpc/address_checker.rs b/engine/src/eth/retry_rpc/address_checker.rs index 86ee63b85a..99c95da83b 100644 --- a/engine/src/eth/retry_rpc/address_checker.rs +++ b/engine/src/eth/retry_rpc/address_checker.rs @@ -2,7 +2,7 @@ use ethers::prelude::*; use crate::eth::rpc::{ address_checker::{AddressCheckerRpcApi, *}, - EthRpcSigningClient, + EthRpcApi, }; use super::EthersRetryRpcClient; @@ -27,7 +27,9 @@ pub trait AddressCheckerRetryRpcApi { } #[async_trait::async_trait] -impl AddressCheckerRetryRpcApi for EthersRetryRpcClient { +impl AddressCheckerRetryRpcApi + for EthersRetryRpcClient +{ async fn address_states( &self, block_hash: H256, diff --git a/engine/src/eth/rpc/address_checker.rs b/engine/src/eth/rpc/address_checker.rs index fd267e8ca8..69be5336fd 100644 --- a/engine/src/eth/rpc/address_checker.rs +++ b/engine/src/eth/rpc/address_checker.rs @@ -2,7 +2,7 @@ use ethers::prelude::*; use anyhow::{Ok, Result}; -use super::EthRpcSigningClient; +use super::{EthRpcClient, EthRpcSigningClient}; abigen!(AddressChecker, "$CF_ETH_CONTRACT_ABI_ROOT/$CF_ETH_CONTRACT_ABI_TAG/IAddressChecker.json"); @@ -24,14 +24,14 @@ pub trait AddressCheckerRpcApi { } #[async_trait::async_trait] -impl AddressCheckerRpcApi for EthRpcSigningClient { +impl AddressCheckerRpcApi for EthRpcClient { async fn address_states( &self, block_hash: H256, contract_address: H160, addresses: Vec, ) -> Result> { - Ok(AddressChecker::new(contract_address, self.signer.inner().clone()) + Ok(AddressChecker::new(contract_address, self.provider.clone()) .address_states(addresses) .block(BlockId::Hash(block_hash)) .call() @@ -44,10 +44,31 @@ impl AddressCheckerRpcApi for EthRpcSigningClient { contract_address: H160, addresses: Vec, ) -> Result> { - Ok(AddressChecker::new(contract_address, self.signer.inner().clone()) + Ok(AddressChecker::new(contract_address, self.provider.clone()) .native_balances(addresses) .block(BlockId::Hash(block_hash)) .call() .await?) } } + +#[async_trait::async_trait] +impl AddressCheckerRpcApi for EthRpcSigningClient { + async fn address_states( + &self, + block_hash: H256, + contract_address: H160, + addresses: Vec, + ) -> Result> { + self.rpc_client.address_states(block_hash, contract_address, addresses).await + } + + async fn balances( + &self, + block_hash: H256, + contract_address: H160, + addresses: Vec, + ) -> Result> { + self.rpc_client.balances(block_hash, contract_address, addresses).await + } +} diff --git a/engine/src/witness/eth/ethereum_deposits.rs b/engine/src/witness/eth/ethereum_deposits.rs index 45c3f6f77d..f5ccb9414e 100644 --- a/engine/src/witness/eth/ethereum_deposits.rs +++ b/engine/src/witness/eth/ethereum_deposits.rs @@ -228,7 +228,7 @@ mod tests { use crate::{ eth::{ retry_rpc::{EthersRetryRpcApi, EthersRetryRpcClient}, - rpc::EthRpcSigningClient, + rpc::EthRpcClient, }, settings::Settings, witness::common::chain_source::Header, @@ -307,7 +307,7 @@ mod tests { ); } - #[ignore = "requries connection to a node"] + #[ignore = "requires connection to a node"] #[tokio::test] async fn test_get_ingress_contract() { task_scope::task_scope(|scope| { @@ -318,9 +318,8 @@ mod tests { "e7f1725E7734CE288F8367e1Bb143E90bb3F0512".parse::
().unwrap(); let settings = Settings::new_test().unwrap(); - let client = EthersRetryRpcClient::::new( + let client = EthersRetryRpcClient::::new( scope, - settings.eth.private_key_file, settings.eth.nodes, U256::from(1337u64), ) diff --git a/engine/src/witness/eth/key_manager.rs b/engine/src/witness/eth/key_manager.rs index 3d985fed13..25a0d0648d 100644 --- a/engine/src/witness/eth/key_manager.rs +++ b/engine/src/witness/eth/key_manager.rs @@ -186,8 +186,8 @@ mod tests { use super::super::eth_source::EthSource; use crate::{ - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, - settings::{self, NodeContainer, WsHttpEndpoints}, + eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcClient}, + settings::{NodeContainer, WsHttpEndpoints}, state_chain_observer::client::StateChainClient, witness::common::{chain_source::extension::ChainSourceExt, epoch_source::EpochSource}, }; @@ -197,21 +197,15 @@ mod tests { async fn test_key_manager_witnesser() { task_scope(|scope| { async { - let eth_settings = settings::Eth { - nodes: NodeContainer { + let retry_client = EthersRetryRpcClient::::new( + scope, + NodeContainer { primary: WsHttpEndpoints { ws_endpoint: "ws://localhost:8546".into(), http_endpoint: "http://localhost:8545".into(), }, backup: None, }, - private_key_file: PathBuf::from_str("/some/key/file").unwrap(), - }; - - let retry_client = EthersRetryRpcClient::::new( - scope, - eth_settings.private_key_file, - eth_settings.nodes, U256::from(1337u64), ) .unwrap(); From 73b921575491b00528104d31dcabd0bc057be790 Mon Sep 17 00:00:00 2001 From: Maxim Shishmarev Date: Mon, 20 Nov 2023 11:32:09 +1100 Subject: [PATCH 5/5] chore: address review --- .../src/main.rs | 1 - .../src/witnessing/eth.rs | 4 ++-- engine/src/eth/retry_rpc.rs | 18 +++++++++--------- engine/src/eth/retry_rpc/address_checker.rs | 6 ++---- engine/src/eth/rpc.rs | 6 +++--- engine/src/main.rs | 4 ++-- engine/src/witness/eth.rs | 4 ++-- engine/src/witness/eth/ethereum_deposits.rs | 4 ++-- engine/src/witness/eth/key_manager.rs | 4 ++-- engine/src/witness/start.rs | 4 ++-- 10 files changed, 26 insertions(+), 29 deletions(-) diff --git a/api/bin/chainflip-ingress-egress-tracker/src/main.rs b/api/bin/chainflip-ingress-egress-tracker/src/main.rs index 89a7c89b8b..584ddb1048 100644 --- a/api/bin/chainflip-ingress-egress-tracker/src/main.rs +++ b/api/bin/chainflip-ingress-egress-tracker/src/main.rs @@ -10,7 +10,6 @@ mod witnessing; #[derive(Clone)] pub struct DepositTrackerSettings { eth_node: WsHttpEndpoints, - // The key shouldn't be necessary, but the current witnesser wants this dot_node: WsHttpEndpoints, state_chain_ws_endpoint: String, btc: HttpBasicAuthEndpoint, diff --git a/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs b/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs index 7afec31097..2b93ac59c0 100644 --- a/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs +++ b/api/bin/chainflip-ingress-egress-tracker/src/witnessing/eth.rs @@ -4,7 +4,7 @@ use cf_primitives::chains::assets::eth::Asset; use utilities::task_scope; use chainflip_engine::{ - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcClient}, + eth::{retry_rpc::EthRetryRpcClient, rpc::EthRpcClient}, settings::NodeContainer, state_chain_observer::client::{StateChainClient, StateChainStreamApi}, witness::{ @@ -40,7 +40,7 @@ where let eth_client = { let nodes = NodeContainer { primary: settings.eth_node.clone(), backup: None }; - EthersRetryRpcClient::::new(scope, nodes, env_params.eth_chain_id.into())? + EthRetryRpcClient::::new(scope, nodes, env_params.eth_chain_id.into())? }; let vaults = epoch_source.vaults().await; diff --git a/engine/src/eth/retry_rpc.rs b/engine/src/eth/retry_rpc.rs index 4765a37a3c..d2b3c14613 100644 --- a/engine/src/eth/retry_rpc.rs +++ b/engine/src/eth/retry_rpc.rs @@ -26,7 +26,7 @@ use cf_chains::Ethereum; use anyhow::{Context, Result}; #[derive(Clone)] -pub struct EthersRetryRpcClient { +pub struct EthRetryRpcClient { rpc_retry_client: RetrierClient, sub_retry_client: RetrierClient, } @@ -36,7 +36,7 @@ const MAX_CONCURRENT_SUBMISSIONS: u32 = 100; const MAX_BROADCAST_RETRIES: Attempt = 2; -impl EthersRetryRpcClient { +impl EthRetryRpcClient { fn from_inner_clients + Send + 'static>( scope: &Scope<'_, anyhow::Error>, nodes: NodeContainer, @@ -73,7 +73,7 @@ impl EthersRetryRpcClient { } } -impl EthersRetryRpcClient { +impl EthRetryRpcClient { pub fn new( scope: &Scope<'_, anyhow::Error>, nodes: NodeContainer, @@ -92,7 +92,7 @@ impl EthersRetryRpcClient { } } -impl EthersRetryRpcClient { +impl EthRetryRpcClient { pub fn new( scope: &Scope<'_, anyhow::Error>, private_key_file: PathBuf, @@ -152,7 +152,7 @@ pub trait EthersRetrySigningRpcApi: EthersRetryRpcApi { } #[async_trait::async_trait] -impl EthersRetryRpcApi for EthersRetryRpcClient { +impl EthersRetryRpcApi for EthRetryRpcClient { async fn get_logs(&self, block_hash: H256, contract_address: H160) -> Vec { self.rpc_retry_client .request( @@ -260,7 +260,7 @@ impl EthersRetryRpcApi for EthersRetryRpcClient { } #[async_trait::async_trait] -impl EthersRetrySigningRpcApi for EthersRetryRpcClient { +impl EthersRetrySigningRpcApi for EthRetryRpcClient { /// Estimates gas and then sends the transaction to the network. async fn broadcast_transaction( &self, @@ -329,7 +329,7 @@ pub trait EthersRetrySubscribeApi { } #[async_trait::async_trait] -impl EthersRetrySubscribeApi for EthersRetryRpcClient { +impl EthersRetrySubscribeApi for EthRetryRpcClient { async fn subscribe_blocks(&self) -> ConscientiousEthWebsocketBlockHeaderStream { self.sub_retry_client .request( @@ -344,7 +344,7 @@ impl EthersRetrySubscribeApi for EthersRetryRpcClient { } #[async_trait::async_trait] -impl ChainClient for EthersRetryRpcClient { +impl ChainClient for EthRetryRpcClient { type Index = ::ChainBlockNumber; type Hash = H256; @@ -445,7 +445,7 @@ mod tests { async move { let settings = Settings::new_test().unwrap(); - let retry_client = EthersRetryRpcClient::::new( + let retry_client = EthRetryRpcClient::::new( scope, settings.eth.private_key_file, settings.eth.nodes, diff --git a/engine/src/eth/retry_rpc/address_checker.rs b/engine/src/eth/retry_rpc/address_checker.rs index 99c95da83b..73cfedba33 100644 --- a/engine/src/eth/retry_rpc/address_checker.rs +++ b/engine/src/eth/retry_rpc/address_checker.rs @@ -5,7 +5,7 @@ use crate::eth::rpc::{ EthRpcApi, }; -use super::EthersRetryRpcClient; +use super::EthRetryRpcClient; use crate::eth::retry_rpc::RequestLog; @@ -27,9 +27,7 @@ pub trait AddressCheckerRetryRpcApi { } #[async_trait::async_trait] -impl AddressCheckerRetryRpcApi - for EthersRetryRpcClient -{ +impl AddressCheckerRetryRpcApi for EthRetryRpcClient { async fn address_states( &self, block_hash: H256, diff --git a/engine/src/eth/rpc.rs b/engine/src/eth/rpc.rs index d628e0730a..cba14a5ebd 100644 --- a/engine/src/eth/rpc.rs +++ b/engine/src/eth/rpc.rs @@ -86,13 +86,13 @@ impl EthRpcApi for EthRpcClient { /// - Request succeeds, but doesn't return a block async fn block(&self, block_number: U64) -> Result> { self.provider.get_block(block_number).await?.ok_or_else(|| { - anyhow!("Getting ETH block for block number {} returned None", block_number) + anyhow!("Getting ETH block for block number {block_number} returned None") }) } async fn block_with_txs(&self, block_number: U64) -> Result> { self.provider.get_block_with_txs(block_number).await?.ok_or_else(|| { - anyhow!("Getting ETH block with txs for block number {} returned None", block_number) + anyhow!("Getting ETH block with txs for block number {block_number} returned None") }) } @@ -109,7 +109,7 @@ impl EthRpcApi for EthRpcClient { self.provider .get_transaction(tx_hash) .await? - .ok_or_else(|| anyhow!("Getting ETH transaction for tx hash {} returned None", tx_hash)) + .ok_or_else(|| anyhow!("Getting ETH transaction for tx hash {tx_hash} returned None")) } } diff --git a/engine/src/main.rs b/engine/src/main.rs index f455c1ae32..37efa7f8b8 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -5,7 +5,7 @@ use chainflip_engine::{ btc::retry_rpc::BtcRetryRpcClient, db::{KeyStore, PersistentKeyDB}, dot::retry_rpc::DotRetryRpcClient, - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, + eth::{retry_rpc::EthRetryRpcClient, rpc::EthRpcSigningClient}, health, p2p, settings::{CommandLineOptions, Settings, DEFAULT_SETTINGS_DIR}, state_chain_observer::{ @@ -175,7 +175,7 @@ async fn run_main(settings: Settings) -> anyhow::Result<()> { .await .expect(STATE_CHAIN_CONNECTION), ); - EthersRetryRpcClient::::new( + EthRetryRpcClient::::new( scope, settings.eth.private_key_file, settings.eth.nodes, diff --git a/engine/src/witness/eth.rs b/engine/src/witness/eth.rs index deb5f4582f..69c1d5454f 100644 --- a/engine/src/witness/eth.rs +++ b/engine/src/witness/eth.rs @@ -16,7 +16,7 @@ use utilities::task_scope::Scope; use crate::{ db::PersistentKeyDB, - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, + eth::{retry_rpc::EthRetryRpcClient, rpc::EthRpcSigningClient}, state_chain_observer::client::{ chain_api::ChainApi, extrinsic_api::signed::SignedExtrinsicApi, storage_api::StorageApi, StateChainStreamApi, @@ -43,7 +43,7 @@ pub async fn start< PrewitnessFut, >( scope: &Scope<'_, anyhow::Error>, - eth_client: EthersRetryRpcClient, + eth_client: EthRetryRpcClient, process_call: ProcessCall, prewitness_call: PrewitnessCall, state_chain_client: Arc, diff --git a/engine/src/witness/eth/ethereum_deposits.rs b/engine/src/witness/eth/ethereum_deposits.rs index f5ccb9414e..705139a161 100644 --- a/engine/src/witness/eth/ethereum_deposits.rs +++ b/engine/src/witness/eth/ethereum_deposits.rs @@ -227,7 +227,7 @@ pub fn eth_ingresses_at_block< mod tests { use crate::{ eth::{ - retry_rpc::{EthersRetryRpcApi, EthersRetryRpcClient}, + retry_rpc::{EthRetryRpcClient, EthersRetryRpcApi}, rpc::EthRpcClient, }, settings::Settings, @@ -318,7 +318,7 @@ mod tests { "e7f1725E7734CE288F8367e1Bb143E90bb3F0512".parse::
().unwrap(); let settings = Settings::new_test().unwrap(); - let client = EthersRetryRpcClient::::new( + let client = EthRetryRpcClient::::new( scope, settings.eth.nodes, U256::from(1337u64), diff --git a/engine/src/witness/eth/key_manager.rs b/engine/src/witness/eth/key_manager.rs index 25a0d0648d..21a6ab27f4 100644 --- a/engine/src/witness/eth/key_manager.rs +++ b/engine/src/witness/eth/key_manager.rs @@ -186,7 +186,7 @@ mod tests { use super::super::eth_source::EthSource; use crate::{ - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcClient}, + eth::{retry_rpc::EthRetryRpcClient, rpc::EthRpcClient}, settings::{NodeContainer, WsHttpEndpoints}, state_chain_observer::client::StateChainClient, witness::common::{chain_source::extension::ChainSourceExt, epoch_source::EpochSource}, @@ -197,7 +197,7 @@ mod tests { async fn test_key_manager_witnesser() { task_scope(|scope| { async { - let retry_client = EthersRetryRpcClient::::new( + let retry_client = EthRetryRpcClient::::new( scope, NodeContainer { primary: WsHttpEndpoints { diff --git a/engine/src/witness/start.rs b/engine/src/witness/start.rs index ec608e4f0d..533024b68b 100644 --- a/engine/src/witness/start.rs +++ b/engine/src/witness/start.rs @@ -6,7 +6,7 @@ use crate::{ btc::retry_rpc::BtcRetryRpcClient, db::PersistentKeyDB, dot::retry_rpc::DotRetryRpcClient, - eth::{retry_rpc::EthersRetryRpcClient, rpc::EthRpcSigningClient}, + eth::{retry_rpc::EthRetryRpcClient, rpc::EthRpcSigningClient}, state_chain_observer::client::{ extrinsic_api::signed::SignedExtrinsicApi, storage_api::StorageApi, StateChainStreamApi, }, @@ -25,7 +25,7 @@ use anyhow::Result; // point it means that on start up this will block, and the state chain observer will not start. pub async fn start( scope: &Scope<'_, anyhow::Error>, - eth_client: EthersRetryRpcClient, + eth_client: EthRetryRpcClient, btc_client: BtcRetryRpcClient, dot_client: DotRetryRpcClient, state_chain_client: Arc,