Repository navigation
LSPS4: budget forwards by next_outbound_htlc_limit_msat - #31
martinsaposnic wants to merge 1 commit into
Conversation
calculate_htlc_actions_for_peer compared each HTLC against the channel's outbound_capacity_msat. That figure ignores the commitment fee the funder pays for one more HTLC output (and dust exposure / in-flight limits), so the largest HTLC LDK will send is next_outbound_htlc_limit_msat, which is lower. An HTLC in that gap was "forwarded": forward_intercepted_htlc returned Ok, then LDK failed it back with temporary_channel_failure and no splice was ever requested. Seen in regtest on the 4th 9,800 sat payment into a 50k sat JIT channel, every time. Use next_outbound_htlc_limit_msat so such HTLCs get a splice/open instead. Forwarded amounts and the inbound >= outbound check are unchanged.
VerificationUnit/integration (#31):
Local e2e A/B (regtest stack, same script, fresh
LSP log for the 4th payment: CI: build + e2e (workspace, workspace-preview, legacy-0.18.0, legacy-0.15.0) pass. Fund-safety analysis
Upstream LSPS2Not affected by this bug class. Upstream LSPS2 (v0.2.7 Relation to the bfc1b29 security fixNone. bfc1b29 did not touch capacity code. The |
Bug
calculate_htlc_actions_for_peercompared each HTLC withoutbound_capacity_msat. That figure does not count the commitment fee the funder (LSP) pays for one more HTLC output, or dust exposure and in-flight limits. The largest HTLC LDK will really send isnext_outbound_htlc_limit_msat, and it is lower.An HTLC in that gap went to
forward_intercepted_htlc, which returnedOk. Then LDK failed it back withtemporary_channel_failure, and no splice was requested. In regtest, the 4th 9,800 sat payment into a 50k sat JIT channel fails every time, on old and new LSP images alike.Fix
Use
next_outbound_htlc_limit_msatin the capacity map. HTLCs in the gap now getSpliceChannel(orOpenChannel) and are held until the timer forwards them.Not changed
channel_over_provisioning_ppm, 500k in lightning-node, so after a splice the limit covers the HTLC).Tests
htlc_above_send_limit_but_within_capacity_gets_liquidity: fails before the fix (Expected SpliceChannel, got None), passes after. It asserts the HTLC is still pending and not failed back.htlc_at_send_limit_is_forwarded(control): the largest forward that fits is still forwarded and reaches the client.Known limit
Later HTLCs in one batch subtract only their amount, not the extra commitment fee each one adds. Such a batch can still overshoot and fail back. No funds move in that case, and the sender retries.