@@ -4453,9 +4453,11 @@ where
4453
4453
self.feerate_per_kw,
4454
4454
dust_exposure_limiting_feerate,
4455
4455
)
4456
- .expect(
4457
- "Adding an inbound HTLC should never exhaust the holder's balance before fees",
4458
- );
4456
+ .map_err(|()| {
4457
+ ChannelError::close(String::from(
4458
+ "Balance after HTLCs and anchors exhausted on local commitment",
4459
+ ))
4460
+ })?;
4459
4461
// Check that they won't violate our local required channel reserve by adding this HTLC.
4460
4462
if next_local_commitment_stats.holder_balance_before_fee_msat
4461
4463
< funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000
@@ -4492,7 +4494,11 @@ where
4492
4494
msg.feerate_per_kw,
4493
4495
dust_exposure_limiting_feerate,
4494
4496
)
4495
- .expect("Updating the fee should never exhaust the balance after HTLCs and anchors");
4497
+ .map_err(|()| {
4498
+ ChannelError::close(String::from(
4499
+ "Balance after HTLCs and anchors exhausted on local commitment",
4500
+ ))
4501
+ })?;
4496
4502
let next_remote_commitment_stats = self
4497
4503
.get_next_remote_commitment_stats(
4498
4504
funding,
@@ -4502,7 +4508,11 @@ where
4502
4508
msg.feerate_per_kw,
4503
4509
dust_exposure_limiting_feerate,
4504
4510
)
4505
- .expect("Updating the fee should never exhaust the balance after HTLCs and anchors");
4511
+ .map_err(|()| {
4512
+ ChannelError::close(String::from(
4513
+ "Balance after HTLCs and anchors exhausted on remote commitment",
4514
+ ))
4515
+ })?;
4506
4516
4507
4517
let max_dust_htlc_exposure_msat =
4508
4518
self.get_max_dust_htlc_exposure_msat(dust_exposure_limiting_feerate);
@@ -4626,16 +4636,22 @@ where
4626
4636
// Include outbound update_add_htlc's in the holding cell, and those which haven't yet been ACK'ed by
4627
4637
// the counterparty (ie. LocalAnnounced HTLCs)
4628
4638
let include_counterparty_unknown_htlcs = true;
4629
- let next_remote_commitment_stats = self
4630
- .get_next_remote_commitment_stats(
4631
- funding,
4632
- None,
4633
- include_counterparty_unknown_htlcs,
4634
- CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize,
4635
- feerate_per_kw,
4636
- dust_exposure_limiting_feerate,
4637
- )
4638
- .expect("Updating the fee should never exhaust the balance after HTLCs and anchors");
4639
+ let next_remote_commitment_stats = if let Ok(stats) = self.get_next_remote_commitment_stats(
4640
+ funding,
4641
+ None,
4642
+ include_counterparty_unknown_htlcs,
4643
+ CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize,
4644
+ feerate_per_kw,
4645
+ dust_exposure_limiting_feerate,
4646
+ ) {
4647
+ stats
4648
+ } else {
4649
+ log_debug!(
4650
+ logger,
4651
+ "Cannot afford to send new feerate due to balance after HTLCs and anchors exhausted on remote commitment",
4652
+ );
4653
+ return false;
4654
+ };
4639
4655
// Note that `stats.commit_tx_fee_sat` accounts for any HTLCs that transition from non-dust to dust
4640
4656
// under a higher feerate (in the case where HTLC-transactions pay endogenous fees).
4641
4657
if next_remote_commitment_stats.holder_balance_before_fee_msat
@@ -4660,16 +4676,22 @@ where
4660
4676
return false;
4661
4677
}
4662
4678
4663
- let next_local_commitment_stats = self
4664
- .get_next_local_commitment_stats(
4665
- funding,
4666
- None,
4667
- include_counterparty_unknown_htlcs,
4668
- CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize,
4669
- feerate_per_kw,
4670
- dust_exposure_limiting_feerate,
4671
- )
4672
- .expect("Updating the fee should never exhaust the balance after HTLCs and anchors");
4679
+ let next_local_commitment_stats = if let Ok(stats) = self.get_next_local_commitment_stats(
4680
+ funding,
4681
+ None,
4682
+ include_counterparty_unknown_htlcs,
4683
+ CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize,
4684
+ feerate_per_kw,
4685
+ dust_exposure_limiting_feerate,
4686
+ ) {
4687
+ stats
4688
+ } else {
4689
+ log_debug!(
4690
+ logger,
4691
+ "Cannot afford to send new feerate due to balance after HTLCs and anchors exhausted on local commitment",
4692
+ );
4693
+ return false;
4694
+ };
4673
4695
if next_local_commitment_stats.dust_exposure_msat > max_dust_htlc_exposure_msat {
4674
4696
log_debug!(
4675
4697
logger,
@@ -4716,7 +4738,10 @@ where
4716
4738
feerate,
4717
4739
dust_exposure_limiting_feerate,
4718
4740
)
4719
- .expect("Balances after HTLCs and anchors should never be exhausted at this point");
4741
+ .map_err(|()| {
4742
+ log_info!(logger, "Attempting to fail HTLC due to balance after HTLCs and anchors exhausted on local commitment");
4743
+ LocalHTLCFailureReason::TemporaryChannelFailure
4744
+ })?;
4720
4745
let next_remote_commitment_stats = self
4721
4746
.get_next_remote_commitment_stats(
4722
4747
funding,
@@ -4726,7 +4751,10 @@ where
4726
4751
feerate,
4727
4752
dust_exposure_limiting_feerate,
4728
4753
)
4729
- .expect("Balances after HTLCs and anchors should never be exhausted at this point");
4754
+ .map_err(|()| {
4755
+ log_info!(logger, "Attempting to fail HTLC due to balance after HTLCs and anchors exhausted on remote commitment");
4756
+ LocalHTLCFailureReason::TemporaryChannelFailure
4757
+ })?;
4730
4758
4731
4759
let max_dust_htlc_exposure_msat =
4732
4760
self.get_max_dust_htlc_exposure_msat(dust_exposure_limiting_feerate);
0 commit comments