diff --git a/crates/chain-connector/src/connector.rs b/crates/chain-connector/src/connector.rs index 5ebcbf4e0e..8fe64e8d1f 100644 --- a/crates/chain-connector/src/connector.rs +++ b/crates/chain-connector/src/connector.rs @@ -82,7 +82,7 @@ pub trait ChainConnector: Send + Sync { pub struct HttpChainConnector { client: Arc, config: ChainConfig, - tx_nonce_mutex: Arc>, + tx_nonce_mutex: Arc>>, host_id: PeerId, } @@ -106,7 +106,7 @@ impl HttpChainConnector { let connector = Arc::new(Self { client: Arc::new(HttpClientBuilder::default().build(&config.http_endpoint)?), config, - tx_nonce_mutex: Arc::new(Default::default()), + tx_nonce_mutex: Arc::new(Mutex::new(None)), host_id, }); @@ -458,8 +458,11 @@ impl HttpChainConnector { let max_fee_per_gas = base_fee + max_priority_fee_per_gas; // We use this lock no ensure that we don't send two transactions with the same nonce - let _lock = self.tx_nonce_mutex.lock().await; - let nonce = self.get_tx_nonce().await?; + let mut nonce_guard = self.tx_nonce_mutex.lock().await; + let nonce = match *nonce_guard { + None => self.get_tx_nonce().await?, + Some(n) => n, + }; // Create a new transaction let tx = Transaction::Eip1559 { @@ -487,12 +490,25 @@ impl HttpChainConnector { self.config.wallet_key.to_address() ); - let resp: String = process_response( + let result: Result = process_response( self.client .request("eth_sendRawTransaction", rpc_params![format!("0x{}", tx)]) .await, - )?; - Ok(resp) + ); + + match result { + Ok(resp) => { + let new_nonce = nonce + Uint::from(1); + *nonce_guard = Some(new_nonce); + tracing::debug!(target: "chain-connector", "Incrementing nonce. New nonce {new_nonce}"); + Ok(resp) + } + Err(err) => { + tracing::warn!(target: "chain-connector", "Failed to send tx: {err}, resetting nonce"); + *nonce_guard = None; + Err(err) + } + } } pub async fn register_worker(