Skip to content

Commit 257033f

Browse files
committed
Don't check for no-outputs under fee spikes in get_available_balances
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.
1 parent c199697 commit 257033f

1 file changed

Lines changed: 39 additions & 56 deletions

File tree

lightning/src/sign/tx_builder.rs

Lines changed: 39 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ fn get_next_commitment_stats(
285285

286286
// For zero-reserve channels, we check two things independently:
287287
// 1) Given the current set of HTLCs and feerate, does the commitment have at least one output ?
288+
//
289+
// We only assume fee spikes in legacy channels, and we do not allow
290+
// `holder_selected_channel_reserve_satoshis` to be set to zero in such channels. It is
291+
// nonetheless still possible to reach the no-outputs case in a fee spike with solely the
292+
// counterparty selected reserve set to zero, so we still guard against this case here.
293+
//
294+
// We don't guard against no-outputs under fee spikes further below in
295+
// `get_available_balances`; in the worst case, the receiver of the HTLC we just sent fails
296+
// it back.
288297
if !has_output(
289298
is_outbound_from_holder,
290299
holder_balance_before_fee_msat,
@@ -349,9 +358,9 @@ fn get_next_commitment_stats(
349358
// 3) s < (100h + 100 - 100d - c) / 99
350359
fn get_next_splice_out_maximum_sat(
351360
is_outbound_from_holder: bool, channel_value_satoshis: u64, local_balance_before_fee_msat: u64,
352-
remote_balance_before_fee_msat: u64, spiked_feerate: u32,
353-
spiked_feerate_nondust_htlc_count: usize, post_splice_delta_above_reserve_sat: u64,
354-
channel_constraints: &ChannelConstraints, channel_type: &ChannelTypeFeatures,
361+
remote_balance_before_fee_msat: u64, feerate_per_kw: u32, nondust_htlc_count: usize,
362+
post_splice_delta_above_reserve_sat: u64, channel_constraints: &ChannelConstraints,
363+
channel_type: &ChannelTypeFeatures,
355364
) -> u64 {
356365
let local_balance_before_fee_sat = local_balance_before_fee_msat / 1000;
357366
let mut next_splice_out_maximum_sat = if channel_constraints
@@ -423,23 +432,23 @@ fn get_next_splice_out_maximum_sat(
423432
//
424433
// If the current `next_splice_out_maximum_sat` would produce a local commitment with no
425434
// outputs, bump this maximum such that, after the splice, the holder's balance covers at
426-
// least `dust_limit_satoshis` and, if they are the funder, `current_spiked_tx_fee_sat`.
427-
// We don't include an additional non-dust inbound HTLC in the `current_spiked_tx_fee_sat`,
435+
// least `dust_limit_satoshis` and, if they are the funder, `current_tx_fee_sat`.
436+
// We don't include an additional non-dust inbound HTLC in the `current_tx_fee_sat`,
428437
// because we don't mind if the holder dips below their dust limit to cover the fee for that
429438
// inbound non-dust HTLC.
430439
if !has_output(
431440
is_outbound_from_holder,
432441
local_balance_before_fee_msat.saturating_sub(next_splice_out_maximum_sat * 1000),
433442
remote_balance_before_fee_msat,
434-
spiked_feerate,
435-
spiked_feerate_nondust_htlc_count,
443+
feerate_per_kw,
444+
nondust_htlc_count,
436445
channel_constraints.holder_dust_limit_satoshis,
437446
channel_type,
438447
) {
439448
let dust_limit_satoshis = channel_constraints.holder_dust_limit_satoshis;
440-
let current_spiked_tx_fee_sat = commit_tx_fee_sat(spiked_feerate, 0, channel_type);
449+
let current_tx_fee_sat = commit_tx_fee_sat(feerate_per_kw, 0, channel_type);
441450
let min_balance_sat = if is_outbound_from_holder {
442-
dust_limit_satoshis.saturating_add(current_spiked_tx_fee_sat)
451+
dust_limit_satoshis.saturating_add(current_tx_fee_sat)
443452
} else {
444453
dust_limit_satoshis
445454
};
@@ -476,13 +485,12 @@ fn get_available_balances(
476485
if channel_type.supports_anchor_zero_fee_commitments() { 0 } else { 1 };
477486

478487
// Note that the feerate is 0 in zero-fee commitment channels, so this statement is a noop
479-
let spiked_feerate = feerate_per_kw.saturating_mul(
480-
if is_outbound_from_holder && !channel_type.supports_anchors_zero_fee_htlc_tx() {
488+
let spiked_feerate =
489+
feerate_per_kw.saturating_mul(if !channel_type.supports_anchors_zero_fee_htlc_tx() {
481490
crate::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32
482491
} else {
483492
1
484-
},
485-
);
493+
});
486494

487495
let local_nondust_htlc_count = pending_htlcs
488496
.iter()
@@ -495,17 +503,6 @@ fn get_available_balances(
495503
)
496504
})
497505
.count();
498-
let local_spiked_nondust_htlc_count = pending_htlcs
499-
.iter()
500-
.filter(|htlc| {
501-
!htlc.is_dust(
502-
true,
503-
spiked_feerate,
504-
channel_constraints.holder_dust_limit_satoshis,
505-
channel_type,
506-
)
507-
})
508-
.count();
509506

510507
// Note here we use the htlc count at the current feerate together with the spiked feerate;
511508
// this makes sure that the holder can afford any fee bump between 1x to 2x from the current
@@ -571,9 +568,9 @@ fn get_available_balances(
571568
channel_value_satoshis,
572569
local_balance_before_fee_msat,
573570
remote_balance_before_fee_msat,
574-
spiked_feerate,
575-
// The number of non-dust HTLCs on the local commitment at the spiked feerate
576-
local_spiked_nondust_htlc_count,
571+
feerate_per_kw,
572+
// The number of non-dust HTLCs on the local commitment at the current feerate
573+
local_nondust_htlc_count,
577574
// The post-splice minimum balance of the holder
578575
if is_outbound_from_holder { local_min_commit_tx_fee_sat } else { 0 },
579576
&channel_constraints,
@@ -704,28 +701,16 @@ fn get_available_balances(
704701
}
705702

706703
// Now adjust our min and max size HTLC to make sure both the local and the remote commitments still have
707-
// at least one output at the spiked feerate.
708-
709-
let remote_spiked_nondust_htlc_count = pending_htlcs
710-
.iter()
711-
.filter(|htlc| {
712-
!htlc.is_dust(
713-
false,
714-
spiked_feerate,
715-
channel_constraints.counterparty_dust_limit_satoshis,
716-
channel_type,
717-
)
718-
})
719-
.count();
704+
// at least one output at the current feerate.
720705

721706
let (next_outbound_htlc_minimum_msat, available_capacity_msat) =
722707
adjust_boundaries_if_max_dust_htlc_produces_no_output(
723708
true,
724709
is_outbound_from_holder,
725710
local_balance_before_fee_msat,
726711
remote_balance_before_fee_msat,
727-
spiked_feerate,
728-
local_spiked_nondust_htlc_count,
712+
feerate_per_kw,
713+
local_nondust_htlc_count,
729714
channel_constraints.holder_dust_limit_satoshis,
730715
channel_type,
731716
next_outbound_htlc_minimum_msat,
@@ -738,8 +723,8 @@ fn get_available_balances(
738723
is_outbound_from_holder,
739724
local_balance_before_fee_msat,
740725
remote_balance_before_fee_msat,
741-
spiked_feerate,
742-
remote_spiked_nondust_htlc_count,
726+
feerate_per_kw,
727+
remote_nondust_htlc_count,
743728
channel_constraints.counterparty_dust_limit_satoshis,
744729
channel_type,
745730
next_outbound_htlc_minimum_msat,
@@ -760,14 +745,13 @@ fn get_available_balances(
760745

761746
fn adjust_boundaries_if_max_dust_htlc_produces_no_output(
762747
local: bool, is_outbound_from_holder: bool, holder_balance_before_fee_msat: u64,
763-
counterparty_balance_before_fee_msat: u64, spiked_feerate: u32,
764-
spiked_feerate_nondust_htlc_count: usize, dust_limit_satoshis: u64,
765-
channel_type: &ChannelTypeFeatures, next_outbound_htlc_minimum_msat: u64,
766-
available_capacity_msat: u64,
748+
counterparty_balance_before_fee_msat: u64, feerate_per_kw: u32, nondust_htlc_count: usize,
749+
dust_limit_satoshis: u64, channel_type: &ChannelTypeFeatures,
750+
next_outbound_htlc_minimum_msat: u64, available_capacity_msat: u64,
767751
) -> (u64, u64) {
768752
// First, determine the biggest dust HTLC we could send
769753
let (htlc_success_tx_fee_sat, htlc_timeout_tx_fee_sat) =
770-
second_stage_tx_fees_sat(channel_type, spiked_feerate);
754+
second_stage_tx_fees_sat(channel_type, feerate_per_kw);
771755
let min_nondust_htlc_sat =
772756
dust_limit_satoshis + if local { htlc_timeout_tx_fee_sat } else { htlc_success_tx_fee_sat };
773757
let max_dust_htlc_msat = (min_nondust_htlc_sat.saturating_mul(1000)).saturating_sub(1);
@@ -778,8 +762,8 @@ fn adjust_boundaries_if_max_dust_htlc_produces_no_output(
778762
is_outbound_from_holder,
779763
holder_balance_before_fee_msat.saturating_sub(max_dust_htlc_msat),
780764
counterparty_balance_before_fee_msat,
781-
spiked_feerate,
782-
spiked_feerate_nondust_htlc_count,
765+
feerate_per_kw,
766+
nondust_htlc_count,
783767
dust_limit_satoshis,
784768
channel_type,
785769
) {
@@ -796,16 +780,15 @@ fn adjust_boundaries_if_max_dust_htlc_produces_no_output(
796780
// Note that this will be a dust HTLC.
797781
} else {
798782
// Remember we've got no non-dust HTLCs on the commitment here
799-
let current_spiked_tx_fee_sat = commit_tx_fee_sat(spiked_feerate, 0, channel_type);
800-
let spike_buffer_tx_fee_sat = commit_tx_fee_sat(spiked_feerate, 1, channel_type);
783+
let current_tx_fee_sat = commit_tx_fee_sat(feerate_per_kw, 0, channel_type);
784+
let spike_buffer_tx_fee_sat = commit_tx_fee_sat(feerate_per_kw, 1, channel_type);
801785
// In case we are the funder, we must cover the greater of
802-
// 1) The dust_limit_satoshis plus the fee of the existing commitment at the spiked feerate.
786+
// 1) The dust_limit_satoshis plus the fee of the existing commitment at the current feerate.
803787
// 2) The fee of the commitment with an additional non-dust HTLC, aka the fee spike buffer HTLC.
804788
// In this case we don't mind the holder balance output dropping below the dust limit, as
805789
// this additional non-dust HTLC will create the single remaining output on the commitment.
806790
let min_balance_msat = if is_outbound_from_holder {
807-
cmp::max(dust_limit_satoshis + current_spiked_tx_fee_sat, spike_buffer_tx_fee_sat)
808-
* 1000
791+
cmp::max(dust_limit_satoshis + current_tx_fee_sat, spike_buffer_tx_fee_sat) * 1000
809792
// In case we are the fundee, we can send dust HTLCs as long as our own balance output
810793
// remains above the dust limit.
811794
} else {

0 commit comments

Comments
 (0)