Skip to content

Disallow holders from selecting 0-reserve in legacy channels#4613

Open
tankyleo wants to merge 5 commits into
lightningdevkit:mainfrom
tankyleo:2026-05-ban-0reserve-legacy-chans
Open

Disallow holders from selecting 0-reserve in legacy channels#4613
tankyleo wants to merge 5 commits into
lightningdevkit:mainfrom
tankyleo:2026-05-ban-0reserve-legacy-chans

Conversation

@tankyleo
Copy link
Copy Markdown
Contributor

@tankyleo tankyleo commented May 13, 2026

We still allow counterparties to set 0-reserve legacy channels, as in prior releases.

@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented May 13, 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 added this to the 0.3 milestone May 13, 2026
@tankyleo tankyleo moved this to Goal: Merge in Weekly Goals May 13, 2026
@tankyleo tankyleo self-assigned this May 13, 2026
@tankyleo tankyleo force-pushed the 2026-05-ban-0reserve-legacy-chans branch 4 times, most recently from e90865f to 603754d Compare May 15, 2026 07:37
@tankyleo tankyleo changed the title Disallow opening and accepting 0-reserve legacy channels Disallow holders from selecting 0-reserve in legacy channels May 15, 2026
@tankyleo tankyleo marked this pull request as ready for review May 15, 2026 08:00
@tankyleo tankyleo requested review from TheBlueMatt and removed request for joostjager May 15, 2026 08:02
use crate::sign::ChannelSigner;
use crate::types::features::ChannelTypeFeatures;
use crate::types::payment::{PaymentHash, PaymentPreimage};
use crate::types::payment::PaymentPreimage;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: PaymentHash is imported from bolt11_invoice which re-exports it from lightning_types::payment. Every other file in this crate imports it from crate::types::payment::PaymentHash. Consider keeping it consistent:

Suggested change
use crate::types::payment::PaymentPreimage;
use crate::types::payment::{PaymentHash, PaymentPreimage};

(and removing the bolt11_invoice::PaymentHash import on line 30)

connect_peers(&nodes[0], &nodes[1]);
connect_peers(&nodes[1], &nodes[2]);

let set_0reserve = if chan_type == ChanType::Legacy { false } else { true };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: This can be simplified to chan_type != ChanType::Legacy (which also explains why PartialEq was derived above).

Comment on lines 2090 to 2091
// A-B: channel 2 A and B have 0-reserve (trusted open + trusted accept),
// channel 3 A has 0-reserve (trusted accept).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The comments on lines 2090-2091 and 2095-2096 still describe channel 2/3/4/5 as having 0-reserve unconditionally, but that's no longer the case for ChanType::Legacy. Consider qualifying these with "if non-legacy" or restructuring the comments to be accurate for both code paths.

@ldk-claude-review-bot
Copy link
Copy Markdown
Collaborator

ldk-claude-review-bot commented May 15, 2026

Good — confirmed that spiked_feerate (via local_max_commit_tx_fee_sat and local_min_commit_tx_fee_sat) is only consumed inside the if is_outbound_from_holder block and in get_next_splice_out_maximum_sat (also guarded by is_outbound_from_holder). The removal of the is_outbound_from_holder guard on the spiked_feerate computation doesn't change behavior.

I've now reviewed every file and every hunk in the diff. The prior review comments already covered all the nits I found. No bugs, security issues, or logic errors beyond those nits.

Review Summary

No bugs or security issues found. The three nits from my prior review remain the only findings:

  1. lightning/src/ln/htlc_reserve_unit_tests.rs:26PaymentHash imported from bolt11_invoice instead of crate::types::payment, inconsistent with the rest of the crate
  2. fuzz/src/chanmon_consistency.rs:2085if chan_type == ChanType::Legacy { false } else { true } can be simplified to chan_type != ChanType::Legacy
  3. fuzz/src/chanmon_consistency.rs:2090-2091 — Channel comments describe 0-reserve unconditionally but that's no longer true for Legacy

All enforcement points (outbound creation, inbound acceptance, accept-channel validation, channel-type downgrade) are correctly implemented. The relaxation of get_available_balances from spiked to current feerate for the no-output boundary checks is safe because get_next_commitment_stats still hard-checks at the spiked feerate. The spiked_feerate condition change (removing is_outbound_from_holder) in get_available_balances has no behavioral impact since it's only consumed in outbound-guarded paths.

No new issues to report.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

❌ Patch coverage is 94.54545% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.40%. Comparing base (b8118e3) to head (96a9e7b).

Files with missing lines Patch % Lines
lightning/src/ln/channel.rs 90.32% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4613      +/-   ##
==========================================
- Coverage   86.40%   86.40%   -0.01%     
==========================================
  Files         158      158              
  Lines      109293   109294       +1     
  Branches   109293   109294       +1     
==========================================
- Hits        94439    94432       -7     
- Misses      12309    12313       +4     
- Partials     2545     2549       +4     
Flag Coverage Δ
fuzzing-fake-hashes 5.08% <0.00%> (-0.01%) ⬇️
fuzzing-real-hashes 22.77% <60.00%> (-0.02%) ⬇️
tests 86.13% <94.54%> (-0.01%) ⬇️

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
Copy Markdown
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.

LGTM, but please reorder the commits so that the "remove tests of legacy + 0-reserve" change happens before we remove the legacy reserve change, that way at each commit tests pass.

tankyleo added 4 commits May 15, 2026 14:45
We still allow counterparties to set 0-reserve legacy channels, as in
prior releases.
We only assume fee spikes in legacy channels, and we do not allow
`holder_selected_channel_reserve_satoshis` to be set to zero in such
channels. It is nonetheless still possible to reach the no-outputs case
in a fee spike with solely the counterparty selected reserve set to
zero, so we still guard against this case in
`get_next_commitment_stats`.

We don't guard against no-outputs under fee spikes
`get_available_balances`; in the worst case, the receiver of the HTLC we
just sent fails it back.
@tankyleo tankyleo force-pushed the 2026-05-ban-0reserve-legacy-chans branch from 603754d to 96a9e7b Compare May 15, 2026 14:48
@tankyleo
Copy link
Copy Markdown
Contributor Author

Thank you done, no other changes

@tankyleo tankyleo requested a review from TheBlueMatt May 15, 2026 14:51
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.

4 participants