@@ -126,17 +126,11 @@ pub(crate) struct ChannelConstraints {
126126
127127pub ( crate ) trait TxBuilder {
128128 fn get_available_balances (
129- & self ,
130- is_outbound_from_holder : bool ,
131- channel_value_satoshis : u64 ,
132- value_to_holder_msat : u64 ,
133- pending_htlcs : & [ HTLCAmountDirection ] ,
134- feerate_per_kw : u32 ,
135- dust_exposure_limiting_feerate : Option < u32 > ,
136- max_dust_htlc_exposure_msat : u64 ,
129+ & self , is_outbound_from_holder : bool , channel_value_satoshis : u64 ,
130+ value_to_holder_msat : u64 , pending_htlcs : & [ HTLCAmountDirection ] , feerate_per_kw : u32 ,
131+ dust_exposure_limiting_feerate : Option < u32 > , max_dust_htlc_exposure_msat : u64 ,
137132 holder_channel_constraints : ChannelConstraints ,
138- counterparty_channel_constraints : ChannelConstraints ,
139- channel_type : & ChannelTypeFeatures ,
133+ counterparty_channel_constraints : ChannelConstraints , channel_type : & ChannelTypeFeatures ,
140134 ) -> crate :: ln:: channel:: AvailableBalances ;
141135 fn get_next_commitment_stats (
142136 & self , local : bool , is_outbound_from_holder : bool , channel_value_satoshis : u64 ,
@@ -159,36 +153,60 @@ pub(crate) struct SpecTxBuilder {}
159153
160154impl TxBuilder for SpecTxBuilder {
161155 fn get_available_balances (
162- & self ,
163- is_outbound_from_holder : bool ,
164- channel_value_satoshis : u64 ,
165- value_to_holder_msat : u64 ,
166- pending_htlcs : & [ HTLCAmountDirection ] ,
167- feerate_per_kw : u32 ,
168- dust_exposure_limiting_feerate : Option < u32 > ,
169- max_dust_htlc_exposure_msat : u64 ,
156+ & self , is_outbound_from_holder : bool , channel_value_satoshis : u64 ,
157+ value_to_holder_msat : u64 , pending_htlcs : & [ HTLCAmountDirection ] , feerate_per_kw : u32 ,
158+ dust_exposure_limiting_feerate : Option < u32 > , max_dust_htlc_exposure_msat : u64 ,
170159 holder_channel_constraints : ChannelConstraints ,
171- counterparty_channel_constraints : ChannelConstraints ,
172- channel_type : & ChannelTypeFeatures ,
160+ counterparty_channel_constraints : ChannelConstraints , channel_type : & ChannelTypeFeatures ,
173161 ) -> crate :: ln:: channel:: AvailableBalances {
174- let fee_spike_buffer_htlc = if channel_type. supports_anchor_zero_fee_commitments ( ) {
175- 0
176- } else {
177- 1
178- } ;
179-
180- 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) ;
181- 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) ;
182- 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) ;
162+ let fee_spike_buffer_htlc =
163+ if channel_type. supports_anchor_zero_fee_commitments ( ) { 0 } else { 1 } ;
164+
165+ let local_stats_max_fee = SpecTxBuilder { } . get_next_commitment_stats (
166+ true ,
167+ is_outbound_from_holder,
168+ channel_value_satoshis,
169+ value_to_holder_msat,
170+ pending_htlcs,
171+ fee_spike_buffer_htlc + 1 ,
172+ feerate_per_kw,
173+ dust_exposure_limiting_feerate,
174+ holder_channel_constraints. dust_limit_satoshis ,
175+ channel_type,
176+ ) ;
177+ let local_stats_min_fee = SpecTxBuilder { } . get_next_commitment_stats (
178+ true ,
179+ is_outbound_from_holder,
180+ channel_value_satoshis,
181+ value_to_holder_msat,
182+ pending_htlcs,
183+ fee_spike_buffer_htlc,
184+ feerate_per_kw,
185+ dust_exposure_limiting_feerate,
186+ holder_channel_constraints. dust_limit_satoshis ,
187+ channel_type,
188+ ) ;
189+ let remote_stats = SpecTxBuilder { } . get_next_commitment_stats (
190+ false ,
191+ is_outbound_from_holder,
192+ channel_value_satoshis,
193+ value_to_holder_msat,
194+ pending_htlcs,
195+ 1 ,
196+ feerate_per_kw,
197+ dust_exposure_limiting_feerate,
198+ counterparty_channel_constraints. dust_limit_satoshis ,
199+ channel_type,
200+ ) ;
183201
184- let outbound_capacity_msat = local_stats_max_fee. holder_balance_before_fee_msat . unwrap_or ( 0 )
185- . saturating_sub (
186- holder_channel_constraints. channel_reserve_satoshis * 1000 ) ;
202+ let outbound_capacity_msat = local_stats_max_fee
203+ . holder_balance_before_fee_msat
204+ . unwrap_or ( 0 )
205+ . saturating_sub ( holder_channel_constraints. channel_reserve_satoshis * 1000 ) ;
187206
188207 let mut available_capacity_msat = outbound_capacity_msat;
189- let ( real_htlc_success_tx_fee_sat, real_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat (
190- channel_type, feerate_per_kw
191- ) ;
208+ let ( real_htlc_success_tx_fee_sat, real_htlc_timeout_tx_fee_sat) =
209+ second_stage_tx_fees_sat ( channel_type, feerate_per_kw) ;
192210
193211 if is_outbound_from_holder {
194212 // We should mind channel commit tx fee when computing how much of the available capacity
@@ -199,40 +217,54 @@ impl TxBuilder for SpecTxBuilder {
199217 // dependency.
200218 // This complicates the computation around dust-values, up to the one-htlc-value.
201219
202- let real_dust_limit_timeout_sat = real_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
220+ let real_dust_limit_timeout_sat =
221+ real_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
203222 let mut max_reserved_commit_tx_fee_msat = local_stats_max_fee. commit_tx_fee_sat * 1000 ;
204223 let mut min_reserved_commit_tx_fee_msat = local_stats_min_fee. commit_tx_fee_sat * 1000 ;
205224
206225 if !channel_type. supports_anchors_zero_fee_htlc_tx ( ) {
207- max_reserved_commit_tx_fee_msat *= crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
208- min_reserved_commit_tx_fee_msat *= crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
226+ max_reserved_commit_tx_fee_msat *=
227+ crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
228+ min_reserved_commit_tx_fee_msat *=
229+ crate :: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
209230 }
210231
211232 // We will first subtract the fee as if we were above-dust. Then, if the resulting
212233 // value ends up being below dust, we have this fee available again. In that case,
213234 // match the value to right-below-dust.
214- let capacity_minus_max_commitment_fee_msat = available_capacity_msat. saturating_sub ( max_reserved_commit_tx_fee_msat) ;
235+ let capacity_minus_max_commitment_fee_msat =
236+ available_capacity_msat. saturating_sub ( max_reserved_commit_tx_fee_msat) ;
215237 if capacity_minus_max_commitment_fee_msat < real_dust_limit_timeout_sat * 1000 {
216- let capacity_minus_min_commitment_fee_msat = available_capacity_msat. saturating_sub ( min_reserved_commit_tx_fee_msat) ;
217- available_capacity_msat = cmp:: min ( real_dust_limit_timeout_sat * 1000 - 1 , capacity_minus_min_commitment_fee_msat) ;
238+ let capacity_minus_min_commitment_fee_msat =
239+ available_capacity_msat. saturating_sub ( min_reserved_commit_tx_fee_msat) ;
240+ available_capacity_msat = cmp:: min (
241+ real_dust_limit_timeout_sat * 1000 - 1 ,
242+ capacity_minus_min_commitment_fee_msat,
243+ ) ;
218244 } else {
219245 available_capacity_msat = capacity_minus_max_commitment_fee_msat;
220246 }
221247 } else {
222248 // If the channel is inbound (i.e. counterparty pays the fee), we need to make sure
223249 // sending a new HTLC won't reduce their balance below our reserve threshold.
224- let real_dust_limit_success_sat = real_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
250+ let real_dust_limit_success_sat =
251+ real_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
225252 let max_reserved_commit_tx_fee_msat = remote_stats. commit_tx_fee_sat * 1000 ;
226253
227- let holder_selected_chan_reserve_msat = counterparty_channel_constraints. channel_reserve_satoshis * 1000 ;
228- if remote_stats. counterparty_balance_before_fee_msat . unwrap_or ( 0 ) < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat {
254+ let holder_selected_chan_reserve_msat =
255+ counterparty_channel_constraints. channel_reserve_satoshis * 1000 ;
256+ if remote_stats. counterparty_balance_before_fee_msat . unwrap_or ( 0 )
257+ < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat
258+ {
229259 // If another HTLC's fee would reduce the remote's balance below the reserve limit
230260 // we've selected for them, we can only send dust HTLCs.
231- available_capacity_msat = cmp:: min ( available_capacity_msat, real_dust_limit_success_sat * 1000 - 1 ) ;
261+ available_capacity_msat =
262+ cmp:: min ( available_capacity_msat, real_dust_limit_success_sat * 1000 - 1 ) ;
232263 }
233264 }
234265
235- let mut next_outbound_htlc_minimum_msat = counterparty_channel_constraints. htlc_minimum_msat ;
266+ let mut next_outbound_htlc_minimum_msat =
267+ counterparty_channel_constraints. htlc_minimum_msat ;
236268
237269 // If we get close to our maximum dust exposure, we end up in a situation where we can send
238270 // between zero and the remaining dust exposure limit remaining OR above the dust limit.
@@ -242,52 +274,77 @@ impl TxBuilder for SpecTxBuilder {
242274 let mut dust_exposure_dust_limit_msat = 0 ;
243275
244276 let dust_buffer_feerate = get_dust_buffer_feerate ( feerate_per_kw) ;
245- let ( buffer_htlc_success_tx_fee_sat, buffer_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat (
246- channel_type, dust_buffer_feerate,
247- ) ;
248- let buffer_dust_limit_success_sat = buffer_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
249- let buffer_dust_limit_timeout_sat = buffer_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
250-
251- if let Some ( extra_htlc_dust_exposure) = remote_stats. extra_nondust_htlc_on_counterparty_tx_dust_exposure_msat {
277+ let ( buffer_htlc_success_tx_fee_sat, buffer_htlc_timeout_tx_fee_sat) =
278+ second_stage_tx_fees_sat ( channel_type, dust_buffer_feerate) ;
279+ let buffer_dust_limit_success_sat =
280+ buffer_htlc_success_tx_fee_sat + counterparty_channel_constraints. dust_limit_satoshis ;
281+ let buffer_dust_limit_timeout_sat =
282+ buffer_htlc_timeout_tx_fee_sat + holder_channel_constraints. dust_limit_satoshis ;
283+
284+ if let Some ( extra_htlc_dust_exposure) =
285+ remote_stats. extra_nondust_htlc_on_counterparty_tx_dust_exposure_msat
286+ {
252287 if extra_htlc_dust_exposure > max_dust_htlc_exposure_msat {
253288 // If adding an extra HTLC would put us over the dust limit in total fees, we cannot
254289 // send any non-dust HTLCs.
255- available_capacity_msat = cmp:: min ( available_capacity_msat, buffer_dust_limit_success_sat * 1000 ) ;
290+ available_capacity_msat =
291+ cmp:: min ( available_capacity_msat, buffer_dust_limit_success_sat * 1000 ) ;
256292 }
257293 }
258294
259- if remote_stats. dust_exposure_msat . saturating_add ( buffer_dust_limit_success_sat * 1000 ) > max_dust_htlc_exposure_msat. saturating_add ( 1 ) {
295+ if remote_stats. dust_exposure_msat . saturating_add ( buffer_dust_limit_success_sat * 1000 )
296+ > max_dust_htlc_exposure_msat. saturating_add ( 1 )
297+ {
260298 // Note that we don't use the `counterparty_tx_dust_exposure` (with
261299 // `htlc_dust_exposure_msat`) here as it only applies to non-dust HTLCs.
262300 remaining_msat_below_dust_exposure_limit =
263301 Some ( max_dust_htlc_exposure_msat. saturating_sub ( remote_stats. dust_exposure_msat ) ) ;
264- dust_exposure_dust_limit_msat = cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_success_sat * 1000 ) ;
302+ dust_exposure_dust_limit_msat =
303+ cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_success_sat * 1000 ) ;
265304 }
266305
267- 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 ( ) ) {
306+ if local_stats_max_fee. dust_exposure_msat as i64
307+ + buffer_dust_limit_timeout_sat as i64 * 1000
308+ - 1 > max_dust_htlc_exposure_msat. try_into ( ) . unwrap_or ( i64:: max_value ( ) )
309+ {
268310 remaining_msat_below_dust_exposure_limit = Some ( cmp:: min (
269311 remaining_msat_below_dust_exposure_limit. unwrap_or ( u64:: max_value ( ) ) ,
270- max_dust_htlc_exposure_msat. saturating_sub ( local_stats_max_fee. dust_exposure_msat ) ) ) ;
271- dust_exposure_dust_limit_msat = cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_timeout_sat * 1000 ) ;
312+ max_dust_htlc_exposure_msat. saturating_sub ( local_stats_max_fee. dust_exposure_msat ) ,
313+ ) ) ;
314+ dust_exposure_dust_limit_msat =
315+ cmp:: max ( dust_exposure_dust_limit_msat, buffer_dust_limit_timeout_sat * 1000 ) ;
272316 }
273317
274318 if let Some ( remaining_limit_msat) = remaining_msat_below_dust_exposure_limit {
275319 if available_capacity_msat < dust_exposure_dust_limit_msat {
276320 available_capacity_msat = cmp:: min ( available_capacity_msat, remaining_limit_msat) ;
277321 } else {
278- next_outbound_htlc_minimum_msat = cmp:: max ( next_outbound_htlc_minimum_msat, dust_exposure_dust_limit_msat) ;
322+ next_outbound_htlc_minimum_msat =
323+ cmp:: max ( next_outbound_htlc_minimum_msat, dust_exposure_dust_limit_msat) ;
279324 }
280325 }
281326
282- available_capacity_msat = cmp:: min ( available_capacity_msat,
283- counterparty_channel_constraints. max_htlc_value_in_flight_msat - pending_htlcs. iter ( ) . filter ( |htlc| htlc. outbound ) . map ( |htlc| htlc. amount_msat ) . sum :: < u64 > ( ) ) ;
327+ available_capacity_msat = cmp:: min (
328+ available_capacity_msat,
329+ counterparty_channel_constraints. max_htlc_value_in_flight_msat
330+ - pending_htlcs
331+ . iter ( )
332+ . filter ( |htlc| htlc. outbound )
333+ . map ( |htlc| htlc. amount_msat )
334+ . sum :: < u64 > ( ) ,
335+ ) ;
284336
285- if pending_htlcs. iter ( ) . filter ( |htlc| htlc. outbound ) . count ( ) + 1 > counterparty_channel_constraints. max_accepted_htlcs as usize {
337+ if pending_htlcs. iter ( ) . filter ( |htlc| htlc. outbound ) . count ( ) + 1
338+ > counterparty_channel_constraints. max_accepted_htlcs as usize
339+ {
286340 available_capacity_msat = 0 ;
287341 }
288342
289343 crate :: ln:: channel:: AvailableBalances {
290- inbound_capacity_msat : remote_stats. counterparty_balance_before_fee_msat . unwrap_or ( 0 ) . saturating_sub ( counterparty_channel_constraints. channel_reserve_satoshis * 1000 ) ,
344+ inbound_capacity_msat : remote_stats
345+ . counterparty_balance_before_fee_msat
346+ . unwrap_or ( 0 )
347+ . saturating_sub ( counterparty_channel_constraints. channel_reserve_satoshis * 1000 ) ,
291348 outbound_capacity_msat,
292349 next_outbound_htlc_limit_msat : available_capacity_msat,
293350 next_outbound_htlc_minimum_msat,
0 commit comments