Skip to content

Commit 90da6cc

Browse files
committed
Only account for fee spike buffer multiple on non-anchor channels
Anchor outputs channels are no longer susceptible to fee spikes as they now mostly target the dynamic minimum mempool fee and can contribute the remainder of fees when closing.
1 parent 610c5f5 commit 90da6cc

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12181218
0x6d => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 1, &mut payment_id, &mut payment_idx); },
12191219

12201220
0x80 => {
1221-
let max_feerate = last_htlc_clear_fee_a * FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1221+
let mut max_feerate = last_htlc_clear_fee_a;
1222+
if !anchors {
1223+
max_feerate *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1224+
}
12221225
if fee_est_a.ret_val.fetch_add(250, atomic::Ordering::AcqRel) + 250 > max_feerate {
12231226
fee_est_a.ret_val.store(max_feerate, atomic::Ordering::Release);
12241227
}
@@ -1227,7 +1230,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12271230
0x81 => { fee_est_a.ret_val.store(253, atomic::Ordering::Release); nodes[0].maybe_update_chan_fees(); },
12281231

12291232
0x84 => {
1230-
let max_feerate = last_htlc_clear_fee_b * FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1233+
let mut max_feerate = last_htlc_clear_fee_b;
1234+
if !anchors {
1235+
max_feerate *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1236+
}
12311237
if fee_est_b.ret_val.fetch_add(250, atomic::Ordering::AcqRel) + 250 > max_feerate {
12321238
fee_est_b.ret_val.store(max_feerate, atomic::Ordering::Release);
12331239
}
@@ -1236,7 +1242,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12361242
0x85 => { fee_est_b.ret_val.store(253, atomic::Ordering::Release); nodes[1].maybe_update_chan_fees(); },
12371243

12381244
0x88 => {
1239-
let max_feerate = last_htlc_clear_fee_c * FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1245+
let mut max_feerate = last_htlc_clear_fee_c;
1246+
if !anchors {
1247+
max_feerate *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1248+
}
12401249
if fee_est_c.ret_val.fetch_add(250, atomic::Ordering::AcqRel) + 250 > max_feerate {
12411250
fee_est_c.ret_val.store(max_feerate, atomic::Ordering::Release);
12421251
}

lightning/src/ln/channel.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,9 +1692,13 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
16921692
}
16931693

16941694
let htlc_above_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000, HTLCInitiator::LocalOffered);
1695-
let max_reserved_commit_tx_fee_msat = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(()));
1695+
let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(()));
16961696
let htlc_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000 - 1, HTLCInitiator::LocalOffered);
1697-
let min_reserved_commit_tx_fee_msat = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * context.next_local_commit_tx_fee_msat(htlc_dust, Some(()));
1697+
let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_dust, Some(()));
1698+
if !context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
1699+
max_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
1700+
min_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
1701+
}
16981702

16991703
// We will first subtract the fee as if we were above-dust. Then, if the resulting
17001704
// value ends up being below dust, we have this fee available again. In that case,
@@ -2859,16 +2863,15 @@ impl<SP: Deref> Channel<SP> where
28592863
}
28602864

28612865
if !self.context.is_outbound() {
2862-
// `2 *` and `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
2863-
// the spec because in the spec, the fee spike buffer requirement doesn't exist on the
2864-
// receiver's side, only on the sender's.
2865-
// Note that when we eventually remove support for fee updates and switch to anchor output
2866-
// fees, we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep
2867-
// the extra htlc when calculating the next remote commitment transaction fee as we should
2868-
// still be able to afford adding this HTLC plus one more future HTLC, regardless of being
2869-
// sensitive to fee spikes.
2866+
// `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
2867+
// the spec because the fee spike buffer requirement doesn't exist on the receiver's
2868+
// side, only on the sender's. Note that with anchor outputs we are no longer as
2869+
// sensitive to fee spikes, so we need to account for them.
28702870
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
2871-
let remote_fee_cost_incl_stuck_buffer_msat = 2 * self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
2871+
let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
2872+
if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
2873+
remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
2874+
}
28722875
if pending_remote_value_msat - msg.amount_msat - self.context.holder_selected_channel_reserve_satoshis * 1000 - anchor_outputs_value_msat < remote_fee_cost_incl_stuck_buffer_msat {
28732876
// Note that if the pending_forward_status is not updated here, then it's because we're already failing
28742877
// the HTLC, i.e. its status is already set to failing.

0 commit comments

Comments
 (0)