Repository navigation
Skip abandoned and unavailable channels when paying and when creating invoices - #759
Conversation
Introduce `channels::is_channel_available`, a single rule that decides
whether a channel can be used to send or receive, advertised as a
routehint, or awaited for (re-)establishment:
available := state == CHANNELD_NORMAL &&
(max_to_us_msat > 0 || short_channel_id.is_some())
`max_to_us_msat` is the monotonically increasing high-water mark of the
balance we have ever held. For zeroconf JIT channels, which may not have
a `short_channel_id` yet, a non-zero gauge signals that the incoming
JIT payment that opened the channel was claimed, so the LSP server has
no reason to have dropped the channel and awaiting it can succeed. A
channel that never held funds and was never confirmed is a dangling
channel open (typically an abandoned JIT channel): it will never come
back, yet we currently await it until the wait deadline expires and
fail otherwise perfectly payable invoices (gl#870, gl#871).
The current balance (`spendable_msat`) is deliberately secondary: a
drained but confirmed channel stays available.
Apply `channels::is_channel_available` to all channel selection sites: - `get_receivable_capacity`: the invoice-side JIT check now counts zeroconf channels whose JIT payment was claimed (gauge > 0) and confirmed incoming-only channels (scid), but never dangling, never-funded channel opens the LSP may have dropped. - `get_routehints`: unavailable channels never become routehints, so incoming payments are not routed into channels that may have been abandoned by their LSP server. - trampoline pay: drop unavailable channels before spawning awaitable tasks; awaiting an abandoned channel used to stall the payment for the full `AWAIT_CHANNELS_TIMEOUT_SEC` since `reestablished_channels` joins on every channel. The pre-existing `spendable_msat` filters remain for allocation purposes. This replaces the ad-hoc per-site filters (which used the current balance or `max_to_us_msat` alone, inconsistently) with the single availability rule (gl#871).
The billboard step of `AwaitableChannel` looped until the caller's wait deadline whenever a channel would never report "Channel ready" / "Reconnected, and reestablished", e.g. because it was closed or abandoned while the wait was in flight. Check the channel state on each billboard poll and return an error as soon as the channel is not (or no longer) in `CHANNELD_NORMAL`, so such channels are dropped from the wait immediately instead of stalling it until the deadline (gl#871). While at it remove the `v23.05gl1` version shims and the now unused `get_version` bookkeeping: nodes older than v25.12gl1 are not in use anymore.
|
A channel sits in that state from the splice commitment until
Suggestion: pass |
Summary
One rule decides everywhere whether a channel may be sent over, received over, advertised as a routehint, or awaited:
max_to_us_msatis the monotonically increasing high-water mark of the balance we ever held. For zeroconf JIT channels — which may not have ashort_channel_idyet — a non-zero gauge signals that the incoming JIT payment that caused the channel to be opened was claimed, so the LSP server has no reason to have dropped the channel and awaiting it can succeed. A channel that never held funds and was never confirmed is a dangling channel open, typically an abandoned JIT channel: it will never come back, yet we currently await it until the wait deadline expires and fail otherwise payable payments (gl#870, gl#871). The current balance (spendable_msat) stays secondary: drained-but-confirmed channels remain available.The rule lives once in
channels::is_channel_available, with primitive arguments so the internal plugin can reuse it after a submodule bump. Pre-v23.05gl1version shims and theget_versionmachinery inawaitablesare dropped — nodes older than v25.12gl1 are not in use anymore.Evidence
Before: gl#870, session 7490976188727296: a node with a healthy 2,575 sat channel plus an abandoned JIT channel (zero gauge, zeroconf, never confirmed) failed a 2,327 sat invoice — payable on the healthy channel alone — because the wait also waited for the abandoned channel, until the deadline expired and the payment failed as a timeout.
After: the abandoned channel is skipped at selection, and a channel that leaves
CHANNELD_NORMALmid-wait fails its await immediately.Unit coverage for the rule's truth table:
Merge Danger
Door: two-way — pure plugin-side channel selection, no persisted state, protocol, or wire format changes.
Blast Radius: invoice creation (JIT negotiation decision, routehints), trampoline pay channel selection, and channel reestablishment waits. Three visible behavior shifts:
CHANNELD_NORMALare skipped even when they show spendable capacity (e.g. currently closing ones) — payments no longer block on channels that can no longer carry them.