Skip to content

Fix liquidity event cancellation in select loop#21

Merged
amackillop merged 1 commit intolsp-0.7.0from
austin_prevent-liquidity-action-cancellation
Apr 21, 2026
Merged

Fix liquidity event cancellation in select loop#21
amackillop merged 1 commit intolsp-0.7.0from
austin_prevent-liquidity-action-cancellation

Conversation

@amackillop
Copy link
Copy Markdown

handle_next_event() both consumed events from the queue via next_event_async() and processed them inline, including spawn_blocking(...).await calls for wallet checks. Because this ran as a polled future inside tokio::select!, any tick timer firing while the handler was suspended at an .await point would cancel the future. The event had already been dequeued, so it was silently lost.

Split event receipt from processing: next_event_async() is polled as the select! future (cancellation-safe since it only dequeues on Poll::Ready), and handle_event() runs in the handler block which select! guarantees runs to completion before the next iteration.

This was the root cause of JIT channel opens and splices timing out in production. The HTLC would be intercepted, the OpenChannel event consumed from the queue, but a timer tick would cancel processing before create_channel was called. The peer would disconnect after 40s and the HTLC would expire.

handle_next_event() both consumed events from the queue via
next_event_async() and processed them inline, including
spawn_blocking(...).await calls for wallet checks. Because
this ran as a polled future inside tokio::select!, any tick
timer firing while the handler was suspended at an .await
point would cancel the future. The event had already been
dequeued, so it was silently lost.

Split event receipt from processing: next_event_async() is
polled as the select! future (cancellation-safe since it only
dequeues on Poll::Ready), and handle_event() runs in the
handler block which select! guarantees runs to completion
before the next iteration.

This was the root cause of JIT channel opens and splices
timing out in production. The HTLC would be intercepted,
the OpenChannel event consumed from the queue, but a timer
tick would cancel processing before create_channel was called.
The peer would disconnect after 40s and the HTLC would expire.
@amackillop amackillop merged commit 49798a0 into lsp-0.7.0 Apr 21, 2026
6 of 34 checks passed
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.

2 participants