Skip to content

Update fee and dust handling for zero fee channels #3884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

carlaKC
Copy link
Contributor

@carlaKC carlaKC commented Jun 23, 2025

This PR completes the off-chain handling of V3 channels, as described in #3789.

carlaKC and others added 9 commits June 13, 2025 14:58
This fee rate is currently used in two scenarios:
- To count any fees above what we consider to be a sane estimate towards
  our dust exposure.
- To get a maximum dust exposure (when using
  MaxDustHTLCExposure::FeeEstimator strategy).

When we have zero fee commitments:
- Commitments are zero fee, so we don't need to count fees towards dust
  exposure.
- The amount of dust we have is not dependent on fees, as everything is
  zero fee.
- We still want to limit our total dust exposure.

This commit updates get_dust_exposure_limiting_feerate to allow a None
value to prepare for support for zero fee commitments. This clearly
allows us to indicate when we don't care about fee rates for dust
considerations.

In get_max_dust_htlc_exposure_msat, we simply hardcode a value of
1 sat/vbyte if a feerate dependent strategy is being used.
LDK does not support a channel type that supports both zero fee and
nonzero fee anchors (as this is impossible), so we can drop the
unnecessary check in build_htlc_output.
This commit pulls calculation of second stage fees into a helper
function. A side effect of this refactor is that it fixes a rounding
issue in commit_and_htlc_tx_fees_sat. Previously, rounding down of
feerate would happen after multiplying by the number of HTLCs. Now the
feerate will be rounded down before multiplying by the number of HTLCs.

This wasn't a serious issue - it would just cause us very slightly
over estimate our dust exposure at certain feerates that needed
rounding. A hard-coded value in test_nondust_htlc_excess_fees_are_dust
is updated to account for this rounding change.
Update second_stage_tx_fees_sat to return zero for zero fee commitments.
As is the case for anchors_zero_fee_commitments, this changes ensures
that we won't trim the second stage transaction fee off of the HTLC
amount.
When we have zero fee commitments, we don't need to calculate our fee
rate or check that it isn't stale because it is always zero.

Co-authored-by: Matt Corallo <[email protected]>
@ldk-reviews-bot
Copy link

👋 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!

@carlaKC
Copy link
Contributor Author

carlaKC commented Jun 23, 2025

This still needs a few tests, opening up early for conceptual review.

@@ -5078,6 +5092,7 @@ where
) -> u64 {
if funding.get_channel_type().supports_anchor_zero_fee_commitments() {
debug_assert_eq!(self.feerate_per_kw, 0);
debug_assert!(fee_spike_buffer_htlc.is_none());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wondering whether it's worth having this assertion (which makes it necessary to check channel type before calling fee functions). The alternative would be to just ignore the parameters completely for zero fee channels (even though Some fee_spike_buffer_htlc doesn't make sense for the type).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't say I have a strong preference. The assertion seems fine to me.

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.

All LGTM, didn't carefully check every hunk, though.

@@ -133,6 +134,22 @@ enum FeeUpdateState {
Outbound,
}

/// Returns the fees for success and timeout second stage HTLC transactions.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Probably belongs in chan_utils.rs given it kinda mirrors commit_and_htlc_tx_fees_sat and is also called from there?

@@ -5078,6 +5092,7 @@ where
) -> u64 {
if funding.get_channel_type().supports_anchor_zero_fee_commitments() {
debug_assert_eq!(self.feerate_per_kw, 0);
debug_assert!(fee_spike_buffer_htlc.is_none());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't say I have a strong preference. The assertion seems fine to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Goal: Open
Development

Successfully merging this pull request may close these issues.

3 participants