Skip to content

Error if the calculated reserve would be greater than the channel value#4580

Draft
tankyleo wants to merge 8 commits intolightningdevkit:mainfrom
tankyleo:2026-04-reserve-greater-than-channel-value
Draft

Error if the calculated reserve would be greater than the channel value#4580
tankyleo wants to merge 8 commits intolightningdevkit:mainfrom
tankyleo:2026-04-reserve-greater-than-channel-value

Conversation

@tankyleo
Copy link
Copy Markdown
Contributor

Based on #4550, draft until parent goes in

As a result, we now validate that both commitments retain at least one
output under the new funding scope, which is crucial for zero-reserve
channels.
We previously determined this value by subtracting the htlcs, the
anchors, and the commitment transaction fee. This ignored the reserve,
as well as the at-least-one-output requirement in zero-reserve channels.

This new field now accounts for both of these constraints. It can be
seen as the total spliceable balance from the channel.
This is equivalent to the previous commit, see the debug assertions
added in the previous commit. We now also get to communicate the
exact maximum back to the user, instead of some "balance is lower
than our reserve" message, which is hard to react to.
We did not enforce this minimum when accepting 0-reserve channels. This
is because we depended on the `MIN_THEIR_CHAN_RESERVE_SATOSHIS` constant
to guarantee this minimum channel value, but this value is no longer
read in 0-reserve channels.

Note that the user's `min_funding_satoshis` value would still be
respected in this case.

When splicing 0-reserve channels, we only enforced that the commitment
transaction retained at least one output after the splice, which could
produce a channel value lower than 1000sats.

Along the way, we also now enforce this 1000sat minimum when splicing
reserve-enabled channels. We previously correctly enforced the reserves
after the splice, but this could still result in a channel value smaller
than 1000sats. This case is now rejected during splice validation.

Note that the user's `min_funding_satoshis` is not respected when
validating splice contributions, we leave this for follow-up work.
@ldk-reviews-bot
Copy link
Copy Markdown

👋 Hi! I see this is a draft PR.
I'll wait to assign reviewers until you mark it as ready for review.
Just convert it out of draft status when you're ready for review!

In 0FC channels, capping the reserve to the total value of the channel
allowed a splice initiator to withdraw past their reserve in case the
acceptor had no balance in the channel.

This is because the post-splice value of the channel was equal to the
initiator's post splice balance. Hence, this post splice balance always
matched the reserve, even though the reserve was below the dust limit.

The only thing that prevented the initiator from withdrawing all their
balance was the script dust limit check in
`interactivetxs::NegotiationContext::receive_tx_add_output`.

In case the splice acceptor had any balance in the channel, or there
were HTLCs in the channel, or the channel was not 0FC, the
splice initiator's post-splice balance was always below the full channel
value. Hence when the reserve was capped at the channel value, the
post-splice balance was always below the reserve, and the splice was
rejected.

Also, in `validate_splice_contributions`, to determine the
`counterparty_selected_channel_reserve`, we now read the holder's dust
limit from the context, instead of the current global constant.
We made the same change to the calculation of the v2 reserve in the
previous commit.
@tankyleo tankyleo force-pushed the 2026-04-reserve-greater-than-channel-value branch from 7d64174 to 06a604d Compare April 30, 2026 01:52
@tankyleo tankyleo self-assigned this Apr 30, 2026
@tankyleo tankyleo moved this to Goal: Merge in Weekly Goals Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Goal: Merge

Development

Successfully merging this pull request may close these issues.

2 participants