From ac29c30d072532b42e4b3c710249157737ef727f Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Fri, 20 Mar 2026 02:00:49 +0700 Subject: [PATCH 1/2] Use adaptive retry delay for transaction resolution Add transaction_hash_retry_delay(attempts) to compute exponential/backoff-style delays based on job.attempts(), and apply it when requeueing transaction-hash fetches. Replace hardcoded 1s/2s delays with the computed delay for both bundler errors (nack) and Pending responses (map_err_nack), and add tracing logs to record bundler_transaction_id, attempt, and retry_delay_seconds. This reduces aggressive retries and centralizes retry timing logic. --- executors/src/eip7702_executor/confirm.rs | 27 +++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/executors/src/eip7702_executor/confirm.rs b/executors/src/eip7702_executor/confirm.rs index 65dc21a..8ebbd13 100644 --- a/executors/src/eip7702_executor/confirm.rs +++ b/executors/src/eip7702_executor/confirm.rs @@ -29,6 +29,16 @@ use crate::{ }, }; +fn transaction_hash_retry_delay(attempts: u32) -> Duration { + match attempts { + 0..=5 => Duration::from_secs(2), + 6..=20 => Duration::from_secs(10), + 21..=100 => Duration::from_secs(30), + 101..=1000 => Duration::from_secs(5 * 60), + _ => Duration::from_secs(30 * 60), + } +} + // --- Job Payload --- #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] @@ -174,6 +184,7 @@ where job: &BorrowedJob, ) -> JobResult { let job_data = &job.job.data; + let transaction_hash_delay = transaction_hash_retry_delay(job.attempts()); // 1. Get Chain let chain = self @@ -214,10 +225,16 @@ where } .fail() } else { + tracing::warn!( + bundler_transaction_id = job_data.bundler_transaction_id, + attempt = job.attempts(), + retry_delay_seconds = transaction_hash_delay.as_secs(), + "Retrying transaction hash fetch after bundler error" + ); Eip7702ConfirmationError::TransactionHashError { message: e.to_string(), } - .nack(Some(Duration::from_secs(2)), RequeuePosition::Last) + .nack(Some(transaction_hash_delay), RequeuePosition::Last) } })?; @@ -232,10 +249,16 @@ where } TwGetTransactionHashResponse::Pending => { + tracing::debug!( + bundler_transaction_id = job_data.bundler_transaction_id, + attempt = job.attempts(), + retry_delay_seconds = transaction_hash_delay.as_secs(), + "Transaction hash still pending, scheduling retry" + ); return Err(Eip7702ConfirmationError::TransactionHashPending { message: "Transaction hash not yet available".to_string(), }) - .map_err_nack(Some(Duration::from_secs(1)), RequeuePosition::Last); + .map_err_nack(Some(transaction_hash_delay), RequeuePosition::Last); } }; From aa0f0b6d9f38a81082fa4de3fc886e632c1428e2 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Fri, 20 Mar 2026 02:04:35 +0700 Subject: [PATCH 2/2] Add tests for transaction_hash_retry_delay Adds a unit test module verifying that transaction_hash_retry_delay respects bucket boundaries. The test checks edge cases around thresholds (5/6, 20/21, 100/101, 1000/1001) and ensures the function returns the expected Durations (2s, 10s, 30s, 5min, 30min) for those ranges. --- executors/src/eip7702_executor/confirm.rs | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/executors/src/eip7702_executor/confirm.rs b/executors/src/eip7702_executor/confirm.rs index 8ebbd13..ad15036 100644 --- a/executors/src/eip7702_executor/confirm.rs +++ b/executors/src/eip7702_executor/confirm.rs @@ -407,3 +407,34 @@ where } } } + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use super::transaction_hash_retry_delay; + + #[test] + fn transaction_hash_retry_delay_respects_bucket_boundaries() { + assert_eq!(transaction_hash_retry_delay(5), Duration::from_secs(2)); + assert_eq!(transaction_hash_retry_delay(6), Duration::from_secs(10)); + + assert_eq!(transaction_hash_retry_delay(20), Duration::from_secs(10)); + assert_eq!(transaction_hash_retry_delay(21), Duration::from_secs(30)); + + assert_eq!(transaction_hash_retry_delay(100), Duration::from_secs(30)); + assert_eq!( + transaction_hash_retry_delay(101), + Duration::from_secs(5 * 60) + ); + + assert_eq!( + transaction_hash_retry_delay(1000), + Duration::from_secs(5 * 60) + ); + assert_eq!( + transaction_hash_retry_delay(1001), + Duration::from_secs(30 * 60) + ); + } +}