Skip to content

Commit 568f169

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 45aa90e commit 568f169

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
@@ -1222,7 +1222,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12221222
0x6d => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 1, &mut payment_id, &mut payment_idx); },
12231223

12241224
0x80 => {
1225-
let max_feerate = last_htlc_clear_fee_a * FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1225+
let mut max_feerate = last_htlc_clear_fee_a;
1226+
if !anchors {
1227+
max_feerate *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1228+
}
12261229
if fee_est_a.ret_val.fetch_add(250, atomic::Ordering::AcqRel) + 250 > max_feerate {
12271230
fee_est_a.ret_val.store(max_feerate, atomic::Ordering::Release);
12281231
}
@@ -1231,7 +1234,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12311234
0x81 => { fee_est_a.ret_val.store(253, atomic::Ordering::Release); nodes[0].maybe_update_chan_fees(); },
12321235

12331236
0x84 => {
1234-
let max_feerate = last_htlc_clear_fee_b * FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1237+
let mut max_feerate = last_htlc_clear_fee_b;
1238+
if !anchors {
1239+
max_feerate *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1240+
}
12351241
if fee_est_b.ret_val.fetch_add(250, atomic::Ordering::AcqRel) + 250 > max_feerate {
12361242
fee_est_b.ret_val.store(max_feerate, atomic::Ordering::Release);
12371243
}
@@ -1240,7 +1246,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12401246
0x85 => { fee_est_b.ret_val.store(253, atomic::Ordering::Release); nodes[1].maybe_update_chan_fees(); },
12411247

12421248
0x88 => {
1243-
let max_feerate = last_htlc_clear_fee_c * FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1249+
let mut max_feerate = last_htlc_clear_fee_c;
1250+
if !anchors {
1251+
max_feerate *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32;
1252+
}
12441253
if fee_est_c.ret_val.fetch_add(250, atomic::Ordering::AcqRel) + 250 > max_feerate {
12451254
fee_est_c.ret_val.store(max_feerate, atomic::Ordering::Release);
12461255
}

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,
@@ -2864,16 +2868,15 @@ impl<SP: Deref> Channel<SP> where
28642868
0
28652869
};
28662870
if !self.context.is_outbound() {
2867-
// `2 *` and `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
2868-
// the spec because in the spec, the fee spike buffer requirement doesn't exist on the
2869-
// receiver's side, only on the sender's.
2870-
// Note that when we eventually remove support for fee updates and switch to anchor output
2871-
// fees, we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep
2872-
// the extra htlc when calculating the next remote commitment transaction fee as we should
2873-
// still be able to afford adding this HTLC plus one more future HTLC, regardless of being
2874-
// sensitive to fee spikes.
2871+
// `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
2872+
// the spec because the fee spike buffer requirement doesn't exist on the receiver's
2873+
// side, only on the sender's. Note that with anchor outputs we are no longer as
2874+
// sensitive to fee spikes, so we need to account for them.
28752875
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
2876-
let remote_fee_cost_incl_stuck_buffer_msat = 2 * self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
2876+
let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
2877+
if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
2878+
remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
2879+
}
28772880
if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(self.context.holder_selected_channel_reserve_satoshis * 1000).saturating_sub(anchor_outputs_value_msat) < remote_fee_cost_incl_stuck_buffer_msat {
28782881
// Note that if the pending_forward_status is not updated here, then it's because we're already failing
28792882
// the HTLC, i.e. its status is already set to failing.

0 commit comments

Comments
 (0)