fix(ecash): stop replayed Minibits claims retrying forever, reduce relay churn #160

Merged
chaum merged 3 commits from fix/minibits-already-redeemed into main 2026-09-15 16:32:54 +00:00
Collaborator

Fixes the Minibits Cashu claim poller retrying an already-redeemed token forever (mint error 11001), which pinned pending_claims at 1 and showed "a payment arrived but couldn't be redeemed yet" permanently. Also reduces relay churn (query the primary relay first, fall back only if unreachable) and pages past a 200-DM backlog.

Root cause: this exact fix existed on feat/minibits-lnurl-receive (2026-09-09) but that branch was never merged into main, which has its own diverged minibits.rs. Ported directly onto main this time.

Full writeup: docs/incident-2026-09-15-minibits-already-redeemed.md.

Live: unstuck archy-x250-pa3 by hand (cleared the one poisoned, already-redeemed pending_claims entry; zero value at risk), confirmed clean polling via journalctl.

cargo test -p archipelago --bin archipelago wallet::minibits: 15 passed, 1 ignored (live-network test), 0 failed.

🤖 Generated with Claude Code

Fixes the Minibits Cashu claim poller retrying an already-redeemed token forever (mint error 11001), which pinned `pending_claims` at 1 and showed "a payment arrived but couldn't be redeemed yet" permanently. Also reduces relay churn (query the primary relay first, fall back only if unreachable) and pages past a 200-DM backlog. Root cause: this exact fix existed on `feat/minibits-lnurl-receive` (2026-09-09) but that branch was never merged into `main`, which has its own diverged `minibits.rs`. Ported directly onto `main` this time. Full writeup: `docs/incident-2026-09-15-minibits-already-redeemed.md`. Live: unstuck archy-x250-pa3 by hand (cleared the one poisoned, already-redeemed `pending_claims` entry; zero value at risk), confirmed clean polling via journalctl. `cargo test -p archipelago --bin archipelago wallet::minibits`: 15 passed, 1 ignored (live-network test), 0 failed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ssmithx added 1 commit 2026-09-15 16:18:01 +00:00
claim_and_redeem retried every redeem failure indefinitely, including a
terminal one: mint error 11001 "Token Already Spent" (a claim replayed by a
relay-watermark edge case, or already redeemed by an earlier run). On
archy-x250-pa3 this pinned pending_claims at 1 forever and hammered
mint.minibits.cash's swap endpoint every ~6s, with the UI permanently
showing "a payment arrived but couldn't be redeemed yet".

- mint_client: expose the NUT error-code-11001 message as
  ALREADY_REDEEMED_MSG so callers can recognize it without duplicating the
  string.
- minibits: drop (not retry) a redeem failure that matches
  is_already_redeemed — the value was already swept, so retrying can never
  succeed.
- fetch_relay_dms: query the primary relay.minibits.cash alone first,
  falling back to the public relay.damus.io/nos.lol only if it's
  unreachable, and page past a 200-DM backlog instead of silently
  stranding older DMs behind an un-advanced watermark.

This fix already existed on feat/minibits-lnurl-receive (4e410d7, 489995c,
2026-09-09) but that branch was never merged into main, which has its own
independently-diverged minibits.rs — so the bug shipped again in
1.8.16-alpha. Ported directly onto main's current implementation this time.

Immediate unblock on archy-x250-pa3: cleared the one poisoned
pending_claims entry from wallet/minibits.json by hand (already-redeemed,
zero value at risk) and restarted archipelago.service; confirmed via
journalctl that polling is quiet again.

See docs/incident-2026-09-15-minibits-already-redeemed.md for the full
writeup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ssmithx added 1 commit 2026-09-15 16:19:29 +00:00
chaum added 1 commit 2026-09-15 16:31:52 +00:00
chaum merged commit 38de1b3310 into main 2026-09-15 16:32:54 +00:00
Sign in to join this conversation.