Skip to content

Count the funding fee in the anchor reserve check for splice-ins - #1223

Open
shubhamkmr04 wants to merge 4 commits into
lightningdevkit:mainfrom
shubhamkmr04:splice-in-reserve-fees
Open

shubhamkmr04 wants to merge 4 commits into
lightningdevkit:mainfrom
shubhamkmr04:splice-in-reserve-fees

Conversation

@shubhamkmr04

Copy link
Copy Markdown
Contributor

Part of #1166. Builds on #1204, so only the last commit is new here.

When splicing in an exact amount, we checked that our on-chain funds cover the amount on top of the anchor reserve, but not the fee for our contribution to the splice transaction, which is paid from the same funds. Coin selection doesn't keep the reserve aside, so the fee could come out of it.

Changes

  • Exact splice_in: once LDK has built the contribution, we now pass what it takes from our wallet, its inputs minus its change, to check_sufficient_onchain_funds, and fail with InsufficientFunds if that exceeds the spendable balance. LDK runs coin selection with the shared input and output, so the change is net of the whole fee, and inputs minus change is exactly the amount plus our fee. Checking the built contribution also avoids estimating the fee up front, which Build splice_in_with_all from manually selected inputs #1176 moved away from for splice_in_with_all.
  • The existing check of the amount alone stays in front, so a plain lack of funds still fails before coin selection.
  • Docs for splice_in, and a CHANGELOG entry.

Testing

  • splice_in_fee_does_not_spend_anchor_reserve: node B holds 1,000,000 sats with a 25,000 sat anchor reserve. Splicing in 970,000 at 50 sat/vB fails with InsufficientFunds, because the ~12,500 sat fee would leave only ~17,500 for the reserve. The same amount at the regtest estimate splices in and keeps the reserve on-chain.

Fee bumps are left for a follow-up: the reserve check when a bump of an exact splice-in shrinks its change or re-runs coin selection, and when a bump of a splice-out falls back to the wallet, as discussed in #1181.

This change was developed with the assistance of Claude Code.

@ldk-reviews-bot

ldk-reviews-bot commented Nov 8, 2026 •

Copy link
Copy Markdown

I've assigned @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

Opening a channel with an exact amount only checked that our on-chain
funds cover the amount plus the anchor reserve, leaving out the fee of
the funding transaction, which is paid from the same funds. Since the
fee rate can now be chosen freely (lightningdevkit#1099), a high one could spend part
of the reserve, or leave too little to build the funding transaction
once the counterparty had accepted the channel.

`check_sufficient_onchain_funds` now takes the fee rate of a new
channel's funding transaction as an `Option` in place of its
`for_new_channel` flag. For a new channel, it also checks that the
amount doesn't exceed what opening the channel with all funds would add
at that fee rate, which already accounts for the fee and the reserve,
and fails with `InsufficientFunds` otherwise. `open_channel_inner`
resolves the fee rate once for both funding amounts.

Part of lightningdevkit#1166.

Developed with assistance from Claude Code.
Opening a channel with an exact amount now fails with
`InsufficientFunds` if the amount exceeds what the corresponding
`_with_all` variant would fund at the same fee rate. Say so in the docs
of the exact-amount variants and in the CHANGELOG, and test that an
open whose fee would come out of the anchor reserve fails, while the
same amount at a lower fee rate opens and keeps the reserve on-chain.

Part of lightningdevkit#1166.

Developed with assistance from Claude Code.
When acting as an LSPS2 service, we open a JIT channel once its payment
arrives, after checking that our on-chain funds cover the channel amount
plus the anchor reserve. As for exact-amount opens, this left out the fee
of the funding transaction, which is built later at our fee estimate and
paid from the same funds, so it could spend part of the reserve.

Also check that the channel amount doesn't exceed what funding with all
our funds would add at that estimate, and don't open the channel
otherwise, or if that maximum can't be determined. To do so, the LSPS2
service now has access to the fee estimator.

Part of lightningdevkit#1166.

Developed with assistance from Claude Code.
Splicing in an exact amount only checked that our on-chain funds cover
the amount on top of the anchor reserve. The fee for our contribution to
the splice transaction is paid from the same funds, though, and coin
selection doesn't keep the reserve aside, so the fee could be taken
from it.

Once the contribution is built, also check that what it takes from our
wallet, its inputs minus its change, fits in the funds beyond the
reserve, and fail with `InsufficientFunds` otherwise. The check of the
amount alone stays in front, so that a plain lack of funds still fails
before coin selection.

Part of lightningdevkit#1166.

Developed with assistance from Claude Code.
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