From 9aea693ea7dc76fcba01e10df1cac8754578b8c9 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 24 Apr 2024 11:32:17 +0200 Subject: [PATCH] fix: better tx receipt mitigation (#614) * fix: better tx receipt mitigation * rustfmt * use client poll interval --- crates/provider/src/heart.rs | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/crates/provider/src/heart.rs b/crates/provider/src/heart.rs index f96692e4ef0..913083d89cd 100644 --- a/crates/provider/src/heart.rs +++ b/crates/provider/src/heart.rs @@ -180,18 +180,35 @@ impl<'a, T: Transport + Clone, N: Network> PendingTransactionBuilder<'a, T, N> { /// confirmed. /// - [`watch`](Self::watch) for watching the transaction without fetching the receipt. pub async fn get_receipt(self) -> TransportResult { - // Try fetching receipt immediately to ensure that we don't watch for a transaction that is - // already confirmed. - let receipt = self.provider.get_transaction_receipt(self.config.tx_hash).await?; - if let Some(receipt) = receipt { - return Ok(receipt); - } + let hash = self.config.tx_hash; + let mut pending_tx = self.provider.watch_pending_transaction(self.config).await?; + + // FIXME: this is a hotfix to prevent a race condition where the heartbeat would miss the + // block the tx was mined in + let mut interval = + tokio::time::interval(Duration::from_millis(self.provider.client().poll_interval())); + + loop { + let mut confirmed = false; + + select! { + _ = interval.tick() => {}, + res = &mut pending_tx => { + let _ = res?; + confirmed = true; + } + } - let pending_tx = self.provider.watch_pending_transaction(self.config).await?; - let hash = pending_tx.await?; - let receipt = self.provider.get_transaction_receipt(hash).await?; + // try to fetch the receipt + let receipt = self.provider.get_transaction_receipt(hash).await?; + if let Some(receipt) = receipt { + return Ok(receipt); + } - receipt.ok_or(RpcError::NullResp) + if confirmed { + return Err(RpcError::NullResp); + } + } } }