@@ -1579,6 +1579,15 @@ pub(super) struct FundingScope {
1579
1579
#[cfg(debug_assertions)]
1580
1580
/// Max to_local and to_remote outputs in a remote-generated commitment transaction
1581
1581
counterparty_max_commitment_tx_output: Mutex<(u64, u64)>,
1582
+
1583
+ // We save these values so we can make sure `next_local_commit_tx_fee_msat` and
1584
+ // `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
1585
+ // be, by comparing the cached values to the fee of the transaction generated by
1586
+ // `build_commitment_transaction`.
1587
+ #[cfg(any(test, fuzzing))]
1588
+ next_local_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
1589
+ #[cfg(any(test, fuzzing))]
1590
+ next_remote_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
1582
1591
}
1583
1592
1584
1593
impl FundingScope {
@@ -1823,15 +1832,6 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
1823
1832
/// This can be used to rebroadcast the channel_announcement message later.
1824
1833
announcement_sigs: Option<(Signature, Signature)>,
1825
1834
1826
- // We save these values so we can make sure `next_local_commit_tx_fee_msat` and
1827
- // `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
1828
- // be, by comparing the cached values to the fee of the tranaction generated by
1829
- // `build_commitment_transaction`.
1830
- #[cfg(any(test, fuzzing))]
1831
- next_local_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
1832
- #[cfg(any(test, fuzzing))]
1833
- next_remote_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
1834
-
1835
1835
/// lnd has a long-standing bug where, upon reconnection, if the channel is not yet confirmed
1836
1836
/// they will not send a channel_reestablish until the channel locks in. Then, they will send a
1837
1837
/// channel_ready *before* sending the channel_reestablish (which is clearly a violation of
@@ -2470,6 +2470,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2470
2470
holder_max_commitment_tx_output: Mutex::new((value_to_self_msat, (channel_value_satoshis * 1000 - msg_push_msat).saturating_sub(value_to_self_msat))),
2471
2471
#[cfg(debug_assertions)]
2472
2472
counterparty_max_commitment_tx_output: Mutex::new((value_to_self_msat, (channel_value_satoshis * 1000 - msg_push_msat).saturating_sub(value_to_self_msat))),
2473
+
2474
+ #[cfg(any(test, fuzzing))]
2475
+ next_local_commitment_tx_fee_info_cached: Mutex::new(None),
2476
+ #[cfg(any(test, fuzzing))]
2477
+ next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
2473
2478
};
2474
2479
let channel_context = ChannelContext {
2475
2480
user_id,
@@ -2578,11 +2583,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2578
2583
2579
2584
announcement_sigs: None,
2580
2585
2581
- #[cfg(any(test, fuzzing))]
2582
- next_local_commitment_tx_fee_info_cached: Mutex::new(None),
2583
- #[cfg(any(test, fuzzing))]
2584
- next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
2585
-
2586
2586
workaround_lnd_bug_4006: None,
2587
2587
sent_message_awaiting_response: None,
2588
2588
@@ -2705,6 +2705,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2705
2705
holder_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
2706
2706
#[cfg(debug_assertions)]
2707
2707
counterparty_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
2708
+
2709
+ #[cfg(any(test, fuzzing))]
2710
+ next_local_commitment_tx_fee_info_cached: Mutex::new(None),
2711
+ #[cfg(any(test, fuzzing))]
2712
+ next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
2708
2713
};
2709
2714
let channel_context = Self {
2710
2715
user_id,
@@ -2810,11 +2815,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2810
2815
2811
2816
announcement_sigs: None,
2812
2817
2813
- #[cfg(any(test, fuzzing))]
2814
- next_local_commitment_tx_fee_info_cached: Mutex::new(None),
2815
- #[cfg(any(test, fuzzing))]
2816
- next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
2817
-
2818
2818
workaround_lnd_bug_4006: None,
2819
2819
sent_message_awaiting_response: None,
2820
2820
@@ -3868,9 +3868,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3868
3868
}
3869
3869
3870
3870
let htlc_above_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000, HTLCInitiator::LocalOffered);
3871
- let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(()));
3871
+ let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(&funding, htlc_above_dust, Some(()));
3872
3872
let htlc_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000 - 1, HTLCInitiator::LocalOffered);
3873
- let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_dust, Some(()));
3873
+ let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(&funding, htlc_dust, Some(()));
3874
3874
if !context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
3875
3875
max_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
3876
3876
min_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
@@ -3899,7 +3899,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3899
3899
}
3900
3900
3901
3901
let htlc_above_dust = HTLCCandidate::new(real_dust_limit_success_sat * 1000, HTLCInitiator::LocalOffered);
3902
- let max_reserved_commit_tx_fee_msat = context.next_remote_commit_tx_fee_msat(Some(htlc_above_dust), None);
3902
+ let max_reserved_commit_tx_fee_msat = context.next_remote_commit_tx_fee_msat(&funding, Some(htlc_above_dust), None);
3903
3903
3904
3904
let holder_selected_chan_reserve_msat = funding.holder_selected_channel_reserve_satoshis * 1000;
3905
3905
let remote_balance_msat = (funding.channel_value_satoshis * 1000 - funding.value_to_self_msat)
@@ -3996,7 +3996,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3996
3996
/// second allows for creating a buffer to ensure a further HTLC can always be accepted/added.
3997
3997
///
3998
3998
/// Dust HTLCs are excluded.
3999
- fn next_local_commit_tx_fee_msat(&self, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>) -> u64 {
3999
+ fn next_local_commit_tx_fee_msat(
4000
+ &self, _funding: &FundingScope, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>,
4001
+ ) -> u64 {
4000
4002
let context = &self;
4001
4003
assert!(context.is_outbound());
4002
4004
@@ -4085,7 +4087,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4085
4087
},
4086
4088
feerate: context.feerate_per_kw,
4087
4089
};
4088
- *context .next_local_commitment_tx_fee_info_cached.lock().unwrap() = Some(commitment_tx_info);
4090
+ *_funding .next_local_commitment_tx_fee_info_cached.lock().unwrap() = Some(commitment_tx_info);
4089
4091
}
4090
4092
res
4091
4093
}
@@ -4100,7 +4102,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4100
4102
/// second allows for creating a buffer to ensure a further HTLC can always be accepted/added.
4101
4103
///
4102
4104
/// Dust HTLCs are excluded.
4103
- fn next_remote_commit_tx_fee_msat(&self, htlc: Option<HTLCCandidate>, fee_spike_buffer_htlc: Option<()>) -> u64 {
4105
+ fn next_remote_commit_tx_fee_msat(
4106
+ &self, _funding: &FundingScope, htlc: Option<HTLCCandidate>, fee_spike_buffer_htlc: Option<()>,
4107
+ ) -> u64 {
4104
4108
debug_assert!(htlc.is_some() || fee_spike_buffer_htlc.is_some(), "At least one of the options must be set");
4105
4109
4106
4110
let context = &self;
@@ -4179,7 +4183,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4179
4183
},
4180
4184
feerate: context.feerate_per_kw,
4181
4185
};
4182
- *context .next_remote_commitment_tx_fee_info_cached.lock().unwrap() = Some(commitment_tx_info);
4186
+ *_funding .next_remote_commitment_tx_fee_info_cached.lock().unwrap() = Some(commitment_tx_info);
4183
4187
}
4184
4188
res
4185
4189
}
@@ -5199,7 +5203,7 @@ impl<SP: Deref> FundedChannel<SP> where
5199
5203
{
5200
5204
let remote_commit_tx_fee_msat = if self.context.is_outbound() { 0 } else {
5201
5205
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
5202
- self.context.next_remote_commit_tx_fee_msat(Some(htlc_candidate), None) // Don't include the extra fee spike buffer HTLC in calculations
5206
+ self.context.next_remote_commit_tx_fee_msat(&self.funding, Some(htlc_candidate), None) // Don't include the extra fee spike buffer HTLC in calculations
5203
5207
};
5204
5208
let anchor_outputs_value_msat = if !self.context.is_outbound() && self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
5205
5209
ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000
@@ -5222,7 +5226,7 @@ impl<SP: Deref> FundedChannel<SP> where
5222
5226
if self.context.is_outbound() {
5223
5227
// Check that they won't violate our local required channel reserve by adding this HTLC.
5224
5228
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
5225
- let local_commit_tx_fee_msat = self.context.next_local_commit_tx_fee_msat(htlc_candidate, None);
5229
+ let local_commit_tx_fee_msat = self.context.next_local_commit_tx_fee_msat(&self.funding, htlc_candidate, None);
5226
5230
if self.funding.value_to_self_msat < self.funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat + anchor_outputs_value_msat {
5227
5231
return Err(ChannelError::close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned()));
5228
5232
}
@@ -5400,8 +5404,8 @@ impl<SP: Deref> FundedChannel<SP> where
5400
5404
#[cfg(any(test, fuzzing))]
5401
5405
{
5402
5406
if self.context.is_outbound() {
5403
- let projected_commit_tx_info = self.context .next_local_commitment_tx_fee_info_cached.lock().unwrap().take();
5404
- *self.context .next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
5407
+ let projected_commit_tx_info = self.funding .next_local_commitment_tx_fee_info_cached.lock().unwrap().take();
5408
+ *self.funding .next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
5405
5409
if let Some(info) = projected_commit_tx_info {
5406
5410
let total_pending_htlcs = self.context.pending_inbound_htlcs.len() + self.context.pending_outbound_htlcs.len()
5407
5411
+ self.context.holding_cell_htlc_updates.len();
@@ -5770,8 +5774,8 @@ impl<SP: Deref> FundedChannel<SP> where
5770
5774
5771
5775
#[cfg(any(test, fuzzing))]
5772
5776
{
5773
- *self.context .next_local_commitment_tx_fee_info_cached.lock().unwrap() = None;
5774
- *self.context .next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
5777
+ *self.funding .next_local_commitment_tx_fee_info_cached.lock().unwrap() = None;
5778
+ *self.funding .next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
5775
5779
}
5776
5780
5777
5781
match &self.context.holder_signer {
@@ -7411,7 +7415,7 @@ impl<SP: Deref> FundedChannel<SP> where
7411
7415
//
7412
7416
// A `None` `HTLCCandidate` is used as in this case because we're already accounting for
7413
7417
// the incoming HTLC as it has been fully committed by both sides.
7414
- let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(None, Some(()));
7418
+ let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(&self.funding, None, Some(()));
7415
7419
if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
7416
7420
remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
7417
7421
}
@@ -8353,8 +8357,8 @@ impl<SP: Deref> FundedChannel<SP> where
8353
8357
#[cfg(any(test, fuzzing))]
8354
8358
{
8355
8359
if !self.context.is_outbound() {
8356
- let projected_commit_tx_info = self.context .next_remote_commitment_tx_fee_info_cached.lock().unwrap().take();
8357
- *self.context .next_local_commitment_tx_fee_info_cached.lock().unwrap() = None;
8360
+ let projected_commit_tx_info = self.funding .next_remote_commitment_tx_fee_info_cached.lock().unwrap().take();
8361
+ *self.funding .next_local_commitment_tx_fee_info_cached.lock().unwrap() = None;
8358
8362
if let Some(info) = projected_commit_tx_info {
8359
8363
let total_pending_htlcs = self.context.pending_inbound_htlcs.len() + self.context.pending_outbound_htlcs.len();
8360
8364
if info.total_pending_htlcs == total_pending_htlcs
@@ -10375,6 +10379,11 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
10375
10379
holder_max_commitment_tx_output: Mutex::new((0, 0)),
10376
10380
#[cfg(debug_assertions)]
10377
10381
counterparty_max_commitment_tx_output: Mutex::new((0, 0)),
10382
+
10383
+ #[cfg(any(test, fuzzing))]
10384
+ next_local_commitment_tx_fee_info_cached: Mutex::new(None),
10385
+ #[cfg(any(test, fuzzing))]
10386
+ next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
10378
10387
},
10379
10388
context: ChannelContext {
10380
10389
user_id,
@@ -10470,11 +10479,6 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
10470
10479
10471
10480
announcement_sigs,
10472
10481
10473
- #[cfg(any(test, fuzzing))]
10474
- next_local_commitment_tx_fee_info_cached: Mutex::new(None),
10475
- #[cfg(any(test, fuzzing))]
10476
- next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
10477
-
10478
10482
workaround_lnd_bug_4006: None,
10479
10483
sent_message_awaiting_response: None,
10480
10484
@@ -10744,7 +10748,7 @@ mod tests {
10744
10748
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
10745
10749
// the dust limit check.
10746
10750
let htlc_candidate = HTLCCandidate::new(htlc_amount_msat, HTLCInitiator::LocalOffered);
10747
- let local_commit_tx_fee = node_a_chan.context.next_local_commit_tx_fee_msat(htlc_candidate, None);
10751
+ let local_commit_tx_fee = node_a_chan.context.next_local_commit_tx_fee_msat(&node_a_chan.funding, htlc_candidate, None);
10748
10752
let local_commit_fee_0_htlcs = commit_tx_fee_sat(node_a_chan.context.feerate_per_kw, 0, node_a_chan.context.get_channel_type()) * 1000;
10749
10753
assert_eq!(local_commit_tx_fee, local_commit_fee_0_htlcs);
10750
10754
@@ -10753,7 +10757,7 @@ mod tests {
10753
10757
node_a_chan.context.channel_transaction_parameters.is_outbound_from_holder = false;
10754
10758
let remote_commit_fee_3_htlcs = commit_tx_fee_sat(node_a_chan.context.feerate_per_kw, 3, node_a_chan.context.get_channel_type()) * 1000;
10755
10759
let htlc_candidate = HTLCCandidate::new(htlc_amount_msat, HTLCInitiator::LocalOffered);
10756
- let remote_commit_tx_fee = node_a_chan.context.next_remote_commit_tx_fee_msat(Some(htlc_candidate), None);
10760
+ let remote_commit_tx_fee = node_a_chan.context.next_remote_commit_tx_fee_msat(&node_a_chan.funding, Some(htlc_candidate), None);
10757
10761
assert_eq!(remote_commit_tx_fee, remote_commit_fee_3_htlcs);
10758
10762
}
10759
10763
@@ -10781,27 +10785,27 @@ mod tests {
10781
10785
// counted as dust when it shouldn't be.
10782
10786
let htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.context.get_channel_type()) / 1000) + chan.context.holder_dust_limit_satoshis + 1) * 1000;
10783
10787
let htlc_candidate = HTLCCandidate::new(htlc_amt_above_timeout, HTLCInitiator::LocalOffered);
10784
- let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(htlc_candidate, None);
10788
+ let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(&chan.funding, htlc_candidate, None);
10785
10789
assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
10786
10790
10787
10791
// If swapped: this HTLC would be counted as non-dust when it shouldn't be.
10788
10792
let dust_htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.context.get_channel_type()) / 1000) + chan.context.holder_dust_limit_satoshis - 1) * 1000;
10789
10793
let htlc_candidate = HTLCCandidate::new(dust_htlc_amt_below_success, HTLCInitiator::RemoteOffered);
10790
- let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(htlc_candidate, None);
10794
+ let commitment_tx_fee = chan.context.next_local_commit_tx_fee_msat(&chan.funding, htlc_candidate, None);
10791
10795
assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
10792
10796
10793
10797
chan.context.channel_transaction_parameters.is_outbound_from_holder = false;
10794
10798
10795
10799
// If swapped: this HTLC would be counted as non-dust when it shouldn't be.
10796
10800
let dust_htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.context.get_channel_type()) / 1000) + chan.context.counterparty_dust_limit_satoshis + 1) * 1000;
10797
10801
let htlc_candidate = HTLCCandidate::new(dust_htlc_amt_above_timeout, HTLCInitiator::LocalOffered);
10798
- let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(Some(htlc_candidate), None);
10802
+ let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), None);
10799
10803
assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
10800
10804
10801
10805
// If swapped: this HTLC would be counted as dust when it shouldn't be.
10802
10806
let htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.context.get_channel_type()) / 1000) + chan.context.counterparty_dust_limit_satoshis - 1) * 1000;
10803
10807
let htlc_candidate = HTLCCandidate::new(htlc_amt_below_success, HTLCInitiator::RemoteOffered);
10804
- let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(Some(htlc_candidate), None);
10808
+ let commitment_tx_fee = chan.context.next_remote_commit_tx_fee_msat(&chan.funding, Some(htlc_candidate), None);
10805
10809
assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
10806
10810
}
10807
10811
0 commit comments