Skip to content

Commit b4487d0

Browse files
authored
Refactor webhook handling and error management in EIP-7702 and external bundler executors (#67)
- Updated webhook queuing logic to skip notifications for "waiting for receipt" states, improving efficiency. - Enhanced error handling in the delegation contract checks to differentiate between retryable and non-retryable errors. - Increased maximum confirmation attempts and reduced confirmation retry delay for external bundler to optimize transaction processing.
1 parent 5786fb5 commit b4487d0

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

executors/src/eip7702_executor/confirm.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,11 +332,25 @@ where
332332
tx: &mut TransactionContext<'_>,
333333
) {
334334
// Don't modify transaction registry on NACK - job will be retried
335-
if let Err(e) = self.queue_nack_webhook(job, nack_data, tx) {
336-
tracing::error!(
335+
336+
// Only queue webhook for actual errors, not for "waiting for receipt" states
337+
let should_queue_webhook = !matches!(
338+
nack_data.error,
339+
Eip7702ConfirmationError::ReceiptNotAvailable { .. }
340+
);
341+
342+
if should_queue_webhook {
343+
if let Err(e) = self.queue_nack_webhook(job, nack_data, tx) {
344+
tracing::error!(
345+
transaction_id = job.job.data.transaction_id,
346+
error = ?e,
347+
"Failed to queue nack webhook"
348+
);
349+
}
350+
} else {
351+
tracing::debug!(
337352
transaction_id = job.job.data.transaction_id,
338-
error = ?e,
339-
"Failed to queue nack webhook"
353+
"Skipping webhook for receipt not available - transaction still mining"
340354
);
341355
}
342356
}

executors/src/eip7702_executor/send.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,22 @@ where
226226
.delegation_contract_cache
227227
.get_delegation_contract(transactions.account().chain())
228228
.await
229-
.map_err(|e| Eip7702SendError::DelegationCheckFailed { inner_error: e })
230-
.map_err_nack(
231-
Some(Duration::from_secs(2)),
232-
twmq::job::RequeuePosition::Last,
233-
)?;
229+
.map_err(|e| {
230+
let mapped_error = Eip7702SendError::DelegationCheckFailed {
231+
inner_error: e.clone(),
232+
};
233+
234+
// Retry only if the error is retryable (network issues, 5xx, etc.)
235+
// Client errors (4xx) like "Invalid chain" or auth errors fail immediately
236+
if is_build_error_retryable(&e) {
237+
mapped_error.nack(
238+
Some(Duration::from_secs(2)),
239+
twmq::job::RequeuePosition::Last,
240+
)
241+
} else {
242+
mapped_error.fail()
243+
}
244+
})?;
234245

235246
let transactions = transactions
236247
.add_authorization_if_needed(
@@ -249,6 +260,8 @@ where
249260
},
250261
};
251262

263+
// Retry only if the error is retryable (network issues, 5xx, etc.)
264+
// Client errors (4xx) like "Invalid chain" or auth errors fail immediately
252265
if is_build_error_retryable(&e) {
253266
mapped_error.nack_with_max_retries(
254267
Some(Duration::from_secs(2)),

executors/src/external_bundler/confirm.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ where
124124
deployment_lock,
125125
webhook_queue,
126126
transaction_registry,
127-
max_confirmation_attempts: 20, // ~5 minutes with 15 second delays
128-
confirmation_retry_delay: Duration::from_secs(5),
127+
max_confirmation_attempts: 50, // ~100 seconds with 2 second delays
128+
confirmation_retry_delay: Duration::from_secs(2),
129129
}
130130
}
131131

@@ -274,12 +274,26 @@ where
274274
tx: &mut TransactionContext<'_>,
275275
) {
276276
// NEVER release lock on NACK - job will be retried with the same lock
277-
// Just queue webhook with current status
278-
if let Err(e) = self.queue_nack_webhook(job, nack_data, tx) {
279-
tracing::error!(
277+
278+
// Only queue webhook for actual errors, not for "waiting for receipt" states
279+
let should_queue_webhook = !matches!(
280+
nack_data.error,
281+
UserOpConfirmationError::ReceiptNotAvailable { .. }
282+
);
283+
284+
if should_queue_webhook {
285+
if let Err(e) = self.queue_nack_webhook(job, nack_data, tx) {
286+
tracing::error!(
287+
transaction_id = job.job.data.transaction_id,
288+
error = ?e,
289+
"Failed to queue nack webhook"
290+
);
291+
}
292+
} else {
293+
tracing::debug!(
280294
transaction_id = job.job.data.transaction_id,
281-
error = ?e,
282-
"Failed to queue nack webhook"
295+
attempt = job.job.attempts,
296+
"Skipping webhook for receipt not available - transaction still mining"
283297
);
284298
}
285299

0 commit comments

Comments
 (0)