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