@@ -1729,10 +1729,23 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17291729 // commitment tx. `addl_htcs` is an optional parameter allowing the caller
17301730 // to add a number of additional HTLCs to the calculation. Note that dust
17311731 // HTLCs are excluded.
1732- fn next_local_commit_tx_fee_msat ( & self , addl_htlcs : usize ) -> u64 {
1732+ fn next_local_commit_tx_fee_msat ( & self , new_htlc_amount : u64 , fee_spike_buffer_htlc : Option < ( ) > ) -> u64 {
17331733 assert ! ( self . channel_outbound) ;
17341734
1735- let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) ;
1735+ let mut addl_htlcs = 1 ;
1736+ if fee_spike_buffer_htlc. is_some ( ) { addl_htlcs += 1 ; }
1737+ if new_htlc_amount / 1000 <= self . holder_dust_limit_satoshis {
1738+ addl_htlcs -= 1 ;
1739+ }
1740+
1741+ let mut their_acked_htlcs = 0 ;
1742+ for ref htlc in self . pending_inbound_htlcs . iter ( ) {
1743+ if htlc. amount_msat / 1000 <= self . holder_dust_limit_satoshis {
1744+ continue
1745+ }
1746+ their_acked_htlcs += 1 ;
1747+ }
1748+
17361749 for ref htlc in self . pending_outbound_htlcs . iter ( ) {
17371750 if htlc. amount_msat / 1000 <= self . holder_dust_limit_satoshis {
17381751 continue
@@ -1760,13 +1773,27 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17601773 // next commitment tx. `addl_htcs` is an optional parameter allowing the caller
17611774 // to add a number of additional HTLCs to the calculation. Note that dust HTLCs
17621775 // are excluded.
1763- fn next_remote_commit_tx_fee_msat ( & self , addl_htlcs : usize ) -> u64 {
1776+ fn next_remote_commit_tx_fee_msat ( & self , new_htlc_amount : u64 , fee_spike_buffer_htlc : Option < ( ) > ) -> u64 {
17641777 assert ! ( !self . channel_outbound) ;
17651778
1766- // When calculating the set of HTLCs which will be included in their next
1767- // commitment_signed, all inbound HTLCs are included (as all states imply it will be
1768- // included) and only committed outbound HTLCs, see below.
1769- let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) ;
1779+ let mut addl_htlcs = 1 ;
1780+ if fee_spike_buffer_htlc. is_some ( ) { addl_htlcs += 1 ; }
1781+ if new_htlc_amount / 1000 <= self . counterparty_dust_limit_satoshis {
1782+ addl_htlcs -= 1 ;
1783+ }
1784+
1785+ // When calculating the set of HTLCs which will be included in their next commitment_signed, all
1786+ // non-dust inbound HTLCs are included (as all states imply it will be included) and only
1787+ // committed outbound HTLCs, see below.
1788+ // let mut their_acked_htlcs = self.pending_inbound_htlcs.len();
1789+ let mut their_acked_htlcs = 0 ;
1790+ for ref htlc in self . pending_inbound_htlcs . iter ( ) {
1791+ if htlc. amount_msat / 1000 <= self . counterparty_dust_limit_satoshis {
1792+ continue
1793+ }
1794+ their_acked_htlcs += 1 ;
1795+ }
1796+
17701797 for ref htlc in self . pending_outbound_htlcs . iter ( ) {
17711798 if htlc. amount_msat / 1000 <= self . counterparty_dust_limit_satoshis {
17721799 continue
@@ -1848,8 +1875,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18481875 // Check that the remote can afford to pay for this HTLC on-chain at the current
18491876 // feerate_per_kw, while maintaining their channel reserve (as required by the spec).
18501877 let remote_commit_tx_fee_msat = if self . channel_outbound { 0 } else {
1851- // +1 for this HTLC.
1852- self . next_remote_commit_tx_fee_msat ( 1 )
1878+ self . next_remote_commit_tx_fee_msat ( msg. amount_msat , None ) // Don't include the extra fee spike buffer HTLC in calculations
18531879 } ;
18541880 if pending_remote_value_msat - msg. amount_msat < remote_commit_tx_fee_msat {
18551881 return Err ( ChannelError :: Close ( "Remote HTLC add would not leave enough to pay for fees" . to_owned ( ) ) ) ;
@@ -1862,14 +1888,15 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18621888 }
18631889
18641890 if !self . channel_outbound {
1865- // `+1` for this HTLC, `2 *` and `+1` fee spike buffer we keep for the remote. This deviates from the
1866- // spec because in the spec, the fee spike buffer requirement doesn't exist on the receiver's side,
1867- // only on the sender's.
1868- // Note that when we eventually remove support for fee updates and switch to anchor output fees,
1869- // we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep the extra +1
1870- // as we should still be able to afford adding this HTLC plus one more future HTLC, regardless of
1871- // being sensitive to fee spikes.
1872- let remote_fee_cost_incl_stuck_buffer_msat = 2 * self . next_remote_commit_tx_fee_msat ( 1 + 1 ) ;
1891+ // `2 *` and `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
1892+ // the spec because in the spec, the fee spike buffer requirement doesn't exist on the
1893+ // receiver's side, only on the sender's.
1894+ // Note that when we eventually remove support for fee updates and switch to anchor output
1895+ // fees, we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep
1896+ // the extra htlc when calculating the next remote commitment transaction fee as we should
1897+ // still be able to afford adding this HTLC plus one more future HTLC, regardless of being
1898+ // sensitive to fee spikes.
1899+ let remote_fee_cost_incl_stuck_buffer_msat = 2 * self . next_remote_commit_tx_fee_msat ( msg. amount_msat , Some ( ( ) ) ) ;
18731900 if pending_remote_value_msat - msg. amount_msat - chan_reserve_msat < remote_fee_cost_incl_stuck_buffer_msat {
18741901 // Note that if the pending_forward_status is not updated here, then it's because we're already failing
18751902 // the HTLC, i.e. its status is already set to failing.
@@ -1878,9 +1905,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18781905 }
18791906 } else {
18801907 // Check that they won't violate our local required channel reserve by adding this HTLC.
1881-
1882- // +1 for this HTLC.
1883- let local_commit_tx_fee_msat = self . next_local_commit_tx_fee_msat ( 1 ) ;
1908+ let local_commit_tx_fee_msat = self . next_local_commit_tx_fee_msat ( msg. amount_msat , None ) ;
18841909 if self . value_to_self_msat < self . counterparty_selected_channel_reserve_satoshis * 1000 + local_commit_tx_fee_msat {
18851910 return Err ( ChannelError :: Close ( "Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value" . to_owned ( ) ) ) ;
18861911 }
@@ -3738,11 +3763,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37383763
37393764 if !self . channel_outbound {
37403765 // Check that we won't violate the remote channel reserve by adding this HTLC.
3741-
37423766 let counterparty_balance_msat = self . channel_value_satoshis * 1000 - self . value_to_self_msat ;
37433767 let holder_selected_chan_reserve_msat = Channel :: < ChanSigner > :: get_holder_selected_channel_reserve_satoshis ( self . channel_value_satoshis ) ;
3744- // 1 additional HTLC corresponding to this HTLC.
3745- let counterparty_commit_tx_fee_msat = self . next_remote_commit_tx_fee_msat ( 1 ) ;
3768+ let counterparty_commit_tx_fee_msat = self . next_remote_commit_tx_fee_msat ( amount_msat, None ) ;
37463769 if counterparty_balance_msat < holder_selected_chan_reserve_msat + counterparty_commit_tx_fee_msat {
37473770 return Err ( ChannelError :: Ignore ( "Cannot send value that would put counterparty balance under holder-announced channel reserve value" . to_owned ( ) ) ) ;
37483771 }
@@ -3753,10 +3776,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37533776 return Err ( ChannelError :: Ignore ( format ! ( "Cannot send value that would overdraw remaining funds. Amount: {}, pending value to self {}" , amount_msat, pending_value_to_self_msat) ) ) ;
37543777 }
37553778
3756- // The `+1` is for the HTLC currently being added to the commitment tx and
3757- // the `2 *` and `+1` are for the fee spike buffer.
3779+ // `2 *` and extra HTLC are for the fee spike buffer.
37583780 let commit_tx_fee_msat = if self . channel_outbound {
3759- 2 * self . next_local_commit_tx_fee_msat ( 1 + 1 )
3781+ 2 * self . next_local_commit_tx_fee_msat ( amount_msat , Some ( ( ) ) )
37603782 } else { 0 } ;
37613783 if pending_value_to_self_msat - amount_msat < commit_tx_fee_msat {
37623784 return Err ( ChannelError :: Ignore ( format ! ( "Cannot send value that would not leave enough to pay for fees. Pending value to self: {}. local_commit_tx_fee {}" , pending_value_to_self_msat, commit_tx_fee_msat) ) ) ;
@@ -4587,6 +4609,73 @@ mod tests {
45874609 assert_eq ! ( open_channel_msg. feerate_per_kw, original_fee) ;
45884610 }
45894611
4612+ #[ test]
4613+ fn test_commit_tx_fees_with_dust ( ) {
4614+ // Test that when calculating the local and remote commitment transaction fees, the correct
4615+ // dust limits are used.
4616+ let feeest = TestFeeEstimator { fee_est : 15000 } ;
4617+ let secp_ctx = Secp256k1 :: new ( ) ;
4618+ let seed = [ 42 ; 32 ] ;
4619+ let network = Network :: Testnet ;
4620+ let keys_provider = test_utils:: TestKeysInterface :: new ( & seed, network) ;
4621+
4622+ // Go through the flow of opening a channel between two nodes, making sure
4623+ // they have different dust limits.
4624+
4625+ // Create Node A's channel pointing to Node B's pubkey
4626+ let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
4627+ let config = UserConfig :: default ( ) ;
4628+ let mut node_a_chan = Channel :: < EnforcingChannelKeys > :: new_outbound ( & & feeest, & & keys_provider, node_b_node_id, 10000000 , 100000 , 42 , & config) . unwrap ( ) ;
4629+
4630+ // Create Node B's channel by receiving Node A's open_channel message
4631+ // Make sure A's dust limit is as we expect.
4632+ let open_channel_msg = node_a_chan. get_open_channel ( genesis_block ( network) . header . block_hash ( ) ) ;
4633+ assert_eq ! ( open_channel_msg. dust_limit_satoshis, 1560 ) ;
4634+ let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 7 ; 32 ] ) . unwrap ( ) ) ;
4635+ let node_b_chan = Channel :: < EnforcingChannelKeys > :: new_from_req ( & & feeest, & & keys_provider, node_b_node_id, InitFeatures :: known ( ) , & open_channel_msg, 7 , & config) . unwrap ( ) ;
4636+
4637+ // Node B --> Node A: accept channel, explicitly setting B's dust limit.
4638+ let mut accept_channel_msg = node_b_chan. get_accept_channel ( ) ;
4639+ accept_channel_msg. dust_limit_satoshis = 546 ;
4640+ node_a_chan. accept_channel ( & accept_channel_msg, & config, InitFeatures :: known ( ) ) . unwrap ( ) ;
4641+
4642+ // Put some inbound and outbound HTLCs in A's channel.
4643+ node_a_chan. pending_inbound_htlcs . push ( InboundHTLCOutput {
4644+ htlc_id : 0 ,
4645+ amount_msat : 547_000 , // put an amount below A's dust amount but above B's.
4646+ payment_hash : PaymentHash ( Sha256 :: hash ( & [ 42 ; 32 ] ) . into_inner ( ) ) ,
4647+ cltv_expiry : 300000000 ,
4648+ state : InboundHTLCState :: Committed ,
4649+ } ) ;
4650+
4651+ node_a_chan. pending_outbound_htlcs . push ( OutboundHTLCOutput {
4652+ htlc_id : 1 ,
4653+ amount_msat : 548_000 , // put an amount below A's dust amount but above B's.
4654+ payment_hash : PaymentHash ( Sha256 :: hash ( & [ 43 ; 32 ] ) . into_inner ( ) ) ,
4655+ cltv_expiry : 200000000 ,
4656+ state : OutboundHTLCState :: Committed ,
4657+ source : HTLCSource :: OutboundRoute {
4658+ path : Vec :: new ( ) ,
4659+ session_priv : SecretKey :: from_slice ( & hex:: decode ( "0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ) . unwrap ( ) [ ..] ) . unwrap ( ) ,
4660+ first_hop_htlc_msat : 548 ,
4661+ }
4662+ } ) ;
4663+
4664+ // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
4665+ // the dust limit check.
4666+ let htlc_amt = 549_000 ;
4667+ let local_commit_tx_fee = node_a_chan. next_local_commit_tx_fee_msat ( htlc_amt, None ) ;
4668+ let local_commit_fee_0_htlcs = node_a_chan. commit_tx_fee_msat ( 0 ) ;
4669+ assert_eq ! ( local_commit_tx_fee, local_commit_fee_0_htlcs) ;
4670+
4671+ // Finally, make sure that when Node A calculates the remote's commitment transaction fees, all
4672+ // of the HTLCs are seen to be above the dust limit.
4673+ node_a_chan. channel_outbound = false ;
4674+ let remote_commit_fee_3_htlcs = node_a_chan. commit_tx_fee_msat ( 3 ) ;
4675+ let remote_commit_tx_fee = node_a_chan. next_remote_commit_tx_fee_msat ( htlc_amt, None ) ;
4676+ assert_eq ! ( remote_commit_tx_fee, remote_commit_fee_3_htlcs) ;
4677+ }
4678+
45904679 #[ test]
45914680 fn channel_reestablish_no_updates ( ) {
45924681 let feeest = TestFeeEstimator { fee_est : 15000 } ;
0 commit comments