Skip to content

Open and accept zero reserve channels#4428

Open
tankyleo wants to merge 6 commits intolightningdevkit:mainfrom
tankyleo:2026-02-zero-reserve
Open

Open and accept zero reserve channels#4428
tankyleo wants to merge 6 commits intolightningdevkit:mainfrom
tankyleo:2026-02-zero-reserve

Conversation

@tankyleo
Copy link
Contributor

@tankyleo tankyleo commented Feb 19, 2026

Fixes #1801

@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Feb 19, 2026

👋 Thanks for assigning @TheBlueMatt 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.

@tankyleo tankyleo moved this to Goal: Merge in Weekly Goals Feb 19, 2026
@tankyleo tankyleo self-assigned this Feb 19, 2026
@tankyleo tankyleo force-pushed the 2026-02-zero-reserve branch from ffa1657 to 5fa3a7c Compare February 26, 2026 09:56
@tankyleo tankyleo marked this pull request as ready for review February 26, 2026 10:45
@tankyleo tankyleo requested a review from TheBlueMatt February 26, 2026 10:46
@tankyleo tankyleo added this to the 0.3 milestone Feb 26, 2026
@codecov
Copy link

codecov bot commented Feb 26, 2026

Codecov Report

❌ Patch coverage is 78.74818% with 146 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.91%. Comparing base (14e522f) to head (5fa3a7c).
⚠️ Report is 25 commits behind head on main.

Files with missing lines Patch % Lines
lightning/src/ln/channel.rs 70.64% 121 Missing and 2 partials ⚠️
lightning/src/ln/channelmanager.rs 81.70% 15 Missing ⚠️
lightning/src/ln/functional_test_utils.rs 94.33% 6 Missing ⚠️
lightning/src/sign/tx_builder.rs 97.46% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4428      +/-   ##
==========================================
- Coverage   85.94%   85.91%   -0.03%     
==========================================
  Files         159      159              
  Lines      104644   105103     +459     
  Branches   104644   105103     +459     
==========================================
+ Hits        89934    90298     +364     
- Misses      12204    12300      +96     
+ Partials     2506     2505       -1     
Flag Coverage Δ
tests 85.91% <78.74%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chanmon_consistency needs to be updated to have a 0-reserve channel or two (I believe we now have three channels between each pair of peers, so we can just do it on a subset of them, in fact we could have three separate channel types for better coverage).

/// Creates a new outbound channel to the given remote node and with the given value.
///
/// The only difference between this method and [`ChannelManager::create_channel`] is that this method sets
/// the reserve the counterparty must keep at all times in the channel to zero. This allows the counterparty to
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: If that's the only difference let's say create_channel_to_trusted_peer_0_reserve? Nice to be explicit, imo.


let channel_value_satoshis =
our_funding_contribution_sats.saturating_add(msg.common_fields.funding_satoshis);
// TODO(zero_reserve): support reading and writing the `disable_channel_reserve` field
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions. Shouldn't we check that if a channel has the 0-reserve feature bit and if it is fail if the user isn't accepting 0-reserve? Also why shouldn't we just set it now? I'm not sure we need to bother with a staging bit, really, honestly...

@TheBlueMatt
Copy link
Collaborator

Needs rebase now :/

@tankyleo tankyleo force-pushed the 2026-02-zero-reserve branch from 471ba8f to 253db4d Compare March 5, 2026 10:55
@tankyleo tankyleo requested a review from TheBlueMatt March 5, 2026 10:57
@tankyleo
Copy link
Contributor Author

tankyleo commented Mar 5, 2026

Needs rebase now :/

Let me know if you prefer I rebase first

@TheBlueMatt
Copy link
Collaborator

Feel free to go ahead and rebase and squash, yea.

@tankyleo tankyleo force-pushed the 2026-02-zero-reserve branch 2 times, most recently from 5fa3a7c to 43be438 Compare March 5, 2026 17:21
@tankyleo
Copy link
Contributor Author

