-
Notifications
You must be signed in to change notification settings - Fork 419
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
Update fee and dust handling for zero fee channels #3884
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
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()); |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
lightning/src/ln/channel.rs
Outdated
@@ -133,6 +134,22 @@ enum FeeUpdateState { | |||
Outbound, | |||
} | |||
|
|||
/// Returns the fees for success and timeout second stage HTLC transactions. |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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.
001c8e9
to
4157d24
Compare
4157d24
to
5fe6fa7
Compare
🔔 1st Reminder Hey @tankyleo! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still grokking some of the changes here and the zero-fee commitment proposal but from my kind of limited context it LGTM (:
5fe6fa7
to
f76a270
Compare
Addressed review: only major change is moving responsibility for not triggering |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM mod two nits, feel free to squash / ping second reviewer :)
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.
Co-authored-by: Matt Corallo <[email protected]>
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 fees would happen after multiplying by the number of HTLCs. Now the fees 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 fee amounts 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]>
Co-authored-by: Matt Corallo <[email protected]>
b421d59
to
60064d1
Compare
Squashed + addressed last 2x comments + rebased. Edit: plus small silent rebase failure, new test on master needed an import this branch deleted. |
Update test helper in preparation to test zero fee commitments, where the local balance will differ from the previously hardcoded value.
60064d1
to
54559b3
Compare
}; | ||
let real_dust_limit_success_sat = htlc_success_dust_limit + context.holder_dust_limit_satoshis; | ||
let real_dust_limit_timeout_sat = htlc_timeout_dust_limit + context.holder_dust_limit_satoshis; | ||
if funding.get_channel_type().supports_anchor_zero_fee_commitments() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non-blocking - should the comment on this method be updated? the htlc
is not an Option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nit and one thing maybe worth following up on, but not worth holding up on.
} | ||
|
||
/// Returns a fee estimate for the commitment transaction depending on channel type. | ||
pub(super) fn commitment_sat_per_1000_weight_for_type<F: Deref>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a huge fan of the name because it hides which fee types we're using - we're using the "feerates that we'd want to assign to a channel" types, which are different from the "minimum/maximum we'd let our peer assign to a channel", but the name doesn't capture that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you think of anything less atrociously long than holder_preferred_commitment_sat_per_1000_weight_for_type
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
selected_commitment_sat_per_1000_weight
?
} else { | ||
non_anchor_feerate | ||
}; | ||
let new_feerate = commitment_sat_per_1000_weight_for_type(&self.fee_estimator, funded_chan.funding.get_channel_type()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, would be nice to keep the old behavior where we fetch the feerates outside the loop. In general implementations of the FeeEstimator
trait should be pretty effecient, but if we can reduce the number of calls we probably should. Same above in maybe_update_chan_fees
.
This PR completes the off-chain handling of V3 channels, as described in #3789.