@@ -1656,6 +1656,54 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1656
1656
cmp:: min ( self . value_to_self_msat as i64 - self . get_outbound_pending_htlc_stats ( ) . 1 as i64 , 0 ) as u64 )
1657
1657
}
1658
1658
1659
+ fn commit_tx_fee_msat ( & self , num_htlcs : u64 ) -> u64 {
1660
+ ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs * COMMITMENT_TX_WEIGHT_PER_HTLC ) * self . feerate_per_kw / 1000 * 1000
1661
+ }
1662
+
1663
+ fn htlc_count_next_local_commit_tx ( & self ) -> u64 {
1664
+ assert ! ( self . channel_outbound) ;
1665
+
1666
+ let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) as u64 ;
1667
+ for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1668
+ match htlc. state {
1669
+ OutboundHTLCState :: Committed => their_acked_htlcs +=1 ,
1670
+ OutboundHTLCState :: RemoteRemoved { ..} => their_acked_htlcs +=1 ,
1671
+ OutboundHTLCState :: LocalAnnounced { ..} => their_acked_htlcs += 1 ,
1672
+ _ => { } ,
1673
+ }
1674
+ }
1675
+
1676
+ for ref htlc in self . holding_cell_htlc_updates . iter ( ) {
1677
+ match htlc {
1678
+ & & HTLCUpdateAwaitingACK :: AddHTLC { .. } => their_acked_htlcs += 1 ,
1679
+ _ => { } ,
1680
+ }
1681
+ }
1682
+
1683
+ their_acked_htlcs
1684
+ }
1685
+
1686
+ fn htlc_count_next_remote_commit_tx ( & self ) -> u64 {
1687
+ assert ! ( !self . channel_outbound) ;
1688
+
1689
+ let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) as u64 ;
1690
+ // When calculating the set of HTLCs which will be included in their next
1691
+ // commitment_signed, all inbound HTLCs are included (as all states imply it will be
1692
+ // included) and only committed outbound HTLCs, see below.
1693
+ for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1694
+ // We only include outbound HTLCs if it will not be included in their next
1695
+ // commitment_signed, ie if they've responded to us with an RAA after announcement
1696
+ // and if the removal process hasn't been finalized.
1697
+ match htlc. state {
1698
+ OutboundHTLCState :: Committed => their_acked_htlcs +=1 ,
1699
+ OutboundHTLCState :: RemoteRemoved { ..} => their_acked_htlcs +=1 ,
1700
+ _ => { } ,
1701
+ }
1702
+ }
1703
+
1704
+ their_acked_htlcs
1705
+ }
1706
+
1659
1707
pub fn update_add_htlc ( & mut self , msg : & msgs:: UpdateAddHTLC , pending_forward_state : PendingHTLCStatus ) -> Result < ( ) , ChannelError > {
1660
1708
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | ChannelState :: RemoteShutdownSent as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
1661
1709
return Err ( ChannelError :: Close ( "Got add HTLC message when channel was not in an operational state" ) ) ;
@@ -1701,8 +1749,14 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1701
1749
removed_outbound_total_msat += htlc. amount_msat ;
1702
1750
}
1703
1751
}
1704
- if htlc_inbound_value_msat + msg. amount_msat + self . value_to_self_msat > ( self . channel_value_satoshis - Channel :: < ChanSigner > :: get_our_channel_reserve_satoshis ( self . channel_value_satoshis ) ) * 1000 + removed_outbound_total_msat {
1705
- return Err ( ChannelError :: Close ( "Remote HTLC add would put them over their reserve value" ) ) ;
1752
+
1753
+ // The + 1 is for the HTLC that is currently being added to the commitment tx.
1754
+ let remote_fee_cost_msat = if self . channel_outbound { 0 } else {
1755
+ self . commit_tx_fee_msat ( self . htlc_count_next_remote_commit_tx ( ) + 1 )
1756
+ } ;
1757
+ if htlc_inbound_value_msat + msg. amount_msat + self . value_to_self_msat + remote_fee_cost_msat
1758
+ > ( self . channel_value_satoshis - Channel :: < ChanSigner > :: get_our_channel_reserve_satoshis ( self . channel_value_satoshis ) ) * 1000 + removed_outbound_total_msat {
1759
+ return Err ( ChannelError :: Ignore ( "Remote HTLC add would put them over their reserve value" ) ) ;
1706
1760
}
1707
1761
if self . next_remote_htlc_id != msg. htlc_id {
1708
1762
return Err ( ChannelError :: Close ( "Remote skipped HTLC ID" ) ) ;
@@ -3534,9 +3588,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3534
3588
return Err ( ChannelError :: Ignore ( "Cannot send value that would put us over the max HTLC value in flight our peer will accept" ) ) ;
3535
3589
}
3536
3590
3591
+ // Add additional reserve that avoids stuck channels in the case of fee spikes.
3592
+
3593
+ // The +1 is for the HTLC currently being added to the commitment tx and
3594
+ // the +2 is for the fee spike reserve.
3595
+ let local_fee_cost_msat = if self . channel_outbound {
3596
+ self . commit_tx_fee_msat ( self . htlc_count_next_local_commit_tx ( ) + 1 + 2 )
3597
+ } else { 0 } ;
3598
+
3537
3599
// Check self.their_channel_reserve_satoshis (the amount we must keep as
3538
3600
// reserve for them to have something to claim if we misbehave)
3539
- if self . value_to_self_msat < self . their_channel_reserve_satoshis * 1000 + amount_msat + htlc_outbound_value_msat {
3601
+ if self . value_to_self_msat < self . their_channel_reserve_satoshis * 1000 + amount_msat + htlc_outbound_value_msat + local_fee_cost_msat {
3540
3602
return Err ( ChannelError :: Ignore ( "Cannot send value that would put us over their reserve value" ) ) ;
3541
3603
}
3542
3604
0 commit comments