@@ -164,17 +164,11 @@ pub(crate) struct ChannelConstraints {
164164
165165pub ( crate ) trait TxBuilder {
166166 fn get_available_balances (
167- & self ,
168- is_outbound_from_holder : bool ,
169- channel_value_satoshis : u64 ,
170- value_to_holder_msat : u64 ,
171- pending_htlcs : & [ HTLCAmountDirection ] ,
172- feerate_per_kw : u32 ,
173- dust_exposure_limiting_feerate : Option < u32 > ,
174- max_dust_htlc_exposure_msat : u64 ,
167+ & self , is_outbound_from_holder : bool , channel_value_satoshis : u64 ,
168+ value_to_holder_msat : u64 , pending_htlcs : & [ HTLCAmountDirection ] , feerate_per_kw : u32 ,
169+ dust_exposure_limiting_feerate : Option < u32 > , max_dust_htlc_exposure_msat : u64 ,
175170 holder_channel_constraints : ChannelConstraints ,
176- counterparty_channel_constraints : ChannelConstraints ,
177- channel_type : & ChannelTypeFeatures ,
171+ counterparty_channel_constraints : ChannelConstraints , channel_type : & ChannelTypeFeatures ,
178172 ) -> crate :: ln:: channel:: AvailableBalances ;
179173 fn get_next_commitment_stats (
180174 & self , local : bool , is_outbound_from_holder : bool , channel_value_satoshis : u64 ,
@@ -197,34 +191,65 @@ pub(crate) struct SpecTxBuilder {}
197191
198192impl TxBuilder for SpecTxBuilder {
199193 fn get_available_balances (
200- & self ,
201- is_outbound_from_holder : bool ,
202- channel_value_satoshis : u64 ,
203- value_to_holder_msat : u64 ,
204- pending_htlcs : & [ HTLCAmountDirection ] ,
205- feerate_per_kw : u32 ,
206- dust_exposure_limiting_feerate : Option < u32 > ,
207- max_dust_htlc_exposure_msat : u64 ,
194+ & self , is_outbound_from_holder : bool , channel_value_satoshis : u64 ,
195+ value_to_holder_msat : u64 , pending_htlcs : & [ HTLCAmountDirection ] , feerate_per_kw : u32 ,
196+ dust_exposure_limiting_feerate : Option < u32 > , max_dust_htlc_exposure_msat : u64 ,
208197 holder_channel_constraints : ChannelConstraints ,
209- counterparty_channel_constraints : ChannelConstraints ,
210- channel_type : & ChannelTypeFeatures ,
198+ counterparty_channel_constraints : ChannelConstraints , channel_type : & ChannelTypeFeatures ,
211199 ) -> crate :: ln:: channel:: AvailableBalances {
212- let fee_spike_buffer_htlc = if channel_type. supports_anchor_zero_fee_commitments ( ) {
213- 0
214- } else {
215- 1
216- } ;
200+ let fee_spike_buffer_htlc =
201+ if channel_type. supports_anchor_zero_fee_commitments ( ) { 0 } else { 1 } ;
217202
218- let local_stats_max_fee = SpecTxBuilder { } . get_next_commitment_stats ( true , is_outbound_from_holder, channel_value_satoshis, value_to_holder_msat, pending_htlcs, fee_spike_buffer_htlc + 1 , feerate_per_kw, dust_exposure_limiting_feerate, holder_channel_constraints. dust_limit_satoshis , channel_type) . unwrap ( ) ;
219- let local_stats_min_fee = SpecTxBuilder { } . get_next_commitment_stats ( true , is_outbound_from_holder, channel_value_satoshis, value_to_holder_msat, pending_htlcs, fee_spike_buffer_htlc, feerate_per_kw, dust_exposure_limiting_feerate, holder_channel_constraints. dust_limit_satoshis , channel_type) . unwrap ( ) ;
220- let remote_stats = SpecTxBuilder { } . get_next_commitment_stats ( false , is_outbound_from_holder, channel_value_satoshis, value_to_holder_msat, pending_htlcs, 1 , feerate_per_kw, dust_exposure_limiting_feerate, counterparty_channel_constraints. dust_limit_satoshis , channel_type) . unwrap ( ) ;
203+ let local_stats_max_fee = SpecTxBuilder { }
204+ . get_next_commitment_stats (
205+ true ,
206+ is_outbound_from_holder,
207+ channel_value_satoshis,
208+ value_to_holder_msat,
209+ pending_htlcs,
210+ fee_spike_buffer_htlc + 1 ,
211+ feerate_per_kw,
212+ dust_exposure_limiting_feerate,
213+ holder_channel_constraints. dust_limit_satoshis ,
214+ channel_type,
215+ )
216+ . unwrap ( ) ;
217+ let local_stats_min_fee = SpecTxBuilder { }
218+ . get_next_commitment_stats (
219+ true ,
220+ is_outbound_from_holder,
221+ channel_value_satoshis,
222+ value_to_holder_msat,
223+ pending_htlcs,
224+ fee_spike_buffer_htlc,
225+ feerate_per_kw,
226+ dust_exposure_limiting_feerate,
227+ holder_channel_constraints. dust_limit_satoshis ,
228+ channel_type,
229+ )
230+ . unwrap ( ) ;
231+ let remote_stats = SpecTxBuilder { }
232+ . get_next_commitment_stats (
233+ false ,
234+ is_outbound_from_holder,
235+ channel_value_satoshis,
236+ value_to_holder_msat,
237+ pending_htlcs,
238+ 1 ,
239+ feerate_per_kw,
240+ dust_exposure_limiting_feerate,
241+ counterparty_channel_constraints. dust_limit_satoshis ,
242+ channel_type,
243+ )
244+ . unwrap ( ) ;
221245
222- let outbound_capacity_msat = local_stats_max_fee. holder_balance_before_fee_msat . saturating_sub ( holder_channel_constraints. channel_reserve_satoshis * 1000 ) ;
246+ let outbound_capacity_msat = local_stats_max_fee
247+ . holder_balance_before_fee_msat
248+ . saturating_sub ( holder_channel_constraints. channel_reserve_satoshis * 1000 ) ;
223249
224250 let mut available_capacity_msat = outbound_capacity_msat;
225- let ( real_htlc_success_tx_fee_sat, real_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat (
226- channel_type, feerate_per_kw
227- ) ;
251+ let ( real_htlc_success_tx_fee_sat, real_htlc_timeout_tx_fee_sat) =
252+ second_stage_tx_fees_sat ( channel_type, feerate_per_kw) ;
228253
229254 if is_outbound_from_holder {
230255 // We should mind channel commit tx fee when computing how much of the available capacity
@@ -235,40 +260,54 @@ impl TxBuilder for SpecTxBuilder {
235260 // dependency.
236261 // This complicates the computation around dust-values, up to the one-htlc-value.
237262
238- let real_dust_limit_timeout_sat = real_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
263+ let real_dust_limit_timeout_sat =
264+ real_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
239265 let mut max_reserved_commit_tx_fee_msat = local_stats_max_fee. commit_tx_fee_sat * 1000 ;
240266 let mut min_reserved_commit_tx_fee_msat = local_stats_min_fee. commit_tx_fee_sat * 1000 ;
241267
242268 if !channel_type. supports_anchors_zero_fee_htlc_tx ( ) {
243- max_reserved_commit_tx_fee_msat *= crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
244- min_reserved_commit_tx_fee_msat *= crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
269+ max_reserved_commit_tx_fee_msat *=
270+ crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
271+ min_reserved_commit_tx_fee_msat *=
272+ crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
245273 }
246274
247275 // We will first subtract the fee as if we were above-dust. Then, if the resulting
248276 // value ends up being below dust, we have this fee available again. In that case,
249277 // match the value to right-below-dust.
250- let capacity_minus_max_commitment_fee_msat = available_capacity_msat. saturating_sub ( max_reserved_commit_tx_fee_msat) ;
278+ let capacity_minus_max_commitment_fee_msat =
279+ available_capacity_msat. saturating_sub ( max_reserved_commit_tx_fee_msat) ;
251280 if capacity_minus_max_commitment_fee_msat < real_dust_limit_timeout_sat * 1000 {
252- let capacity_minus_min_commitment_fee_msat = available_capacity_msat. saturating_sub ( min_reserved_commit_tx_fee_msat) ;
253- available_capacity_msat = cmp:: min ( real_dust_limit_timeout_sat * 1000 - 1 , capacity_minus_min_commitment_fee_msat) ;
281+ let capacity_minus_min_commitment_fee_msat =
282+ available_capacity_msat. saturating_sub ( min_reserved_commit_tx_fee_msat) ;
283+ available_capacity_msat = cmp:: min (
284+ real_dust_limit_timeout_sat * 1000 - 1 ,
285+ capacity_minus_min_commitment_fee_msat,
286+ ) ;
254287 } else {
255288 available_capacity_msat = capacity_minus_max_commitment_fee_msat;
256289 }
257290 } else {
258291 // If the channel is inbound (i.e. counterparty pays the fee), we need to make sure
259292 // sending a new HTLC won't reduce their balance below our reserve threshold.
260- let real_dust_limit_success_sat = real_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
293+ let real_dust_limit_success_sat =
294+ real_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
261295 let max_reserved_commit_tx_fee_msat = remote_stats. commit_tx_fee_sat * 1000 ;
262296
263- let holder_selected_chan_reserve_msat = counterparty_channel_constraints. channel_reserve_satoshis * 1000 ;
264- if remote_stats. counterparty_balance_before_fee_msat < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat {
297+ let holder_selected_chan_reserve_msat =
298+ counterparty_channel_constraints. channel_reserve_satoshis * 1000 ;
299+ if remote_stats. counterparty_balance_before_fee_msat
300+ < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat
301+ {
265302 // If another HTLC's fee would reduce the remote's balance below the reserve limit
266303 // we've selected for them, we can only send dust HTLCs.
267- available_capacity_msat = cmp:: min ( available_capacity_msat, real_dust_limit_success_sat * 1000 - 1 ) ;
304+ available_capacity_msat =
305+ cmp:: min ( available_capacity_msat, real_dust_limit_success_sat * 1000 - 1 ) ;
268306 }
269307 }
270308
271- let mut next_outbound_htlc_minimum_msat = counterparty_channel_constraints. htlc_minimum_msat ;
309+ let mut next_outbound_htlc_minimum_msat =
310+ counterparty_channel_constraints. htlc_minimum_msat ;
272311
273312 // If we get close to our maximum dust exposure, we end up in a situation where we can send
274313 // between zero and the remaining dust exposure limit remaining OR above the dust limit.
@@ -278,50 +317,72 @@ impl TxBuilder for SpecTxBuilder {
278317 let mut dust_exposure_dust_limit_msat = 0 ;
279318
280319 let dust_buffer_feerate = get_dust_buffer_feerate ( feerate_per_kw) ;
281- let ( buffer_htlc_success_tx_fee_sat, buffer_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat (
282- channel_type, dust_buffer_feerate,
283- ) ;
284- let buffer_dust_limit_success_sat = buffer_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
285- let buffer_dust_limit_timeout_sat = buffer_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
320+ let ( buffer_htlc_success_tx_fee_sat, buffer_htlc_timeout_tx_fee_sat) =
321+ second_stage_tx_fees_sat ( channel_type, dust_buffer_feerate) ;
322+ let buffer_dust_limit_success_sat =
323+ buffer_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
324+ let buffer_dust_limit_timeout_sat =
325+ buffer_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
286326
287327 if remote_stats. extra_accepted_htlc_dust_exposure_msat > max_dust_htlc_exposure_msat {
288328 // If adding an extra HTLC would put us over the dust limit in total fees, we cannot
289329 // send any non-dust HTLCs.
290- available_capacity_msat = cmp:: min ( available_capacity_msat, buffer_dust_limit_success_sat * 1000 ) ;
330+ available_capacity_msat =
331+ cmp:: min ( available_capacity_msat, buffer_dust_limit_success_sat * 1000 ) ;
291332 }
292333
293- if remote_stats. dust_exposure_msat . saturating_add ( buffer_dust_limit_success_sat * 1000 ) > max_dust_htlc_exposure_msat. saturating_add ( 1 ) {
334+ if remote_stats. dust_exposure_msat . saturating_add ( buffer_dust_limit_success_sat * 1000 )
335+ > max_dust_htlc_exposure_msat. saturating_add ( 1 )
336+ {
294337 // Note that we don't use the `counterparty_tx_dust_exposure` (with
295338 // `htlc_dust_exposure_msat`) here as it only applies to non-dust HTLCs.
296339 remaining_msat_below_dust_exposure_limit =
297340 Some ( max_dust_htlc_exposure_msat. saturating_sub ( remote_stats. dust_exposure_msat ) ) ;
298- dust_exposure_dust_limit_msat = cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_success_sat * 1000 ) ;
341+ dust_exposure_dust_limit_msat =
342+ cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_success_sat * 1000 ) ;
299343 }
300344
301- if local_stats_max_fee. dust_exposure_msat as i64 + buffer_dust_limit_timeout_sat as i64 * 1000 - 1 > max_dust_htlc_exposure_msat. try_into ( ) . unwrap_or ( i64:: max_value ( ) ) {
345+ if local_stats_max_fee. dust_exposure_msat as i64
346+ + buffer_dust_limit_timeout_sat as i64 * 1000
347+ - 1 > max_dust_htlc_exposure_msat. try_into ( ) . unwrap_or ( i64:: max_value ( ) )
348+ {
302349 remaining_msat_below_dust_exposure_limit = Some ( cmp:: min (
303350 remaining_msat_below_dust_exposure_limit. unwrap_or ( u64:: max_value ( ) ) ,
304- max_dust_htlc_exposure_msat. saturating_sub ( local_stats_max_fee. dust_exposure_msat ) ) ) ;
305- dust_exposure_dust_limit_msat = cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_timeout_sat * 1000 ) ;
351+ max_dust_htlc_exposure_msat. saturating_sub ( local_stats_max_fee. dust_exposure_msat ) ,
352+ ) ) ;
353+ dust_exposure_dust_limit_msat =
354+ cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_timeout_sat * 1000 ) ;
306355 }
307356
308357 if let Some ( remaining_limit_msat) = remaining_msat_below_dust_exposure_limit {
309358 if available_capacity_msat < dust_exposure_dust_limit_msat {
310359 available_capacity_msat = cmp:: min ( available_capacity_msat, remaining_limit_msat) ;
311360 } else {
312- next_outbound_htlc_minimum_msat = cmp:: max ( next_outbound_htlc_minimum_msat, dust_exposure_dust_limit_msat) ;
361+ next_outbound_htlc_minimum_msat =
362+ cmp:: max ( next_outbound_htlc_minimum_msat, dust_exposure_dust_limit_msat) ;
313363 }
314364 }
315365
316- available_capacity_msat = cmp:: min ( available_capacity_msat,
317- counterparty_channel_constraints. max_htlc_value_in_flight_msat - pending_htlcs. iter ( ) . filter ( |htlc| htlc. outbound ) . map ( |htlc| htlc. amount_msat ) . sum :: < u64 > ( ) ) ;
366+ available_capacity_msat = cmp:: min (
367+ available_capacity_msat,
368+ counterparty_channel_constraints. max_htlc_value_in_flight_msat
369+ - pending_htlcs
370+ . iter ( )
371+ . filter ( |htlc| htlc. outbound )
372+ . map ( |htlc| htlc. amount_msat )
373+ . sum :: < u64 > ( ) ,
374+ ) ;
318375
319- if pending_htlcs. iter ( ) . filter ( |htlc| htlc. outbound ) . count ( ) + 1 > counterparty_channel_constraints. max_accepted_htlcs as usize {
376+ if pending_htlcs. iter ( ) . filter ( |htlc| htlc. outbound ) . count ( ) + 1
377+ > counterparty_channel_constraints. max_accepted_htlcs as usize
378+ {
320379 available_capacity_msat = 0 ;
321380 }
322381
323382 crate :: ln:: channel:: AvailableBalances {
324- inbound_capacity_msat : remote_stats. counterparty_balance_before_fee_msat . saturating_sub ( counterparty_channel_constraints. channel_reserve_satoshis * 1000 ) ,
383+ inbound_capacity_msat : remote_stats
384+ . counterparty_balance_before_fee_msat
385+ . saturating_sub ( counterparty_channel_constraints. channel_reserve_satoshis * 1000 ) ,
325386 outbound_capacity_msat,
326387 next_outbound_htlc_limit_msat : available_capacity_msat,
327388 next_outbound_htlc_minimum_msat,
@@ -499,12 +560,14 @@ impl TxBuilder for SpecTxBuilder {
499560 . unwrap ( )
500561 . checked_sub ( remote_htlc_total_msat)
501562 . unwrap ( ) ;
502- let ( local_balance_before_fee_msat, remote_balance_before_fee_msat) = subtract_addl_outputs (
503- channel_parameters. is_outbound_from_holder ,
504- value_to_self_after_htlcs_msat,
505- value_to_remote_after_htlcs_msat,
506- & channel_parameters. channel_type_features
507- ) . unwrap ( ) ;
563+ let ( local_balance_before_fee_msat, remote_balance_before_fee_msat) =
564+ subtract_addl_outputs (
565+ channel_parameters. is_outbound_from_holder ,
566+ value_to_self_after_htlcs_msat,
567+ value_to_remote_after_htlcs_msat,
568+ & channel_parameters. channel_type_features ,
569+ )
570+ . unwrap ( ) ;
508571
509572 // We MUST use saturating subs here, as the funder's balance is not guaranteed to be greater
510573 // than or equal to `commit_tx_fee_sat`.
0 commit comments