diff --git a/crates/shared/src/web3/contracts/helpers/utils.rs b/crates/shared/src/web3/contracts/helpers/utils.rs index 8dcbca1e..b6501ff9 100644 --- a/crates/shared/src/web3/contracts/helpers/utils.rs +++ b/crates/shared/src/web3/contracts/helpers/utils.rs @@ -9,7 +9,7 @@ use alloy::{ }; use anyhow::Result; use log::{debug, info, warn}; -use tokio::time::{timeout, Duration}; +use tokio::time::Duration; use crate::web3::wallet::WalletProvider; @@ -30,13 +30,23 @@ where N: Network, D: CallDecoder + Clone, { + const PENDING_TRANSACTION_TIMEOUT: Duration = Duration::from_secs(60); + let mut tries = 0; let retry_delay = retry_delay.unwrap_or(2); + let mut tx_hash = None; while tries < max_tries { if tries > 0 { tokio::time::sleep(Duration::from_secs(retry_delay)).await; + if let Some(tx_hash) = tx_hash { + let receipt = provider.get_transaction_receipt(tx_hash).await?; + if receipt.is_some() { + return Ok(tx_hash); + } + } + // On retry, always fetch fresh fee estimates from the provider. let priority_fee_res = provider.get_max_priority_fee_per_gas().await; let gas_price_res = provider.get_gas_price().await; @@ -54,7 +64,7 @@ where call = call .clone() .max_fee_per_gas(new_gas_price) - .max_priority_fee_per_gas(new_priority_fee); + .max_priority_fee_per_gas(new_priority_fee) } else { warn!("Could not get new gas fees, retrying with old settings."); } @@ -63,10 +73,15 @@ where match call.clone().send().await { Ok(result) => { debug!("Transaction sent, waiting for confirmation..."); - match timeout(Duration::from_secs(30), result.watch()).await { - Ok(Ok(hash)) => return Ok(hash), - Ok(Err(err)) => warn!("Transaction watch failed: {err:?}"), - Err(_) => warn!("Watch timed out, retrying transaction..."), + tx_hash = Some(*result.tx_hash()); + + match result + .with_timeout(Some(PENDING_TRANSACTION_TIMEOUT)) + .watch() + .await + { + Ok(hash) => return Ok(hash), + Err(err) => warn!("Transaction watch failed: {err:?}"), } } Err(err) => {