Skip to content

Commit 067bfa0

Browse files
committed
f: Tweak next commit tx fee msat parameters
1 parent e538b7a commit 067bfa0

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

lightning/src/ln/channel.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,7 @@ pub enum AnnouncementSigsState {
10581058
}
10591059

10601060
/// An enum indicating whether the local or remote side offered a given HTLC.
1061+
#[allow(dead_code)]
10611062
enum HTLCInitiator {
10621063
LocalOffered,
10631064
RemoteOffered,
@@ -4145,7 +4146,7 @@ where
41454146
{
41464147
let remote_commit_tx_fee_msat = if funding.is_outbound() { 0 } else {
41474148
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
4148-
self.next_remote_commit_tx_fee_msat(funding, Some(htlc_candidate), None) // Don't include the extra fee spike buffer HTLC in calculations
4149+
self.next_remote_commit_tx_fee_msat(funding, Some(htlc_candidate), 0) // Don't include the extra fee spike buffer HTLC in calculations
41494150
};
41504151
if remote_balance_before_fee_msat.saturating_sub(msg.amount_msat) < remote_commit_tx_fee_msat {
41514152
return Err(ChannelError::close("Remote HTLC add would not leave enough to pay for fees".to_owned()));
@@ -4158,7 +4159,7 @@ where
41584159
if funding.is_outbound() {
41594160
// Check that they won't violate our local required channel reserve by adding this HTLC.
41604161
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
4161-
let local_commit_tx_fee_msat = self.next_local_commit_tx_fee_msat(funding, htlc_candidate, None);
4162+
let local_commit_tx_fee_msat = self.next_local_commit_tx_fee_msat(funding, Some(htlc_candidate), 0);
41624163
if local_balance_before_fee_msat < funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat {
41634164
return Err(ChannelError::close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned()));
41644165
}
@@ -4372,7 +4373,7 @@ where
43724373
//
43734374
// A `None` `HTLCCandidate` is used as in this case because we're already accounting for
43744375
// the incoming HTLC as it has been fully committed by both sides.
4375-
let mut remote_fee_cost_incl_stuck_buffer_msat = self.next_remote_commit_tx_fee_msat(funding, None, Some(()));
4376+
let mut remote_fee_cost_incl_stuck_buffer_msat = self.next_remote_commit_tx_fee_msat(funding, None, 1);
43764377
if !funding.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
43774378
remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
43784379
}
@@ -4865,10 +4866,8 @@ where
48654866
// dependency.
48664867
// This complicates the computation around dust-values, up to the one-htlc-value.
48674868

4868-
let htlc_above_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000, HTLCInitiator::LocalOffered);
4869-
let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(funding, htlc_above_dust, Some(()));
4870-
let htlc_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000 - 1, HTLCInitiator::LocalOffered);
4871-
let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(funding, htlc_dust, Some(()));
4869+
let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(funding, None, 2);
4870+
let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(funding, None, 1);
48724871
if !funding.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
48734872
max_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
48744873
min_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
@@ -4891,8 +4890,7 @@ where
48914890
} else {
48924891
// If the channel is inbound (i.e. counterparty pays the fee), we need to make sure
48934892
// sending a new HTLC won't reduce their balance below our reserve threshold.
4894-
let htlc_above_dust = HTLCCandidate::new(real_dust_limit_success_sat * 1000, HTLCInitiator::LocalOffered);
4895-
let max_reserved_commit_tx_fee_msat = context.next_remote_commit_tx_fee_msat(funding, Some(htlc_above_dust), None);
4893+
let max_reserved_commit_tx_fee_msat = context.next_remote_commit_tx_fee_msat(funding, None, 1);
48964894

48974895
let holder_selected_chan_reserve_msat = funding.holder_selected_channel_reserve_satoshis * 1000;
48984896
if remote_balance_before_fee_msat < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat {
@@ -4975,18 +4973,22 @@ where
49754973
/// Dust HTLCs are excluded.
49764974
#[rustfmt::skip]
49774975
fn next_local_commit_tx_fee_msat(
4978-
&self, funding: &FundingScope, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>,
4976+
&self, funding: &FundingScope, htlc: Option<HTLCCandidate>, addl_nondust_htlc: usize,
49794977
) -> u64 {
4978+
debug_assert!(htlc.is_some() || addl_nondust_htlc != 0, "At least one of the options must be set");
4979+
49804980
let context = self;
49814981
assert!(funding.is_outbound());
49824982
let mut htlcs: Vec<HTLCAmountDirection> = Vec::new();
49834983

4984-
match htlc.origin {
4985-
HTLCInitiator::LocalOffered => {
4986-
htlcs.push(HTLCAmountDirection { offered: true, amount_msat: htlc.amount_msat });
4987-
},
4988-
HTLCInitiator::RemoteOffered => {
4989-
htlcs.push(HTLCAmountDirection { offered: false, amount_msat: htlc.amount_msat });
4984+
if let Some(htlc) = &htlc {
4985+
match htlc.origin {
4986+
HTLCInitiator::LocalOffered => {
4987+
htlcs.push(HTLCAmountDirection { offered: true, amount_msat: htlc.amount_msat });
4988+
},
4989+
HTLCInitiator::RemoteOffered => {
4990+
htlcs.push(HTLCAmountDirection { offered: false, amount_msat: htlc.amount_msat });
4991+
}
49904992
}
49914993
}
49924994

@@ -5017,13 +5019,13 @@ where
50175019
}
50185020

50195021
#[cfg(any(test, fuzzing))]
5020-
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.holder_dust_limit_satoshis, context.feerate_per_kw, &htlcs, fee_spike_buffer_htlc.map(|_| 1).unwrap_or(0), funding.get_channel_type()) * 1000;
5022+
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.holder_dust_limit_satoshis, context.feerate_per_kw, &htlcs, addl_nondust_htlc, funding.get_channel_type()) * 1000;
50215023
#[cfg(not(any(test, fuzzing)))]
5022-
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.holder_dust_limit_satoshis, context.feerate_per_kw, &htlcs, fee_spike_buffer_htlc.map(|_| 1).unwrap_or(0), funding.get_channel_type()) * 1000;
5024+
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.holder_dust_limit_satoshis, context.feerate_per_kw, &htlcs, addl_nondust_htlc, funding.get_channel_type()) * 1000;
50235025
#[cfg(any(test, fuzzing))]
5024-
{
5026+
if let Some(htlc) = htlc {
50255027
let mut fee = commit_tx_fee_msat;
5026-
if fee_spike_buffer_htlc.is_some() {
5028+
if addl_nondust_htlc != 0 {
50275029
fee = SpecTxBuilder {}.commit_tx_fee_sat(context.holder_dust_limit_satoshis, context.feerate_per_kw, &htlcs, 0, funding.get_channel_type()) * 1000;
50285030
}
50295031
let total_pending_htlcs = context.pending_inbound_htlcs.len() + context.pending_outbound_htlcs.len()
@@ -5058,9 +5060,9 @@ where
50585060
/// Dust HTLCs are excluded.
50595061
#[rustfmt::skip]
50605062
fn next_remote_commit_tx_fee_msat(
5061-
&self, funding: &FundingScope, htlc: Option<HTLCCandidate>, fee_spike_buffer_htlc: Option<()>,
5063+
&self, funding: &FundingScope, htlc: Option<HTLCCandidate>, addl_nondust_htlc: usize,
50625064
) -> u64 {
5063-
debug_assert!(htlc.is_some() || fee_spike_buffer_htlc.is_some(), "At least one of the options must be set");
5065+
debug_assert!(htlc.is_some() || addl_nondust_htlc != 0, "At least one of the options must be set");
50645066

50655067
let context = self;
50665068
assert!(!funding.is_outbound());
@@ -5097,13 +5099,13 @@ where
50975099
}
50985100

50995101
#[cfg(any(test, fuzzing))]
5100-
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.counterparty_dust_limit_satoshis, context.feerate_per_kw, &htlcs, fee_spike_buffer_htlc.map(|_| 1).unwrap_or(0), funding.get_channel_type()) * 1000;
5102+
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.counterparty_dust_limit_satoshis, context.feerate_per_kw, &htlcs, addl_nondust_htlc, funding.get_channel_type()) * 1000;
51015103
#[cfg(not(any(test, fuzzing)))]
5102-
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.counterparty_dust_limit_satoshis, context.feerate_per_kw, &htlcs, fee_spike_buffer_htlc.map(|_| 1).unwrap_or(0), funding.get_channel_type()) * 1000;
5104+
let commit_tx_fee_msat = SpecTxBuilder {}.commit_tx_fee_sat(context.counterparty_dust_limit_satoshis, context.feerate_per_kw, &htlcs, addl_nondust_htlc, funding.get_channel_type()) * 1000;
51035105
#[cfg(any(test, fuzzing))]
51045106
if let Some(htlc) = &htlc {
51055107
let mut fee = commit_tx_fee_msat;
5106-
if fee_spike_buffer_htlc.is_some() {
5108+
if addl_nondust_htlc != 0 {
51075109
fee = SpecTxBuilder {}.commit_tx_fee_sat(context.counterparty_dust_limit_satoshis, context.feerate_per_kw, &htlcs, 0, funding.get_channel_type()) * 1000;
51085110
}
51095111
let total_pending_htlcs = context.pending_inbound_htlcs.len() + context.pending_outbound_htlcs.len();
@@ -13450,7 +13452,7 @@ mod tests {
1345013452
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
1345113453
// the dust limit check.
1345213454
let htlc_candidate = HTLCCandidate::new(htlc_amount_msat, HTLCInitiator::LocalOffered);
13453-
let local_commit_tx_fee = node_a_chan.context.next_local_commit_tx_fee_msat(&node_a_chan.funding, htlc_candidate, None);
13455+
let local_commit_tx_fee = node_a_chan.context.next_local_commit_tx_fee_msat(&node_a_chan.funding, Some(htlc_candidate), 0);
1345413456
let local_commit_fee_0_htlcs = commit_tx_fee_sat(node_a_chan.context.feerate_per_kw, 0, node_a_chan.funding.get_channel_type()) * 1000;
1345513457
assert_eq!(local_commit_tx_fee, local_commit_fee_0_htlcs);
1345613458

@@ -13459,7 +13461,7 @@ mod tests {
1345913461
node_a_chan.funding.channel_transaction_parameters.is_outbound_from_holder = false;
1346013462
let remote_commit_fee_3_htlcs = commit_tx_fee_sat(node_a_chan.context.feerate_per_kw, 3, node_a_chan.funding.get_channel_type()) * 1000;
1346113463
let htlc_candidate = HTLCCandidate::new(htlc_amount_msat, HTLCInitiator::LocalOffered);
13462-
let remote_commit_tx_fee = node_a_chan.context.next_remote_commit_tx_fee_msat(&node_a_chan.funding, Some(htlc_candidate), None);
13464+
let remote_commit_tx_fee = node_a_chan.context.next_remote_commit_tx_fee_msat(&node_a_chan.funding, Some(htlc_candidate), 0);
1346313465
assert_eq!(remote_commit_tx_fee, remote_commit_fee_3_htlcs);
1346413466
}
1346513467

@@ -13489,27 +13491,27 @@ mod tests {
1348913491
// counted as dust when it shouldn't be.
1349013492
let htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.funding.get_channel_type()) / 1000) + chan.context.holder_dust_limit_satoshis + 1) * 1000;
1349113493
let htlc_candidate = HTLCCandidate::new(htlc_amt_above_timeout, HTLCInitiator::LocalOffered);
13492-
let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(&chan.funding, htlc_candidate, None);
13494+
let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), 0);
1349313495
assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
1349413496

