Skip to content

Commit e2ef7a4

Browse files
authored
fix: timeout for tx confirmation (#2098)
1 parent ed0f273 commit e2ef7a4

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

apps/fortuna/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/fortuna/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fortuna"
3-
version = "6.5.4"
3+
version = "6.5.5"
44
edition = "2021"
55

66
[dependencies]

apps/fortuna/src/keeper.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ use {
6565
},
6666
time::{
6767
self,
68+
timeout,
6869
Duration,
6970
},
7071
},
@@ -421,6 +422,8 @@ pub async fn process_event_with_backoff(
421422
}
422423

423424

425+
const TX_CONFIRMATION_TIMEOUT_SECS: u64 = 30;
426+
424427
/// Process a callback on a chain. It estimates the gas for the reveal with callback and
425428
/// submits the transaction if the gas estimate is below the gas limit.
426429
/// It will return a permanent or transient error depending on the error type and whether
@@ -501,8 +504,28 @@ pub async fn process_event(
501504
))
502505
})?;
503506

504-
let receipt = pending_tx
505-
.await
507+
let reset_nonce = || {
508+
let nonce_manager = contract.client_ref().inner().inner();
509+
nonce_manager.reset();
510+
};
511+
512+
let pending_receipt = timeout(
513+
Duration::from_secs(TX_CONFIRMATION_TIMEOUT_SECS),
514+
pending_tx,
515+
)
516+
.await
517+
.map_err(|_| {
518+
// Tx can get stuck in mempool without any progress if the nonce is too high
519+
// in this case ethers internal polling will not reduce the number of retries
520+
// and keep retrying indefinitely. So we set a manual timeout here and reset the nonce.
521+
reset_nonce();
522+
backoff::Error::transient(anyhow!(
523+
"Tx stuck in mempool. Resetting nonce. Tx:{:?}",
524+
transaction
525+
))
526+
})?;
527+
528+
let receipt = pending_receipt
506529
.map_err(|e| {
507530
backoff::Error::transient(anyhow!(
508531
"Error waiting for transaction receipt. Tx:{:?} Error:{:?}",
@@ -513,10 +536,9 @@ pub async fn process_event(
513536
.ok_or_else(|| {
514537
// RPC may not return an error on tx submission if the nonce is too high.
515538
// But we will never get a receipt. So we reset the nonce manager to get the correct nonce.
516-
let nonce_manager = contract.client_ref().inner().inner();
517-
nonce_manager.reset();
539+
reset_nonce();
518540
backoff::Error::transient(anyhow!(
519-
"Can't verify the reveal, probably dropped from mempool Tx:{:?}",
541+
"Can't verify the reveal, probably dropped from mempool. Resetting nonce. Tx:{:?}",
520542
transaction
521543
))
522544
})?;

0 commit comments

Comments
 (0)