@@ -1579,6 +1579,15 @@ pub(super) struct FundingScope {
15791579 #[cfg(debug_assertions)]
15801580 /// Max to_local and to_remote outputs in a remote-generated commitment transaction
15811581 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>>,
15821591}
15831592
15841593impl FundingScope {
@@ -1823,15 +1832,6 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
18231832 /// This can be used to rebroadcast the channel_announcement message later.
18241833 announcement_sigs: Option<(Signature, Signature)>,
18251834
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-
18351835 /// lnd has a long-standing bug where, upon reconnection, if the channel is not yet confirmed
18361836 /// they will not send a channel_reestablish until the channel locks in. Then, they will send a
18371837 /// 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 {
24702470 holder_max_commitment_tx_output: Mutex::new((value_to_self_msat, (channel_value_satoshis * 1000 - msg_push_msat).saturating_sub(value_to_self_msat))),
24712471 #[cfg(debug_assertions)]
24722472 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),
24732478 };
24742479 let channel_context = ChannelContext {
24752480 user_id,
@@ -2578,11 +2583,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
25782583
25792584 announcement_sigs: None,
25802585
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-
25862586 workaround_lnd_bug_4006: None,
25872587 sent_message_awaiting_response: None,
25882588
@@ -2705,6 +2705,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
27052705 holder_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
27062706 #[cfg(debug_assertions)]
27072707 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),
27082713 };
27092714 let channel_context = Self {
27102715 user_id,
@@ -2810,11 +2815,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
28102815
28112816 announcement_sigs: None,
28122817
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-
28182818 workaround_lnd_bug_4006: None,
28192819 sent_message_awaiting_response: None,
28202820
@@ -3868,9 +3868,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38683868 }
38693869
38703870 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(()));
38723872 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(()));
38743874 if !context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
38753875 max_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
38763876 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 {
38993899 }
39003900
39013901 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);
39033903
39043904 let holder_selected_chan_reserve_msat = funding.holder_selected_channel_reserve_satoshis * 1000;
39053905 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 {
39963996 /// second allows for creating a buffer to ensure a further HTLC can always be accepted/added.
39973997 ///
39983998 /// 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 {
40004002 let context = &self;
40014003 assert!(context.is_outbound());
40024004
@@ -4085,7 +4087,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
40854087 },
40864088 feerate: context.feerate_per_kw,
40874089 };
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);
40894091 }
40904092 res
40914093 }
@@ -4100,7 +4102,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
41004102 /// second allows for creating a buffer to ensure a further HTLC can always be accepted/added.
41014103 ///
41024104 /// 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 {
41044108 debug_assert!(htlc.is_some() || fee_spike_buffer_htlc.is_some(), "At least one of the options must be set");
41054109
41064110 let context = &self;
@@ -4179,7 +4183,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
41794183 },
41804184 feerate: context.feerate_per_kw,
41814185 };
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);
41834187 }
41844188 res
41854189 }
@@ -5199,7 +5203,7 @@ impl<SP: Deref> FundedChannel<SP> where
51995203 {
52005204 let remote_commit_tx_fee_msat = if self.context.is_outbound() { 0 } else {
52015205 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
52035207 };
52045208 let anchor_outputs_value_msat = if !self.context.is_outbound() && self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
52055209 ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000
@@ -5222,7 +5226,7 @@ impl<SP: Deref> FundedChannel<SP> where
52225226 if self.context.is_outbound() {
52235227 // Check that they won't violate our local required channel reserve by adding this HTLC.
52245228 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);
52265230 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 {
52275231 return Err(ChannelError::close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned()));
52285232 }
@@ -5400,8 +5404,8 @@ impl<SP: Deref> FundedChannel<SP> where
54005404 #[cfg(any(test, fuzzing))]
54015405 {
54025406 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;
54055409 if let Some(info) = projected_commit_tx_info {
54065410 let total_pending_htlcs = self.context.pending_inbound_htlcs.len() + self.context.pending_outbound_htlcs.len()
54075411 + self.context.holding_cell_htlc_updates.len();
@@ -5770,8 +5774,8 @@ impl<SP: Deref> FundedChannel<SP> where
57705774
57715775 #[cfg(any(test, fuzzing))]
57725776 {
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;
57755779 }
57765780
57775781 match &self.context.holder_signer {
@@ -7411,7 +7415,7 @@ impl<SP: Deref> FundedChannel<SP> where
74117415 //
74127416 // A `None` `HTLCCandidate` is used as in this case because we're already accounting for
74137417 // 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(()));
74157419 if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
74167420 remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
74177421 }
@@ -8353,8 +8357,8 @@ impl<SP: Deref> FundedChannel<SP> where
83538357 #[cfg(any(test, fuzzing))]
83548358 {
83558359 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;
83588362 if let Some(info) = projected_commit_tx_info {
83598363 let total_pending_htlcs = self.context.pending_inbound_htlcs.len() + self.context.pending_outbound_htlcs.len();
83608364 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
1037510379 holder_max_commitment_tx_output: Mutex::new((0, 0)),
1037610380 #[cfg(debug_assertions)]
1037710381 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),
1037810387 },
1037910388 context: ChannelContext {
1038010389 user_id,
@@ -10470,11 +10479,6 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
1047010479
1047110480 announcement_sigs,
1047210481
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-
1047810482 workaround_lnd_bug_4006: None,
1047910483 sent_message_awaiting_response: None,
1048010484
@@ -10744,7 +10748,7 @@ mod tests {
1074410748 // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
1074510749 // the dust limit check.
1074610750 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);
1074810752 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;
1074910753 assert_eq!(local_commit_tx_fee, local_commit_fee_0_htlcs);
1075010754
@@ -10753,7 +10757,7 @@ mod tests {
1075310757 node_a_chan.context.channel_transaction_parameters.is_outbound_from_holder = false;
1075410758 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;
1075510759 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);
1075710761 assert_eq!(remote_commit_tx_fee, remote_commit_fee_3_htlcs);
1075810762 }
1075910763
@@ -10781,27 +10785,27 @@ mod tests {
1078110785 // counted as dust when it shouldn't be.
1078210786 let htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.context.get_channel_type()) / 1000) + chan.context.holder_dust_limit_satoshis + 1) * 1000;
1078310787 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);
1078510789 assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
1078610790
1078710791 // If swapped: this HTLC would be counted as non-dust when it shouldn't be.
1078810792 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;
1078910793 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);
1079110795 assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
1079210796
1079310797 chan.context.channel_transaction_parameters.is_outbound_from_holder = false;
1079410798
1079510799 // If swapped: this HTLC would be counted as non-dust when it shouldn't be.
1079610800 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;
1079710801 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);
1079910803 assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
1080010804
1080110805 // If swapped: this HTLC would be counted as dust when it shouldn't be.
1080210806 let htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.context.get_channel_type()) / 1000) + chan.context.counterparty_dust_limit_satoshis - 1) * 1000;
1080310807 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);
1080510809 assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
1080610810 }
1080710811
0 commit comments