Repository navigation
loopd: leave running loop outs to their own htlc sweep - #1294
Draft
claravanstaden wants to merge 3 commits into
Draft
claravanstaden wants to merge 3 commits into
claravanstaden wants to merge 3 commits into
Conversation
Add Client.LoopOutRunning so other daemon parts can tell whether a loop out is executing in this client. The executor marks a loop out as running before it hands the swap over and clears the mark when the swap goroutine returns. The method waits until pending swaps have been resumed, so a swap that is about to resume also counts as running. The htlc recovery worker uses this in the next commit to leave the HTLC of a running swap alone.
The htlc confirmed recovery worker swept a loop out HTLC directly, even when the swap was still running in this daemon. That sweep reveals the preimage, but nothing recorded the reveal. The running swap kept its unrevealed state, so near the expiry it, or the same swap resumed after a restart, could give up on the swap while the preimage was already public. Skip the direct sweep when the swap is running. The HTLC is left to the running swap, which records the preimage reveal and sweeps through the sweep batcher, or has decided not to reveal the preimage. The swap is found by its HTLC address, not by the notified hash. Swaps that are not running still get the direct sweep. The running check is a required dependency of the worker. Without it, or when it fails, the worker does not sweep.
claravanstaden
force-pushed
the
loopout-recovery-preimage-state
branch
from
November 13, 2026 09:37
1298ecb to
25c5744
Compare
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.
The htlc confirmed recovery worker swept a loop out HTLC directly even when the swap was still running in loopd. That sweep reveals the preimage, but nothing recorded the reveal, so the running swap, or the same swap resumed after a restart, kept treating the preimage as secret and could give up on the swap near its expiry while the preimage was already public.
Before and after
Before
After
Fix
The executor now tracks which loop outs are running, and
Client.LoopOutRunningexposes that after pending swaps have been resumed. The worker finds the swap by its HTLC address (not the notified hash) and skips the direct sweep when the swap is running. The HTLC is left to the running swap, which records the preimage reveal and sweeps through the sweep batcher, or has decided not to reveal the preimage. The running check is required: a worker without it, or one whose check fails, never sweeps. Swaps that are not running still get the direct sweep as before.Tests
TestLoopOutRunning: a loop out counts as running while it executes and stops counting after it finishes.TestLoopOutRunningWaitsForResumeandTestLoopOutRunningPendingSwap: the check blocks until the executor is ready and the pending swaps are resumed, and a pending swap counts as running right after start.TestExecutorLoopOutRunningHandover: a swap counts as running during the handover to the executor, and a canceled handover clears the mark.TestHtlcConfirmedRecoveryManagerRunningCheckFailClosed: no sweep when the running check is missing or fails.TestHtlcConfirmedRecoveryManagerSkipsRunningSwap: no sweep for a running swap, even when the notification names a different swap hash. Fails without the fix.TestHtlcConfirmedRecoveryManagerSweepsStoppedSwap: a swap that is not running still gets the direct sweep.Known limits