AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 69 Bitcoin

Release `OutputSweeper::pending_sweep` flag on future drop

Public commit record

What the developer wrote

Authored by Elias Rohrer

85/100 · Strong
Release `OutputSweeper::pending_sweep` flag on future drop

`regenerate_and_broadcast_spend_if_necessary` used `pending_sweep:
AtomicBool` as a single-runner gate but only cleared the flag with an
unconditional `store(false)` *after* the inner future resolved. If the
caller's future was dropped while the inner await was `Pending` —
which `tokio::time::timeout`, `futures::select!`, manual
`JoinHandle::abort`, etc. all do — the reset never ran, leaving the
flag stuck `true` and every subsequent call to the function
short-circuiting with `Ok(())`.

Because `OutputSweeper` is what claims `SpendableOutputDescriptor`s
back to the user's wallet after channel closure (including HTLC
outputs with time-bounded recovery deadlines), a stuck flag turns
into fund-loss exposure: time-sensitive HTLC sweeps simply stop
happening, while every other code path keeps queueing new outputs to
sweep, until the process is restarted.

Replace the trailing `store(false)` with an RAII `PendingSweepGuard`
whose `Drop` impl always releases the flag — covering normal return,
error, and cancellation alike.

Co-Authored-By: HAL 9000
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
The short version

What changed, and why it matters

This commit fixes a bug in rust-lightning's OutputSweeper where a cancellation-safe flag was not actually cancellation-safe. If the future performing sweep operations was dropped mid-await (for example, due to a timeout or abort), a 'sweep in progress' flag would stay stuck on, permanently disabling the sweeper. Because the sweeper is responsible for recovering funds from closed Lightning channels, including time-sensitive HTLC outputs, a stuck flag could lead to real fund loss until the process restarted. The fix replaces a manual flag-clear that ran only on normal completion with an RAII guard whose Drop implementation always releases the flag, even when the future is cancelled. A regression test is included.

Recommended action

Treat this as a security-reliability fix and include it in the next maintenance release. Users running nodes with async cancellation patterns (tokio timeouts, select!, abort handles) should upgrade promptly because the bug can silently stop on-chain fund recovery. Review other AtomicBool or Mutex-based single-runner gates in the codebase for similar cancellation hazards.

Security signals we found

01

AtomicBool gate not cleared on async cancellation leading to permanent functional disablement

02

OutputSweeper responsible for broadcasting recovery transactions for SpendableOutputDescriptor outputs after channel closure

03

HTLC sweep transactions are time-bounded; failure to broadcast can cause irrecoverable fund loss

04

Fix uses RAII Drop guard to guarantee flag release on all control-flow paths including future drop

05

Regression test explicitly simulates cancellation via future drop and asserts flag reset

Risk score

Why this scored 69/100

Our methodology →
Potential impact 28/30
Exploitability 5/25
Stealth signal 12/15
Affected reach 10/15
Confidence 9/10
Evidence quality 5/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.