@@ -44,6 +44,7 @@ pub struct ChannelValueStat {
44
44
pub pending_inbound_htlcs_amount_msat : u64 ,
45
45
pub holding_cell_outbound_amount_msat : u64 ,
46
46
pub their_max_htlc_value_in_flight_msat : u64 , // outgoing
47
+ pub their_dust_limit_msat : u64 ,
47
48
}
48
49
49
50
enum InboundHTLCRemovalReason {
@@ -1665,6 +1666,73 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1665
1666
cmp:: min ( self . value_to_self_msat as i64 - self . get_outbound_pending_htlc_stats ( ) . 1 as i64 , 0 ) as u64 )
1666
1667
}
1667
1668
1669
+ // Get the fee cost of a commitment tx with a given number of HTLC outputs.
1670
+ // Note that num_htlcs should not include dust HTLCs.
1671
+ fn commit_tx_fee_msat ( & self , num_htlcs : usize ) -> u64 {
1672
+ // Note that we need to divide before multiplying to round properly,
1673
+ // since the lowest denomination of bitcoin on-chain is the satoshi.
1674
+ ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) * self . feerate_per_kw / 1000 * 1000
1675
+ }
1676
+
1677
+ // Get the commitment tx fee for the local (i.e our) next commitment transaction
1678
+ // based on the number of pending HTLCs that are on track to be in our next
1679
+ // commitment tx. `addl_htcs` is an optional parameter allowing the caller
1680
+ // to add a number of additional HTLCs to the calculation. Note that dust
1681
+ // HTLCs are excluded.
1682
+ fn next_local_commit_tx_fee_msat ( & self , addl_htlcs : usize ) -> u64 {
1683
+ assert ! ( self . channel_outbound) ;
1684
+
1685
+ let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) ;
1686
+ for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1687
+ if htlc. amount_msat / 1000 <= self . our_dust_limit_satoshis {
1688
+ continue
1689
+ }
1690
+ match htlc. state {
1691
+ OutboundHTLCState :: Committed => their_acked_htlcs += 1 ,
1692
+ OutboundHTLCState :: RemoteRemoved { ..} => their_acked_htlcs += 1 ,
1693
+ OutboundHTLCState :: LocalAnnounced { ..} => their_acked_htlcs += 1 ,
1694
+ _ => { } ,
1695
+ }
1696
+ }
1697
+
1698
+ for htlc in self . holding_cell_htlc_updates . iter ( ) {
1699
+ match htlc {
1700
+ & HTLCUpdateAwaitingACK :: AddHTLC { .. } => their_acked_htlcs += 1 ,
1701
+ _ => { } ,
1702
+ }
1703
+ }
1704
+
1705
+ self . commit_tx_fee_msat ( their_acked_htlcs + addl_htlcs)
1706
+ }
1707
+
1708
+ // Get the commitment tx fee for the remote's next commitment transaction
1709
+ // based on the number of pending HTLCs that are on track to be in their
1710
+ // next commitment tx. `addl_htcs` is an optional parameter allowing the caller
1711
+ // to add a number of additional HTLCs to the calculation. Note that dust HTLCs
1712
+ // are excluded.
1713
+ fn next_remote_commit_tx_fee_msat ( & self , addl_htlcs : usize ) -> u64 {
1714
+ assert ! ( !self . channel_outbound) ;
1715
+
1716
+ // When calculating the set of HTLCs which will be included in their next
1717
+ // commitment_signed, all inbound HTLCs are included (as all states imply it will be
1718
+ // included) and only committed outbound HTLCs, see below.
1719
+ let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) ;
1720
+ for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1721
+ if htlc. amount_msat / 1000 <= self . their_dust_limit_satoshis {
1722
+ continue
1723
+ }
1724
+ // We only include outbound HTLCs if it will not be included in their next
1725
+ // commitment_signed, i.e. if they've responded to us with an RAA after announcement.
1726
+ match htlc. state {
1727
+ OutboundHTLCState :: Committed => their_acked_htlcs += 1 ,
1728
+ OutboundHTLCState :: RemoteRemoved { ..} => their_acked_htlcs += 1 ,
1729
+ _ => { } ,
1730
+ }
1731
+ }
1732
+
1733
+ self . commit_tx_fee_msat ( their_acked_htlcs + addl_htlcs)
1734
+ }
1735
+
1668
1736
pub fn update_add_htlc < F > ( & mut self , msg : & msgs:: UpdateAddHTLC , mut pending_forward_state : PendingHTLCStatus , create_pending_htlc_status : F ) -> Result < ( ) , ChannelError >
1669
1737
where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus {
1670
1738
if !self . is_usable ( ) {
@@ -1721,9 +1789,48 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1721
1789
removed_outbound_total_msat += htlc. amount_msat ;
1722
1790
}
1723
1791
}
1724
- if htlc_inbound_value_msat + msg. amount_msat + self . value_to_self_msat > ( self . channel_value_satoshis - Channel :: < ChanSigner > :: get_remote_channel_reserve_satoshis ( self . channel_value_satoshis ) ) * 1000 + removed_outbound_total_msat {
1725
- return Err ( ChannelError :: Close ( "Remote HTLC add would put them under their reserve value" ) ) ;
1792
+
1793
+ let pending_value_to_self_msat =
1794
+ self . value_to_self_msat + htlc_inbound_value_msat - removed_outbound_total_msat;
1795
+ let pending_remote_value_msat =
1796
+ self . channel_value_satoshis * 1000 - pending_value_to_self_msat;
1797
+ if pending_remote_value_msat < msg. amount_msat {
1798
+ return Err ( ChannelError :: Close ( "Remote HTLC add would overdraw remaining funds" ) ) ;
1799
+ }
1800
+
1801
+ let remote_commit_tx_fee_msat = if self . channel_outbound { 0 } else {
1802
+ // +1 for this HTLC.
1803
+ self . next_remote_commit_tx_fee_msat ( 1 )
1804
+ } ;
1805
+ if pending_remote_value_msat - msg. amount_msat < remote_commit_tx_fee_msat {
1806
+ return Err ( ChannelError :: Close ( "Remote HTLC add would not leave enough to pay for fees" ) ) ;
1807
+ } ;
1808
+
1809
+ let chan_reserve_msat =
1810
+ Channel :: < ChanSigner > :: get_remote_channel_reserve_satoshis ( self . channel_value_satoshis ) * 1000 ;
1811
+ if pending_remote_value_msat - msg. amount_msat - remote_commit_tx_fee_msat < chan_reserve_msat {
1812
+ return Err ( ChannelError :: Close ( "Remote HTLC add would put them under remote reserve value" ) ) ;
1813
+ }
1814
+
1815
+ if !self . channel_outbound {
1816
+ // `+1` for this HTLC, `2 *` and `+1` fee spike buffer we keep for the remote (this deviates from the spec
1817
+ // but should help protect us from stuck channels).
1818
+ let remote_fee_cost_incl_stuck_buffer_msat = 2 * self . next_remote_commit_tx_fee_msat ( 1 + 1 ) ;
1819
+ if pending_remote_value_msat - msg. amount_msat - chan_reserve_msat < remote_fee_cost_incl_stuck_buffer_msat {
1820
+ // Note that if the pending_forward_state is not updated here, then it's because we're already failing
1821
+ // the HTLC, i.e. its status is already set to failing.
1822
+ pending_forward_state = create_pending_htlc_status ( self , pending_forward_state, 0x1000 |7 ) ;
1823
+ }
1824
+ } else {
1825
+ // Check that they won't violate our local required channel reserve by adding this HTLC.
1826
+
1827
+ // +1 for this HTLC.
1828
+ let local_commit_tx_fee_msat = self . next_local_commit_tx_fee_msat ( 1 ) ;
1829
+ if self . value_to_self_msat < self . local_channel_reserve_satoshis * 1000 + local_commit_tx_fee_msat {
1830
+ return Err ( ChannelError :: Close ( "Cannot receive value that would put us under local channel reserve value" ) ) ;
1831
+ }
1726
1832
}
1833
+
1727
1834
if self . next_remote_htlc_id != msg. htlc_id {
1728
1835
return Err ( ChannelError :: Close ( "Remote skipped HTLC ID" ) ) ;
1729
1836
}
@@ -3049,6 +3156,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3049
3156
res
3050
3157
} ,
3051
3158
their_max_htlc_value_in_flight_msat : self . their_max_htlc_value_in_flight_msat ,
3159
+ their_dust_limit_msat : self . their_dust_limit_satoshis * 1000 ,
3052
3160
}
3053
3161
}
3054
3162
@@ -3558,40 +3666,67 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3558
3666
return Err ( ChannelError :: Ignore ( "Cannot send value that would put us over the max HTLC value in flight our peer will accept" ) ) ;
3559
3667
}
3560
3668
3669
+ if !self . channel_outbound {
3670
+ // Check that we won't violate the remote channel reserve by adding this HTLC.
3671
+
3672
+ let remote_balance_msat = self . channel_value_satoshis * 1000 - self . value_to_self_msat ;
3673
+ let remote_chan_reserve_msat = Channel :: < ChanSigner > :: get_remote_channel_reserve_satoshis ( self . channel_value_satoshis ) ;
3674
+ // 1 additional HTLC corresponding to this HTLC.
3675
+ let remote_commit_tx_fee_msat = self . next_remote_commit_tx_fee_msat ( 1 ) ;
3676
+ if remote_balance_msat < remote_chan_reserve_msat + remote_commit_tx_fee_msat {
3677
+ return Err ( ChannelError :: Ignore ( "Cannot send value that would put them under remote channel reserve value" ) ) ;
3678
+ }
3679
+ }
3680
+
3681
+ let pending_value_to_self_msat = self . value_to_self_msat - htlc_outbound_value_msat;
3682
+ if pending_value_to_self_msat < amount_msat {
3683
+ return Err ( ChannelError :: Ignore ( "Cannot send value that would overdraw remaining funds" ) ) ;
3684
+ }
3685
+
3686
+ // The `+1` is for the HTLC currently being added to the commitment tx and
3687
+ // the `2 *` and `+1` are for the fee spike buffer.
3688
+ let local_commit_tx_fee_msat = if self . channel_outbound {
3689
+ 2 * self . next_local_commit_tx_fee_msat ( 1 + 1 )
3690
+ } else { 0 } ;
3691
+ if pending_value_to_self_msat - amount_msat < local_commit_tx_fee_msat {
3692
+ return Err ( ChannelError :: Ignore ( "Cannot send value that would not leave enough to pay for fees" ) ) ;
3693
+ }
3694
+
3561
3695
// Check self.local_channel_reserve_satoshis (the amount we must keep as
3562
3696
// reserve for the remote to have something to claim if we misbehave)
3563
- if self . value_to_self_msat < self . local_channel_reserve_satoshis * 1000 + amount_msat + htlc_outbound_value_msat {
3697
+ let chan_reserve_msat = self . local_channel_reserve_satoshis * 1000 ;
3698
+ if pending_value_to_self_msat - amount_msat - local_commit_tx_fee_msat < chan_reserve_msat {
3564
3699
return Err ( ChannelError :: Ignore ( "Cannot send value that would put us under local channel reserve value" ) ) ;
3565
3700
}
3566
3701
3567
3702
// Now update local state:
3568
3703
if ( self . channel_state & ( ChannelState :: AwaitingRemoteRevoke as u32 ) ) == ( ChannelState :: AwaitingRemoteRevoke as u32 ) {
3569
3704
self . holding_cell_htlc_updates . push ( HTLCUpdateAwaitingACK :: AddHTLC {
3570
- amount_msat : amount_msat ,
3571
- payment_hash : payment_hash ,
3572
- cltv_expiry : cltv_expiry ,
3705
+ amount_msat,
3706
+ payment_hash,
3707
+ cltv_expiry,
3573
3708
source,
3574
- onion_routing_packet : onion_routing_packet ,
3709
+ onion_routing_packet,
3575
3710
} ) ;
3576
3711
return Ok ( None ) ;
3577
3712
}
3578
3713
3579
3714
self . pending_outbound_htlcs . push ( OutboundHTLCOutput {
3580
3715
htlc_id : self . next_local_htlc_id ,
3581
- amount_msat : amount_msat ,
3716
+ amount_msat,
3582
3717
payment_hash : payment_hash. clone ( ) ,
3583
- cltv_expiry : cltv_expiry ,
3718
+ cltv_expiry,
3584
3719
state : OutboundHTLCState :: LocalAnnounced ( Box :: new ( onion_routing_packet. clone ( ) ) ) ,
3585
3720
source,
3586
3721
} ) ;
3587
3722
3588
3723
let res = msgs:: UpdateAddHTLC {
3589
3724
channel_id : self . channel_id ,
3590
3725
htlc_id : self . next_local_htlc_id ,
3591
- amount_msat : amount_msat ,
3592
- payment_hash : payment_hash ,
3593
- cltv_expiry : cltv_expiry ,
3594
- onion_routing_packet : onion_routing_packet ,
3726
+ amount_msat,
3727
+ payment_hash,
3728
+ cltv_expiry,
3729
+ onion_routing_packet,
3595
3730
} ;
3596
3731
self . next_local_htlc_id += 1 ;
3597
3732
0 commit comments