1349513497
// If swapped: this HTLC would be counted as non-dust when it shouldn't be.
1349613498
let dust_htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.funding.get_channel_type()) / 1000) + chan.context.holder_dust_limit_satoshis - 1) * 1000;
1349713499
let htlc_candidate = HTLCCandidate::new(dust_htlc_amt_below_success, HTLCInitiator::RemoteOffered);
13498-
let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(&chan.funding, htlc_candidate, None);
13500+
let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), 0);
1349913501
assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
1350013502

1350113503
chan.funding.channel_transaction_parameters.is_outbound_from_holder = false;
1350213504

1350313505
// If swapped: this HTLC would be counted as non-dust when it shouldn't be.
1350413506
let dust_htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.funding.get_channel_type()) / 1000) + chan.context.counterparty_dust_limit_satoshis + 1) * 1000;
1350513507
let htlc_candidate = HTLCCandidate::new(dust_htlc_amt_above_timeout, HTLCInitiator::LocalOffered);
13506-
let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), None);
13508+
let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), 0);
1350713509
assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
1350813510

1350913511
// If swapped: this HTLC would be counted as dust when it shouldn't be.
1351013512
let htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.funding.get_channel_type()) / 1000) + chan.context.counterparty_dust_limit_satoshis - 1) * 1000;
1351113513
let htlc_candidate = HTLCCandidate::new(htlc_amt_below_success, HTLCInitiator::RemoteOffered);
13512-
let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), None);
13514+
let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), 0);
1351313515
assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
1351413516
}
1351513517

0 commit comments

Comments
 (0)