Description
Handle FAILED status in the poll_until_confirmed loop. A FAILED status means the transaction was rejected on-chain (e.g., budget exceeded, invalid operation, auth failure).
Current Behavior
FAILED is matched in poll_until_confirmed and returns SubmitError::TransactionFailed with the diagnostic events. This is correct but needs proper error propagation.
Desired Behavior
When FAILED is detected:
- Extract
diagnosticEventsXdr from the response
- Log at
error level with the hash and events
- Return
SubmitError::TransactionFailed { events } immediately (do not retry)
- The caller (
execute_handler or set_prices_on_chain) should record the failure
Implementation Details
"FAILED" => {
let events = result.diagnostic_events_xdr.unwrap_or_default();
tracing::error!(hash, ?events, "transaction failed");
return Err(SubmitError::TransactionFailed { events });
}
- Do NOT retry on
FAILED — the transaction is permanently rejected
- Diagnostic events contain Soroban contract error details
- The caller should parse the events to determine if it is a
Budget, ExceededLimit (for order freeze logic)
Acceptance Criteria
Description
Handle
FAILEDstatus in thepoll_until_confirmedloop. AFAILEDstatus means the transaction was rejected on-chain (e.g., budget exceeded, invalid operation, auth failure).Current Behavior
FAILEDis matched inpoll_until_confirmedand returnsSubmitError::TransactionFailedwith the diagnostic events. This is correct but needs proper error propagation.Desired Behavior
When
FAILEDis detected:diagnosticEventsXdrfrom the responseerrorlevel with the hash and eventsSubmitError::TransactionFailed { events }immediately (do not retry)execute_handlerorset_prices_on_chain) should record the failureImplementation Details
FAILED— the transaction is permanently rejectedBudget, ExceededLimit(for order freeze logic)Acceptance Criteria
FAILEDstatus returnsSubmitError::TransactionFailedimmediatelyFAILEDdoes NOT trigger a retryerrorlevel with hash and events