tankyleo commented Mar 5, 2026

Squash diff (do not click compare just above, I pushed the wrong branch, and later corrected it):

https://github.com/lightningdevkit/rust-lightning/compare/253db4d9a05cda43f74c2835448126d3205b27b8..43be438f70ba28ad7918e407026a78763ac2b368

tankyleo added 6 commits March 5, 2026 17:32
The goal is to prevent any commitments with no outputs, since these are
not broadcastable.
This new flag sets 0-reserve for the channel opener.
This new method sets 0-reserve for the channel accepter.
`ChannelContext::do_accept_channel_checks`,
`ChannelContext::new_for_outbound_channel`,
`ChannelContext::new_for_inbound_channel`,
`InboundV1Channel::new`,
`OutboundV1Channel::new`.
@tankyleo tankyleo force-pushed the 2026-02-zero-reserve branch from 43be438 to 7fde002 Compare March 5, 2026 17:36
@tankyleo
Copy link
Contributor Author

tankyleo commented Mar 5, 2026

git range-diff main 43be438 7fde002

1:  bfba6e993 ! 1:  b916c3596 Add inbound and outbound checks for zero reserve channels
    @@ lightning/src/ln/channel.rs: impl FundingScope {

                // New reserve values are based on the new channel value and are v2-specific
     -          let counterparty_selected_channel_reserve_satoshis =
    --                  Some(get_v2_channel_reserve_satoshis(post_channel_value, MIN_CHAN_DUST_LIMIT_SATOSHIS));
    +-                  get_v2_channel_reserve_satoshis(post_channel_value, MIN_CHAN_DUST_LIMIT_SATOSHIS);
     -          let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
     -                  post_channel_value,
     -                  context.counterparty_dust_limit_satoshis,
    @@ lightning/src/ln/channel.rs: impl FundingScope {
     +                  == 0
     +          {
     +                  // If we previously had a 0-value reserve, continue with the same reserve
    -+                  Some(0)
    ++                  0
     +          } else {
    -+                  Some(get_v2_channel_reserve_satoshis(post_channel_value, MIN_CHAN_DUST_LIMIT_SATOSHIS))
    ++                  get_v2_channel_reserve_satoshis(post_channel_value, MIN_CHAN_DUST_LIMIT_SATOSHIS)
     +          };
     +          let holder_selected_channel_reserve_satoshis =
     +                  if prev_funding.holder_selected_channel_reserve_satoshis == 0 {
    @@ lightning/src/sign/tx_builder.rs: fn get_next_commitment_stats(
        );

     @@ lightning/src/sign/tx_builder.rs: fn get_available_balances(
    -   let fee_spike_buffer_htlc =
                if channel_type.supports_anchor_zero_fee_commitments() { 0 } else { 1 };

    +   // Note that the feerate is 0 in zero-fee commitment channels, so this statement is a noop
     -  let local_feerate = feerate_per_kw
     +  let spiked_feerate = feerate_per_kw
                * if is_outbound_from_holder && !channel_type.supports_anchors_zero_fee_htlc_tx() {
2:  1f8ca6c66 = 2:  53fc9a354 Add 0-reserve to `accept_inbound_channel_from_trusted_peer`
3:  1b94f7cc3 = 3:  da0520818 Add `ChannelManager::create_channel_to_trusted_peer_0reserve`
4:  19b8d7943 = 4:  1905f94e7 Shakedown zero reserve channels
5:  de2366da4 = 5:  4e6a7527a Format `ChannelManager::create_channel_internal` and...
6:  43be438f7 = 6:  7fde002e7 Update `chanmon_consistency` to include 0FC and 0-reserve channels

@ldk-reviews-bot
Copy link

✅ Added second reviewer: @joostjager

@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @TheBlueMatt @joostjager! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

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.

Support 0 counterparty channel reserve

3 participants