Skip to content

Commit b9be982

Browse files
committed
Add TxBuilder::get_available_balances
Besides the changes in the `TxBuilder` API, this is a code move.
1 parent db1b4af commit b9be982

File tree

2 files changed

+162
-138
lines changed

2 files changed

+162
-138
lines changed

lightning/src/ln/channel.rs

Lines changed: 13 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,7 @@ impl HolderCommitmentPoint {
13621362
#[cfg(any(fuzzing, test, feature = "_test_utils"))]
13631363
pub const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
13641364
#[cfg(not(any(fuzzing, test, feature = "_test_utils")))]
1365-
const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
1365+
pub(crate) const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
13661366

13671367
/// If we fail to see a funding transaction confirmed on-chain within this many blocks after the
13681368
/// channel creation on an inbound channel, we simply force-close and move on.
@@ -5085,13 +5085,6 @@ where
50855085
where
50865086
F::Target: FeeEstimator,
50875087
{
5088-
use crate::sign::tx_builder::get_dust_buffer_feerate;
5089-
5090-
let holder_channel_constraints = self.get_holder_channel_constraints(funding);
5091-
let counterparty_channel_constraints = self.get_counterparty_channel_constraints(funding);
5092-
// Note that we have to handle overflow due to the case mentioned in the docs in general
5093-
// here.
5094-
50955088
let pending_outbound_htlcs = self.pending_outbound_htlcs.iter().map(|htlc| HTLCAmountDirection { amount_msat: htlc.amount_msat, outbound: true });
50965089
let pending_inbound_htlcs = self.pending_inbound_htlcs.iter().map(|htlc| HTLCAmountDirection { amount_msat: htlc.amount_msat, outbound: false });
50975090
let holding_cell_htlcs = self.holding_cell_htlc_updates.iter().filter_map(|htlc| {
@@ -5104,141 +5097,24 @@ where
51045097

51055098
let mut pending_htlcs: Vec<HTLCAmountDirection> = Vec::with_capacity(self.pending_outbound_htlcs.len() + self.pending_inbound_htlcs.len() + self.holding_cell_htlc_updates.len());
51065099
pending_htlcs.extend(pending_outbound_htlcs.chain(pending_inbound_htlcs).chain(holding_cell_htlcs));
5107-
let pending_htlcs = &pending_htlcs;
51085100

51095101
let dust_exposure_limiting_feerate = self.get_dust_exposure_limiting_feerate(
51105102
&fee_estimator, funding.get_channel_type(),
51115103
);
51125104
let max_dust_htlc_exposure_msat = self.get_max_dust_htlc_exposure_msat(dust_exposure_limiting_feerate);
51135105

5114-
let is_outbound_from_holder = funding.is_outbound();
5115-
let channel_value_satoshis = funding.get_value_satoshis();
5116-
let value_to_holder_msat = funding.get_value_to_self_msat();
5117-
let feerate_per_kw = self.feerate_per_kw;
5118-
let channel_type = funding.get_channel_type();
5119-
5120-
let fee_spike_buffer_htlc = if channel_type.supports_anchor_zero_fee_commitments() {
5121-
0
5122-
} else {
5123-
1
5124-
};
5125-
5126-
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);
5127-
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);
5128-
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);
5129-
5130-
let outbound_capacity_msat = local_stats_max_fee.holder_balance_before_fee_msat.unwrap_or(0)
5131-
.saturating_sub(
5132-
holder_channel_constraints.channel_reserve_satoshis * 1000);
5133-
5134-
let mut available_capacity_msat = outbound_capacity_msat;
5135-
let (real_htlc_success_tx_fee_sat, real_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat(
5136-
channel_type, feerate_per_kw
5137-
);
5138-
5139-
if is_outbound_from_holder {
5140-
// We should mind channel commit tx fee when computing how much of the available capacity
5141-
// can be used in the next htlc. Mirrors the logic in send_htlc.
5142-
//
5143-
// The fee depends on whether the amount we will be sending is above dust or not,
5144-
// and the answer will in turn change the amount itself — making it a circular
5145-
// dependency.
5146-
// This complicates the computation around dust-values, up to the one-htlc-value.
5147-
5148-
let real_dust_limit_timeout_sat = real_htlc_timeout_tx_fee_sat + holder_channel_constraints.dust_limit_satoshis;
5149-
let mut max_reserved_commit_tx_fee_msat = local_stats_max_fee.commit_tx_fee_sat * 1000;
5150-
let mut min_reserved_commit_tx_fee_msat = local_stats_min_fee.commit_tx_fee_sat * 1000;
5151-
5152-
if !channel_type.supports_anchors_zero_fee_htlc_tx() {
5153-
max_reserved_commit_tx_fee_msat *= crate::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
5154-
min_reserved_commit_tx_fee_msat *= crate::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
5155-
}
5156-
5157-
// We will first subtract the fee as if we were above-dust. Then, if the resulting
5158-
// value ends up being below dust, we have this fee available again. In that case,
5159-
// match the value to right-below-dust.
5160-
let capacity_minus_max_commitment_fee_msat = available_capacity_msat.saturating_sub(max_reserved_commit_tx_fee_msat);
5161-
if capacity_minus_max_commitment_fee_msat < real_dust_limit_timeout_sat * 1000 {
5162-
let capacity_minus_min_commitment_fee_msat = available_capacity_msat.saturating_sub(min_reserved_commit_tx_fee_msat);
5163-
available_capacity_msat = cmp::min(real_dust_limit_timeout_sat * 1000 - 1, capacity_minus_min_commitment_fee_msat);
5164-
} else {
5165-
available_capacity_msat = capacity_minus_max_commitment_fee_msat;
5166-
}
5167-
} else {
5168-
// If the channel is inbound (i.e. counterparty pays the fee), we need to make sure
5169-
// sending a new HTLC won't reduce their balance below our reserve threshold.
5170-
let real_dust_limit_success_sat = real_htlc_success_tx_fee_sat + counterparty_channel_constraints.dust_limit_satoshis;
5171-
let max_reserved_commit_tx_fee_msat = remote_stats.commit_tx_fee_sat * 1000;
5172-
5173-
let holder_selected_chan_reserve_msat = counterparty_channel_constraints.channel_reserve_satoshis * 1000;
5174-
if remote_stats.counterparty_balance_before_fee_msat.unwrap_or(0) < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat {
5175-
// If another HTLC's fee would reduce the remote's balance below the reserve limit
5176-
// we've selected for them, we can only send dust HTLCs.
5177-
available_capacity_msat = cmp::min(available_capacity_msat, real_dust_limit_success_sat * 1000 - 1);
5178-
}
5179-
}
5180-
5181-
let mut next_outbound_htlc_minimum_msat = counterparty_channel_constraints.htlc_minimum_msat;
5182-
5183-
// If we get close to our maximum dust exposure, we end up in a situation where we can send
5184-
// between zero and the remaining dust exposure limit remaining OR above the dust limit.
5185-
// Because we cannot express this as a simple min/max, we prefer to tell the user they can
5186-
// send above the dust limit (as the router can always overpay to meet the dust limit).
5187-
let mut remaining_msat_below_dust_exposure_limit = None;
5188-
let mut dust_exposure_dust_limit_msat = 0;
5189-
5190-
let dust_buffer_feerate = get_dust_buffer_feerate(feerate_per_kw);
5191-
let (buffer_htlc_success_tx_fee_sat, buffer_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat(
5192-
channel_type, dust_buffer_feerate,
5193-
);
5194-
let buffer_dust_limit_success_sat = buffer_htlc_success_tx_fee_sat + counterparty_channel_constraints.dust_limit_satoshis;
5195-
let buffer_dust_limit_timeout_sat = buffer_htlc_timeout_tx_fee_sat + holder_channel_constraints.dust_limit_satoshis;
5196-
5197-
if let Some(extra_htlc_dust_exposure) = remote_stats.extra_nondust_htlc_on_counterparty_tx_dust_exposure_msat {
5198-
if extra_htlc_dust_exposure > max_dust_htlc_exposure_msat {
5199-
// If adding an extra HTLC would put us over the dust limit in total fees, we cannot
5200-
// send any non-dust HTLCs.
5201-
available_capacity_msat = cmp::min(available_capacity_msat, buffer_dust_limit_success_sat * 1000);
5202-
}
5203-
}
5204-
5205-
if remote_stats.dust_exposure_msat.saturating_add(buffer_dust_limit_success_sat * 1000) > max_dust_htlc_exposure_msat.saturating_add(1) {
5206-
// Note that we don't use the `counterparty_tx_dust_exposure` (with
5207-
// `htlc_dust_exposure_msat`) here as it only applies to non-dust HTLCs.
5208-
remaining_msat_below_dust_exposure_limit =
5209-
Some(max_dust_htlc_exposure_msat.saturating_sub(remote_stats.dust_exposure_msat));
5210-
dust_exposure_dust_limit_msat = cmp::max(dust_exposure_dust_limit_msat, buffer_dust_limit_success_sat * 1000);
5211-
}
5212-
5213-
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()) {
5214-
remaining_msat_below_dust_exposure_limit = Some(cmp::min(
5215-
remaining_msat_below_dust_exposure_limit.unwrap_or(u64::max_value()),
5216-
max_dust_htlc_exposure_msat.saturating_sub(local_stats_max_fee.dust_exposure_msat)));
5217-
dust_exposure_dust_limit_msat = cmp::max(dust_exposure_dust_limit_msat, buffer_dust_limit_timeout_sat * 1000);
5218-
}
5219-
5220-
if let Some(remaining_limit_msat) = remaining_msat_below_dust_exposure_limit {
5221-
if available_capacity_msat < dust_exposure_dust_limit_msat {
5222-
available_capacity_msat = cmp::min(available_capacity_msat, remaining_limit_msat);
5223-
} else {
5224-
next_outbound_htlc_minimum_msat = cmp::max(next_outbound_htlc_minimum_msat, dust_exposure_dust_limit_msat);
5225-
}
5226-
}
5227-
5228-
available_capacity_msat = cmp::min(available_capacity_msat,
5229-
counterparty_channel_constraints.max_htlc_value_in_flight_msat - pending_htlcs.iter().filter(|htlc| htlc.outbound).map(|htlc| htlc.amount_msat).sum::<u64>());
5230-
5231-
if pending_htlcs.iter().filter(|htlc| htlc.outbound).count() + 1 > counterparty_channel_constraints.max_accepted_htlcs as usize {
5232-
available_capacity_msat = 0;
5233-
}
5234-
5235-
#[allow(deprecated)] // TODO: Remove once balance_msat is removed.
5236-
AvailableBalances {
5237-
inbound_capacity_msat: remote_stats.counterparty_balance_before_fee_msat.unwrap_or(0).saturating_sub(counterparty_channel_constraints.channel_reserve_satoshis * 1000),
5238-
outbound_capacity_msat,
5239-
next_outbound_htlc_limit_msat: available_capacity_msat,
5240-
next_outbound_htlc_minimum_msat,
5241-
}
5106+
SpecTxBuilder {}.get_available_balances(
5107+
funding.is_outbound(),
5108+
funding.get_value_satoshis(),
5109+
funding.get_value_to_self_msat(),
5110+
&pending_htlcs,
5111+
self.feerate_per_kw,
5112+
dust_exposure_limiting_feerate,
5113+
max_dust_htlc_exposure_msat,
5114+
self.get_holder_channel_constraints(funding),
5115+
self.get_counterparty_channel_constraints(funding),
5116+
funding.get_channel_type(),
5117+
)
52425118
}
52435119

52445120
/// Get the commitment tx fee for the local's (i.e. our) next commitment transaction based on the

lightning/src/sign/tx_builder.rs

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn subtract_addl_outputs(
106106
(local_balance_before_fee_msat, remote_balance_before_fee_msat)
107107
}
108108

109-
pub(crate) fn get_dust_buffer_feerate(feerate_per_kw: u32) -> u32 {
109+
fn get_dust_buffer_feerate(feerate_per_kw: u32) -> u32 {
110110
// When calculating our exposure to dust HTLCs, we assume that the channel feerate
111111
// may, at any point, increase by at least 10 sat/vB (i.e 2530 sat/kWU) or 25%,
112112
// whichever is higher. This ensures that we aren't suddenly exposed to significantly
@@ -125,6 +125,19 @@ pub(crate) struct ChannelConstraints {
125125
}
126126

127127
pub(crate) trait TxBuilder {
128+
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,
137+
holder_channel_constraints: ChannelConstraints,
138+
counterparty_channel_constraints: ChannelConstraints,
139+
channel_type: &ChannelTypeFeatures,
140+
) -> crate::ln::channel::AvailableBalances;
128141
fn get_next_commitment_stats(
129142
&self, local: bool, is_outbound_from_holder: bool, channel_value_satoshis: u64,
130143
value_to_holder_msat: u64, next_commitment_htlcs: &[HTLCAmountDirection],
@@ -152,6 +165,141 @@ pub(crate) trait TxBuilder {
152165
pub(crate) struct SpecTxBuilder {}
153166

154167
impl TxBuilder for SpecTxBuilder {
168+
fn get_available_balances(
169+
&self,
170+
is_outbound_from_holder: bool,
171+
channel_value_satoshis: u64,
172+
value_to_holder_msat: u64,
173+
pending_htlcs: &[HTLCAmountDirection],
174+
feerate_per_kw: u32,
175+
dust_exposure_limiting_feerate: Option<u32>,
176+
max_dust_htlc_exposure_msat: u64,
177+
holder_channel_constraints: ChannelConstraints,
178+
counterparty_channel_constraints: ChannelConstraints,
179+
channel_type: &ChannelTypeFeatures,
180+
) -> crate::ln::channel::AvailableBalances {
181+
let fee_spike_buffer_htlc = if channel_type.supports_anchor_zero_fee_commitments() {
182+
0
183+
} else {
184+
1
185+
};
186+
187+
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);
188+
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);
189+
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);
190+
191+
let outbound_capacity_msat = local_stats_max_fee.holder_balance_before_fee_msat.unwrap_or(0)
192+
.saturating_sub(
193+
holder_channel_constraints.channel_reserve_satoshis * 1000);
194+
195+
let mut available_capacity_msat = outbound_capacity_msat;
196+
let (real_htlc_success_tx_fee_sat, real_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat(
197+
channel_type, feerate_per_kw
198+
);
199+
200+
if is_outbound_from_holder {
201+
// We should mind channel commit tx fee when computing how much of the available capacity
202+
// can be used in the next htlc. Mirrors the logic in send_htlc.
203+
//
204+
// The fee depends on whether the amount we will be sending is above dust or not,
205+
// and the answer will in turn change the amount itself — making it a circular
206+
// dependency.
207+
// This complicates the computation around dust-values, up to the one-htlc-value.
208+
209+
let real_dust_limit_timeout_sat = real_htlc_timeout_tx_fee_sat + holder_channel_constraints.dust_limit_satoshis;
210+
let mut max_reserved_commit_tx_fee_msat = local_stats_max_fee.commit_tx_fee_sat * 1000;
211+
let mut min_reserved_commit_tx_fee_msat = local_stats_min_fee.commit_tx_fee_sat * 1000;
212+
213+
if !channel_type.supports_anchors_zero_fee_htlc_tx() {
214+
max_reserved_commit_tx_fee_msat *= crate::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
215+
min_reserved_commit_tx_fee_msat *= crate::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
216+
}
217+
218+
// We will first subtract the fee as if we were above-dust. Then, if the resulting
219+
// value ends up being below dust, we have this fee available again. In that case,
220+
// match the value to right-below-dust.
221+
let capacity_minus_max_commitment_fee_msat = available_capacity_msat.saturating_sub(max_reserved_commit_tx_fee_msat);
222+
if capacity_minus_max_commitment_fee_msat < real_dust_limit_timeout_sat * 1000 {
223+
let capacity_minus_min_commitment_fee_msat = available_capacity_msat.saturating_sub(min_reserved_commit_tx_fee_msat);
224+
available_capacity_msat = cmp::min(real_dust_limit_timeout_sat * 1000 - 1, capacity_minus_min_commitment_fee_msat);
225+
} else {
226+
available_capacity_msat = capacity_minus_max_commitment_fee_msat;
227+
}
228+
} else {
229+
// If the channel is inbound (i.e. counterparty pays the fee), we need to make sure
230+
// sending a new HTLC won't reduce their balance below our reserve threshold.
231+
let real_dust_limit_success_sat = real_htlc_success_tx_fee_sat + counterparty_channel_constraints.dust_limit_satoshis;
232+
let max_reserved_commit_tx_fee_msat = remote_stats.commit_tx_fee_sat * 1000;
233+
234+
let holder_selected_chan_reserve_msat = counterparty_channel_constraints.channel_reserve_satoshis * 1000;
235+
if remote_stats.counterparty_balance_before_fee_msat.unwrap_or(0) < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat {
236+
// If another HTLC's fee would reduce the remote's balance below the reserve limit
237+
// we've selected for them, we can only send dust HTLCs.
238+
available_capacity_msat = cmp::min(available_capacity_msat, real_dust_limit_success_sat * 1000 - 1);
239+
}
240+
}
241+
242+
let mut next_outbound_htlc_minimum_msat = counterparty_channel_constraints.htlc_minimum_msat;
243+
244+
// If we get close to our maximum dust exposure, we end up in a situation where we can send
245+
// between zero and the remaining dust exposure limit remaining OR above the dust limit.
246+
// Because we cannot express this as a simple min/max, we prefer to tell the user they can
247+
// send above the dust limit (as the router can always overpay to meet the dust limit).
248+
let mut remaining_msat_below_dust_exposure_limit = None;
249+
let mut dust_exposure_dust_limit_msat = 0;
250+
251+
let dust_buffer_feerate = get_dust_buffer_feerate(feerate_per_kw);
252+
let (buffer_htlc_success_tx_fee_sat, buffer_htlc_timeout_tx_fee_sat) = second_stage_tx_fees_sat(
253+
channel_type, dust_buffer_feerate,
254+
);
255+
let buffer_dust_limit_success_sat = buffer_htlc_success_tx_fee_sat + counterparty_channel_constraints.dust_limit_satoshis;
256+
let buffer_dust_limit_timeout_sat = buffer_htlc_timeout_tx_fee_sat + holder_channel_constraints.dust_limit_satoshis;
257+
258+
if let Some(extra_htlc_dust_exposure) = remote_stats.extra_nondust_htlc_on_counterparty_tx_dust_exposure_msat {
259+
if extra_htlc_dust_exposure > max_dust_htlc_exposure_msat {
260+
// If adding an extra HTLC would put us over the dust limit in total fees, we cannot
261+
// send any non-dust HTLCs.
262+
available_capacity_msat = cmp::min(available_capacity_msat, buffer_dust_limit_success_sat * 1000);
263+
}
264+
}
265+
266+
if remote_stats.dust_exposure_msat.saturating_add(buffer_dust_limit_success_sat * 1000) > max_dust_htlc_exposure_msat.saturating_add(1) {
267+
// Note that we don't use the `counterparty_tx_dust_exposure` (with
268+
// `htlc_dust_exposure_msat`) here as it only applies to non-dust HTLCs.
269+
remaining_msat_below_dust_exposure_limit =
270+
Some(max_dust_htlc_exposure_msat.saturating_sub(remote_stats.dust_exposure_msat));
271+
dust_exposure_dust_limit_msat = cmp::max(dust_exposure_dust_limit_msat, buffer_dust_limit_success_sat * 1000);
272+
}
273+
274+
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()) {
275+
remaining_msat_below_dust_exposure_limit = Some(cmp::min(
276+
remaining_msat_below_dust_exposure_limit.unwrap_or(u64::max_value()),
277+
max_dust_htlc_exposure_msat.saturating_sub(local_stats_max_fee.dust_exposure_msat)));
278+
dust_exposure_dust_limit_msat = cmp::max(dust_exposure_dust_limit_msat, buffer_dust_limit_timeout_sat * 1000);
279+
}
280+
281+
if let Some(remaining_limit_msat) = remaining_msat_below_dust_exposure_limit {
282+
if available_capacity_msat < dust_exposure_dust_limit_msat {
283+
available_capacity_msat = cmp::min(available_capacity_msat, remaining_limit_msat);
284+
} else {
285+
next_outbound_htlc_minimum_msat = cmp::max(next_outbound_htlc_minimum_msat, dust_exposure_dust_limit_msat);
286+
}
287+
}
288+
289+
available_capacity_msat = cmp::min(available_capacity_msat,
290+
counterparty_channel_constraints.max_htlc_value_in_flight_msat - pending_htlcs.iter().filter(|htlc| htlc.outbound).map(|htlc| htlc.amount_msat).sum::<u64>());
291+
292+
if pending_htlcs.iter().filter(|htlc| htlc.outbound).count() + 1 > counterparty_channel_constraints.max_accepted_htlcs as usize {
293+
available_capacity_msat = 0;
294+
}
295+
296+
crate::ln::channel::AvailableBalances {
297+
inbound_capacity_msat: remote_stats.counterparty_balance_before_fee_msat.unwrap_or(0).saturating_sub(counterparty_channel_constraints.channel_reserve_satoshis * 1000),
298+
outbound_capacity_msat,
299+
next_outbound_htlc_limit_msat: available_capacity_msat,
300+
next_outbound_htlc_minimum_msat,
301+
}
302+
}
155303
fn get_next_commitment_stats(
156304
&self, local: bool, is_outbound_from_holder: bool, channel_value_satoshis: u64,
157305
value_to_holder_msat: u64, next_commitment_htlcs: &[HTLCAmountDirection],

0 commit comments

Comments
 (0)