Repository navigation
feat:alerting for stuck entries and a fee-bump ceiling - #706
Merged
robertocarlous merged 1 commit intoOct 20, 2026
Conversation
|
@bibi-fay Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the transactional outbox for on-chain operations (#325). Business state and the intent to submit to Stellar are now written in the same DB transaction. A prioritized dispatcher then turns each intent into a submission, so a crash or failed submit no longer loses the operation.
Changes
src/outbox/service.ts: DB-facing operations: idempotent enqueue (byidempotencyKey), atomic claim (PENDING -> SUBMITTEDvia conditionalupdateMany), retry/terminal transitions, admin force-retry and cancel, queue stats, and the txHash reconciliation used by the events oracle.src/outbox/dispatcher.ts:dispatchOnefor synchronous callers (deposit/withdraw, referral payout),dispatchInBackgroundfor fire-and-forget ops, andrunDispatchSweepfor crash recovery and retries. All paths converge onsubmitClaimedOp.src/outbox/stateMachine.ts: pure transition rules, priority ordering (CRITICAL > NORMAL > LOW, FIFO within a tier), and full-jitter backoff.src/outbox/executors.ts: exportsresolveSignerPublicKeyandexecuteOutboxPayload, which the dispatcher imports. These were declared but not exported, which broke compilation across many test suites.Behavior notes
PENDINGwith backoff. OncemaxAttemptsis reached, it moves toFAILED, which raises a critical alert and publishesoutbox.op_failed.status: 'failed'is terminal and not retried, matching the pre-Durable Outbox & Prioritized On-Chain Transaction Queue #325 deposit/withdraw behavior.feeBumpMaxAttempts, clamped atmaxAbsFee. CRITICAL ops use the aggressive base fee under congestion.lowMaxDeferMs.signerLock.isUserHaltedblocks dispatch for inactive or frozen users.Testing
npx tsc --noEmitpassestests/unit/outbox/stateMachine.test.tstests/integration/outbox/dispatcher.integration.test.tsKnown follow-ups
findClaimableOpsappliestake: limitwithout anORDER BY, so priority sorting only reorders the fetched batch. With a backlog larger thanbatchSize, a CRITICAL op can be left out of a sweep.computeBackoffMssaysbase * 2^attempt, but the code uses2^(attempt - 1).Closes #588
Closes #703
Closes #704
Closes #702