@@ -2446,24 +2446,56 @@ where
24462446 /// Doesn't bother handling the
24472447 /// if-we-removed-it-already-but-haven't-fully-resolved-they-can-still-send-an-inbound-HTLC
24482448 /// corner case properly.
2449- pub fn get_available_balances <F: FeeEstimator>(
2449+ fn get_available_balances_internal <F: FeeEstimator>(
24502450 &self, fee_estimator: &LowerBoundedFeeEstimator<F>,
2451- ) -> AvailableBalances {
2451+ include_counterparty_unknown_htlcs: bool,
2452+ ) -> Result<AvailableBalances, ()> {
24522453 match &self.phase {
24532454 ChannelPhase::Undefined => unreachable!(),
2454- ChannelPhase::Funded(chan) => chan.get_available_balances(fee_estimator),
2455+ ChannelPhase::Funded(chan) => chan
2456+ .get_available_balances_internal(fee_estimator, include_counterparty_unknown_htlcs),
24552457 ChannelPhase::UnfundedOutboundV1(chan) => {
2456- chan.context.get_available_balances_for_scope(&chan.funding, fee_estimator)
2457- },
2458- ChannelPhase::UnfundedInboundV1(chan) => {
2459- chan.context.get_available_balances_for_scope(&chan.funding, fee_estimator)
2460- },
2461- ChannelPhase::UnfundedV2(chan) => {
2462- chan.context.get_available_balances_for_scope(&chan.funding, fee_estimator)
2458+ chan.context.get_available_balances_for_scope(
2459+ &chan.funding,
2460+ fee_estimator,
2461+ include_counterparty_unknown_htlcs,
2462+ )
24632463 },
2464+ ChannelPhase::UnfundedInboundV1(chan) => chan.context.get_available_balances_for_scope(
2465+ &chan.funding,
2466+ fee_estimator,
2467+ include_counterparty_unknown_htlcs,
2468+ ),
2469+ ChannelPhase::UnfundedV2(chan) => chan.context.get_available_balances_for_scope(
2470+ &chan.funding,
2471+ fee_estimator,
2472+ include_counterparty_unknown_htlcs,
2473+ ),
24642474 }
24652475 }
24662476
2477+ #[cfg(any(test, feature = "_externalize_tests"))]
2478+ pub fn get_available_balances_with_counterparty_unknown_htlcs<F: FeeEstimator>(
2479+ &self, fee_estimator: &LowerBoundedFeeEstimator<F>,
2480+ ) -> Result<AvailableBalances, ()> {
2481+ self.get_available_balances_internal(fee_estimator, true)
2482+ }
2483+
2484+ pub fn get_available_balances<F: FeeEstimator>(
2485+ &self, fee_estimator: &LowerBoundedFeeEstimator<F>,
2486+ ) -> AvailableBalances {
2487+ let balances_result = self.get_available_balances_internal(fee_estimator, false);
2488+ balances_result.unwrap_or_else(|()| {
2489+ debug_assert!(false, "some channel balance has been overdrawn");
2490+ AvailableBalances {
2491+ inbound_capacity_msat: 0,
2492+ outbound_capacity_msat: 0,
2493+ next_outbound_htlc_limit_msat: 0,
2494+ next_outbound_htlc_minimum_msat: u64::MAX,
2495+ }
2496+ })
2497+ }
2498+
24672499 pub fn minimum_depth(&self) -> Option<u32> {
24682500 self.context().minimum_depth(self.funding())
24692501 }
@@ -5783,8 +5815,8 @@ impl<SP: SignerProvider> ChannelContext<SP> {
57835815 #[rustfmt::skip]
57845816 fn get_available_balances_for_scope<F: FeeEstimator>(
57855817 &self, funding: &FundingScope, fee_estimator: &LowerBoundedFeeEstimator<F>,
5786- ) -> AvailableBalances {
5787- let include_counterparty_unknown_htlcs = true;
5818+ include_counterparty_unknown_htlcs: bool,
5819+ ) -> Result<AvailableBalances, ()> {
57885820 let dust_exposure_limiting_feerate = self.get_dust_exposure_limiting_feerate(
57895821 &fee_estimator, funding.get_channel_type(),
57905822 );
@@ -5796,7 +5828,7 @@ impl<SP: SignerProvider> ChannelContext<SP> {
57965828 0,
57975829 self.feerate_per_kw,
57985830 dust_exposure_limiting_feerate
5799- ).map(|(remote_stats, _)| remote_stats.available_balances).unwrap() ;
5831+ ).map(|(remote_stats, _)| remote_stats.available_balances)? ;
58005832
58015833 #[cfg(debug_assertions)]
58025834 if balances.next_outbound_htlc_limit_msat >= balances.next_outbound_htlc_minimum_msat
@@ -5820,7 +5852,7 @@ impl<SP: SignerProvider> ChannelContext<SP> {
58205852 >= funding.counterparty_selected_channel_reserve_satoshis.unwrap_or(0) * 1000);
58215853 }
58225854
5823- balances
5855+ Ok( balances)
58245856 }
58255857
58265858 #[rustfmt::skip]
@@ -12487,7 +12519,13 @@ where
1248712519 return Err((LocalHTLCFailureReason::ZeroAmount, "Cannot send 0-msat HTLC".to_owned()));
1248812520 }
1248912521
12490- let available_balances = self.get_available_balances(fee_estimator);
12522+ let available_balances =
12523+ self.get_available_balances_internal(fee_estimator, true).map_err(|()| {
12524+ (
12525+ LocalHTLCFailureReason::ChannelBalanceOverdrawn,
12526+ "Channel balance overdrawn".to_owned(),
12527+ )
12528+ })?;
1249112529 if amount_msat < available_balances.next_outbound_htlc_minimum_msat {
1249212530 return Err((
1249312531 LocalHTLCFailureReason::HTLCMinimum,
@@ -12582,21 +12620,37 @@ where
1258212620 }
1258312621
1258412622 #[rustfmt::skip]
12585- pub(super) fn get_available_balances<F: FeeEstimator>(
12586- &self, fee_estimator: &LowerBoundedFeeEstimator<F>,
12587- ) -> AvailableBalances {
12588- core::iter::once(&self.funding)
12589- .chain(self.pending_funding().iter())
12590- .map(|funding| self.context.get_available_balances_for_scope(funding, fee_estimator))
12591- .reduce(|acc, e| {
12592- AvailableBalances {
12623+ pub(super) fn get_available_balances_internal<F: FeeEstimator>(
12624+ &self, fee_estimator: &LowerBoundedFeeEstimator<F>, include_counterparty_unknown_htlcs: bool,
12625+ ) -> Result<AvailableBalances, ()> {
12626+ let init = self.context.get_available_balances_for_scope(&self.funding, fee_estimator, include_counterparty_unknown_htlcs)?;
12627+ self.pending_funding().iter().try_fold(
12628+ init,
12629+ |acc, funding| {
12630+ let e = self.context.get_available_balances_for_scope(funding, fee_estimator, include_counterparty_unknown_htlcs)?;
12631+ Ok(AvailableBalances {
1259312632 inbound_capacity_msat: acc.inbound_capacity_msat.min(e.inbound_capacity_msat),
1259412633 outbound_capacity_msat: acc.outbound_capacity_msat.min(e.outbound_capacity_msat),
1259512634 next_outbound_htlc_limit_msat: acc.next_outbound_htlc_limit_msat.min(e.next_outbound_htlc_limit_msat),
1259612635 next_outbound_htlc_minimum_msat: acc.next_outbound_htlc_minimum_msat.max(e.next_outbound_htlc_minimum_msat),
12597- }
12636+ })
1259812637 })
12599- .expect("At least one FundingScope is always provided")
12638+ }
12639+
12640+ #[rustfmt::skip]
12641+ pub(super) fn get_available_balances<F: FeeEstimator>(
12642+ &self, fee_estimator: &LowerBoundedFeeEstimator<F>,
12643+ ) -> AvailableBalances {
12644+ let balances_result = self.get_available_balances_internal(fee_estimator, false);
12645+ balances_result.unwrap_or_else(|()| {
12646+ debug_assert!(false, "some channel balance has been overdrawn");
12647+ AvailableBalances {
12648+ inbound_capacity_msat: 0,
12649+ outbound_capacity_msat: 0,
12650+ next_outbound_htlc_limit_msat: 0,
12651+ next_outbound_htlc_minimum_msat: u64::MAX,
12652+ }
12653+ })
1260012654 }
1260112655
1260212656 fn build_commitment_no_status_check<L: Logger>(&mut self, logger: &L) -> ChannelMonitorUpdate {
0 commit comments