diff --git a/executors/src/eoa/worker/confirm.rs b/executors/src/eoa/worker/confirm.rs index 11f95bf..09ea467 100644 --- a/executors/src/eoa/worker/confirm.rs +++ b/executors/src/eoa/worker/confirm.rs @@ -109,11 +109,41 @@ impl EoaExecutorWorker { bumped_nonce = transaction_counts.preconfirmed, preconfirmed_nonce = transaction_counts.preconfirmed, latest_nonce = transaction_counts.latest, - "Failed to attempt gas bump for stalled nonce. Scheduling nonce reset" + "Failed to attempt gas bump for stalled nonce. Attempting no-op transaction as fallback" ); - if let Err(e) = self.store.schedule_manual_reset().await { - tracing::error!(error = ?e, "Failed to schedule auto-reset"); + // Try sending a no-op transaction as fallback + match self + .send_noop_transaction(transaction_counts.preconfirmed) + .await + { + Ok(noop_tx) => { + // Process the no-op transaction + if let Err(e) = + self.store.process_noop_transactions(&[noop_tx]).await + { + tracing::error!( + error = ?e, + bumped_nonce = transaction_counts.preconfirmed, + preconfirmed_nonce = transaction_counts.preconfirmed, + latest_nonce = transaction_counts.latest, + "Failed to process fallback no-op transaction for stalled nonce, but sending transactions was successful" + ); + } + } + Err(e) => { + tracing::error!( + error = ?e, + bumped_nonce = transaction_counts.preconfirmed, + preconfirmed_nonce = transaction_counts.preconfirmed, + latest_nonce = transaction_counts.latest, + "Failed to send fallback no-op transaction for stalled nonce. Scheduling auto-reset if EOA is stuck" + ); + + if let Err(e) = self.store.schedule_manual_reset().await { + tracing::error!(error = ?e, "Failed to schedule auto-reset"); + } + } } } } diff --git a/executors/src/eoa/worker/send.rs b/executors/src/eoa/worker/send.rs index 36fe55a..3a50144 100644 --- a/executors/src/eoa/worker/send.rs +++ b/executors/src/eoa/worker/send.rs @@ -1,13 +1,16 @@ -use alloy::providers::Provider; +use alloy::{consensus::Transaction, providers::Provider}; use engine_core::{chain::Chain, error::AlloyRpcErrorToEngineError}; use crate::eoa::{ - store::{BorrowedTransaction, PendingTransaction, SubmissionResult}, + EoaExecutorStore, + store::{BorrowedTransaction, PendingTransaction, SubmissionResult, SubmissionResultType}, worker::{ + EoaExecutorWorker, error::{ - is_retryable_preparation_error, should_update_balance_threshold, EoaExecutorWorkerError, SendContext - }, EoaExecutorWorker - }, EoaExecutorStore, + EoaExecutorWorkerError, SendContext, is_retryable_preparation_error, + should_update_balance_threshold, + }, + }, }; const HEALTH_CHECK_INTERVAL_MS: u64 = 60 * 5 * 1000; // 5 minutes in milliseconds @@ -391,12 +394,24 @@ impl EoaExecutorWorker { .into_iter() .zip(cleaned_results.into_iter()) .map(|(send_result, borrowed_tx)| { - SubmissionResult::from_send_result( + let result = SubmissionResult::from_send_result( &borrowed_tx, send_result, SendContext::InitialBroadcast, &self.chain, - ) + ); + + match &result.result { + SubmissionResultType::Success => result, + SubmissionResultType::Nack(e) => { + tracing::error!(error = ?e, transaction_id = borrowed_tx.transaction_id, nonce = borrowed_tx.data.signed_transaction.nonce(), "Transaction nack error during send"); + result + } + SubmissionResultType::Fail(e) => { + tracing::error!(error = ?e, transaction_id = borrowed_tx.transaction_id, nonce = borrowed_tx.data.signed_transaction.nonce(), "Transaction failed during send"); + result + } + } }) .collect();