Skip to content

fix(swap-service): terminate swaps whose swapper stays unreachable - #62

Merged
kaladinlight merged 1 commit into
developfrom
fix/unreachable-swapper-timeout
Sep 2, 2026
Merged

fix(swap-service): terminate swaps whose swapper stays unreachable#62
kaladinlight merged 1 commit into
developfrom
fix/unreachable-swapper-timeout

Conversation

@kaladinlight

Copy link
Copy Markdown
Member

Description

Follow-up to #61, which merged before this was pushed.

#61 fails a swap the swapper still cannot settle 24 hours after registration, but the catch in checkSwapStatus returns PENDING directly and never reaches that logic. A swap whose swapper throws on every poll therefore polls forever — the same eternal-PENDING case #61 exists to close, reached by a different route. Raised by CodeRabbit on that PR.

The fix is not to apply the same threshold there. An unreachable swapper is no evidence the swap is dead, only that we could not ask, so failing on 24h would permanently fail a swap that settled at hour 25 while the swapper's api happened to blip — and FAILED is a one-way door, since getPendingTxSwaps selects only IDLE/PENDING and never re-checks it.

Confidence that a swap is dead rises with age, so the error path gets its own, much longer window:

evidence window
swapper reports unsettled 24h
swapper unreachable 7d

A transient outage cannot reach seven days, while a swap that has been failing for a week still terminates. The last error is preserved in statusMessage either way, so it stays diagnosable.

timeoutMs is a required argument rather than defaulting to the 24h window. A default would mean a future call site that omitted it silently got the aggressive threshold on a transition that cannot be undone, with nothing at the call site to review — the bug would be an absence. Both callers now name the window they mean.

Testing

  • yarn workspace @shapeshift/swap-service test — 87 passing (85 before)
  • Two new cases: a swap two days old whose swapper is unreachable stays PENDING; one eight days old fails with Abandoned: unsettled 7d after registration (last swapper status: Error polling status: …)
  • Existing cases updated to pass their window explicitly, confirming the 24h path is unchanged

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 30 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 493a6d40-8091-4de4-b017-566d796bc2bd

📥 Commits

Reviewing files that changed from the base of the PR and between b939c85 and 356e18d.

📒 Files selected for processing (4)
  • apps/swap-service/src/swaps/__tests__/utils.test.ts
  • apps/swap-service/src/swaps/constants.ts
  • apps/swap-service/src/swaps/swaps.service.ts
  • apps/swap-service/src/swaps/utils.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Follow-up to #61. The catch in checkSwapStatus returned PENDING directly, so a
swap whose swapper throws on every poll never reached the stall timeout and
polled forever - the same eternal-PENDING case #61 closes, reached by a
different route.

Routes that path through resolveStalledSwap with its own, much longer window.
An unreachable swapper is no evidence the swap is dead, only that we could not
ask, so failing it on the 24h threshold would permanently fail a swap that
settled at hour 25 while the swapper's api happened to blip. Seven days gives a
transient outage no way to reach the threshold while still terminating a swap
that has been failing for a week.

The timeout is a required argument rather than defaulting to the 24h window: a
call site that omitted it would otherwise silently get the aggressive threshold
on a transition that cannot be undone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8TEhCBbEexNvEfJ1F8pbY
@kaladinlight
kaladinlight force-pushed the fix/unreachable-swapper-timeout branch from f46a87f to 356e18d Compare September 2, 2026 21:07
@kaladinlight
kaladinlight enabled auto-merge (squash) September 2, 2026 21:07
@kaladinlight
kaladinlight merged commit 3b635ba into develop Sep 2, 2026
2 checks passed
@kaladinlight
kaladinlight deleted the fix/unreachable-swapper-timeout branch September 2, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant