You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Field report from a production ASB (mainnet, 2026-08-31): a Monero lock transaction was constructed from an output that a concurrent swap had just spent, then rejected in a loop until the cancel timelock expired. The swap ended in the known ghost state (XmrRefundable) and required manual SafelyAborted cleanup. This happened with PR #1193 applied, so it is the residual "wallet2 lag" race that #1193's description honestly flags, not the pre-#1193 failure mode.
Mainnet, single ASB process, max_buy_btc = 0.05 at the time
No external wallet interference; funds were only ever touched by the ASB wallet
Timeline (UTC, same ASB process)
Time
Event
13:52:24
Swap A 1447d921… setup completed
13:55:34
Swap B f70b01e7… setup completed
13:56:29
B: Bob's BTC lock in mempool
13:59:27
A: btc is locked
13:59:28
A: xmr lock transaction constructed
13:59:29
A: xmr lock published successfully (tx 43588a69…)
13:59:30
B: btc is locked
13:59:32
B: xmr lock transaction constructed (tx e40bf3ae…) — 3 s after A published
13:59:33+
B: publish → TransactionRejected (43 retries in the first ~20 min, hundreds overall)
14:19:30
B: "Monero lock phase exceeded its deadline; releasing the lock" — retries continued anyway
16:52:39
B: cancel timelock expired → btc is cancelled
16:59:51
B: btc is refunded → xmr is refundable → "waiting for Monero lock tx to be confirmed" (never comes)
17:16
B manually archived as SafelyAborted (documented ghost-order cleanup; XMR lock never confirmed on-chain)
What we observed
The two lock transactions were constructed 3 seconds apart; both selected the same unlocked output. A's publish won, B's publish was rejected forever because its input was already spent.
Retrying the same rejected tx hash cannot succeed; the ASB kept hammering TransactionRejected for hours until the cancel timelock.
Impact: counterparty BTC locked until the cancel timelock (~3.5 h), a ghost inflight that blocked safe ASB restart, and manual DB cleanup. No funds lost.
Relation to upstream work
This is exactly the "wallet2 lag" caveat acknowledged in #1193 (author reproduced the wedge on live mainnet on 2026-08-21).
#1142 ("rebuild xmr lock tx on confirmed double spend") looks like the right follow-up: when the wallet confirms the input was double-spent, rebuild the lock tx from fresh outputs instead of retrying a dead tx.
Please consider serializing the construction step (mutex around output selection + construction), not only publication — the 3 s window above shows construction is still racy.
Optionally, check is_key_image_spent before/after publishing so a spent-input lock is abandoned immediately instead of retried.
Happy to provide full logs or a DB dump on request.
Summary
Field report from a production ASB (mainnet, 2026-08-31): a Monero lock transaction was constructed from an output that a concurrent swap had just spent, then rejected in a loop until the cancel timelock expired. The swap ended in the known ghost state (
XmrRefundable) and required manualSafelyAbortedcleanup. This happened with PR #1193 applied, so it is the residual "wallet2 lag" race that #1193's description honestly flags, not the pre-#1193 failure mode.Environment
max_buy_btc = 0.05at the timeTimeline (UTC, same ASB process)
1447d921…setup completedf70b01e7…setup completed43588a69…)e40bf3ae…) — 3 s after A publishedTransactionRejected(43 retries in the first ~20 min, hundreds overall)xmr is refundable→ "waiting for Monero lock tx to be confirmed" (never comes)SafelyAborted(documented ghost-order cleanup; XMR lock never confirmed on-chain)What we observed
TransactionRejectedfor hours until the cancel timelock.inflightthat blocked safe ASB restart, and manual DB cleanup. No funds lost.Relation to upstream work
Request
is_key_image_spentbefore/after publishing so a spent-input lock is abandoned immediately instead of retried.Happy to provide full logs or a DB dump on request.