@@ -1724,63 +1724,108 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17241724 ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) * self . feerate_per_kw as u64 / 1000 * 1000
17251725 }
17261726
1727- // Get the commitment tx fee for the local (i.e our) next commitment transaction
1728- // based on the number of pending HTLCs that are on track to be in our next
1729- // commitment tx. `addl_htcs` is an optional parameter allowing the caller
1730- // to add a number of additional HTLCs to the calculation. Note that dust
1731- // HTLCs are excluded.
1732- fn next_local_commit_tx_fee_msat ( & self , addl_htlcs : usize ) -> u64 {
1727+ // Get the commitment tx fee for the local's (i.e. our) next commitment transaction based on the
1728+ // number of pending HTLCs that are on track to be in our next commitment tx, plus an additional
1729+ // HTLC if `fee_spike_buffer_htlc` is Some, plus a new HTLC given by `new_htlc_amount`. Dust HTLCs
1730+ // are excluded.
1731+ fn next_local_commit_tx_fee_msat ( & self , new_htlc_amount : u64 , locally_offered : bool , fee_spike_buffer_htlc : Option < ( ) > ) -> u64 {
17331732 assert ! ( self . channel_outbound) ;
17341733
1735- let mut their_acked_htlcs = self . pending_inbound_htlcs . len ( ) ;
1734+ let real_dust_limit_success_sat = ( self . feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
1735+ let real_dust_limit_timeout_sat = ( self . feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
1736+
1737+ let mut addl_htlcs = 0 ;
1738+ if fee_spike_buffer_htlc. is_some ( ) { addl_htlcs += 1 ; }
1739+ if locally_offered && new_htlc_amount / 1000 >= real_dust_limit_timeout_sat {
1740+ addl_htlcs += 1 ;
1741+ } else if !locally_offered && new_htlc_amount / 1000 >= real_dust_limit_success_sat {
1742+ addl_htlcs += 1 ;
1743+ }
1744+
1745+ let mut included_htlcs = 0 ;
1746+ for ref htlc in self . pending_inbound_htlcs . iter ( ) {
1747+ if htlc. amount_msat / 1000 < real_dust_limit_success_sat {
1748+ continue
1749+ }
1750+ // We include LocalRemoved HTLCs here because we may still need to broadcast a commitment
1751+ // transaction including this HTLC if it times out before they RAA.
1752+ included_htlcs += 1 ;
1753+ }
1754+
17361755 for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1737- if htlc. amount_msat / 1000 <= self . holder_dust_limit_satoshis {
1756+ if htlc. amount_msat / 1000 < real_dust_limit_timeout_sat {
17381757 continue
17391758 }
17401759 match htlc. state {
1741- OutboundHTLCState :: Committed => their_acked_htlcs += 1 ,
1742- OutboundHTLCState :: RemoteRemoved { ..} => their_acked_htlcs += 1 ,
1743- OutboundHTLCState :: LocalAnnounced { ..} => their_acked_htlcs += 1 ,
1760+ OutboundHTLCState :: LocalAnnounced { ..} => included_htlcs += 1 ,
1761+ OutboundHTLCState :: Committed => included_htlcs += 1 ,
1762+ OutboundHTLCState :: RemoteRemoved { ..} => included_htlcs += 1 ,
1763+ // We don't include AwaitingRemoteRevokeToRemove HTLCs because our next commitment
1764+ // transaction won't be generated until they send us their next RAA, which will mean
1765+ // dropping any HTLCs in this state.
17441766 _ => { } ,
17451767 }
17461768 }
17471769
17481770 for htlc in self . holding_cell_htlc_updates . iter ( ) {
17491771 match htlc {
1750- & HTLCUpdateAwaitingACK :: AddHTLC { .. } => their_acked_htlcs += 1 ,
1751- _ => { } ,
1772+ & HTLCUpdateAwaitingACK :: AddHTLC { amount_msat, .. } => {
1773+ if amount_msat / 1000 < real_dust_limit_timeout_sat {
1774+ continue
1775+ }
1776+ included_htlcs += 1
1777+ } ,
1778+ _ => { } , // Don't include claims/fails that are awaiting ack, because once we get the
1779+ // ack we're guaranteed to never include them in commitment txs anymore.
17521780 }
17531781 }
17541782
1755- self . commit_tx_fee_msat ( their_acked_htlcs + addl_htlcs)
1783+ self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
17561784 }
17571785
1758- // Get the commitment tx fee for the remote's next commitment transaction
1759- // based on the number of pending HTLCs that are on track to be in their
1760- // next commitment tx. `addl_htcs` is an optional parameter allowing the caller
1761- // to add a number of additional HTLCs to the calculation. Note that dust HTLCs
1762- // are excluded.
1763- fn next_remote_commit_tx_fee_msat ( & self , addl_htlcs : usize ) -> u64 {
1786+ // Get the commitment tx fee for the remote's next commitment transaction based on the number of
1787+ // pending HTLCs that are on track to be in their next commitment tx, plus an additional HTLC if
1788+ // `fee_spike_buffer_htlc` is Some, plus a new HTLC given by `new_htlc_amount`. Dust HTLCs are
1789+ // excluded.
1790+ fn next_remote_commit_tx_fee_msat ( & self , new_htlc_amount : u64 , locally_offered : bool , fee_spike_buffer_htlc : Option < ( ) > ) -> u64 {
17641791 assert ! ( !self . channel_outbound) ;
17651792
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 ( ) ;
1793+ let real_dust_limit_success_sat = ( self . feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
1794+ let real_dust_limit_timeout_sat = ( self . feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
1795+
1796+ let mut addl_htlcs = 0 ;
1797+ if fee_spike_buffer_htlc. is_some ( ) { addl_htlcs += 1 ; }
1798+ if locally_offered && new_htlc_amount / 1000 >= real_dust_limit_success_sat {
1799+ addl_htlcs += 1 ;
1800+ } else if !locally_offered && new_htlc_amount / 1000 >= real_dust_limit_timeout_sat {
1801+ addl_htlcs += 1 ;
1802+ }
1803+
1804+ // When calculating the set of HTLCs which will be included in their next commitment_signed, all
1805+ // non-dust inbound HTLCs are included (as all states imply it will be included) and only
1806+ // committed outbound HTLCs, see below.
1807+ let mut included_htlcs = 0 ;
1808+ for ref htlc in self . pending_inbound_htlcs . iter ( ) {
1809+ if htlc. amount_msat / 1000 <= real_dust_limit_timeout_sat {
1810+ continue
1811+ }
1812+ included_htlcs += 1 ;
1813+ }
1814+
17701815 for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1771- if htlc. amount_msat / 1000 <= self . counterparty_dust_limit_satoshis {
1816+ if htlc. amount_msat / 1000 <= real_dust_limit_success_sat {
17721817 continue
17731818 }
1774- // We only include outbound HTLCs if it will not be included in their next
1775- // commitment_signed, i.e. if they've responded to us with an RAA after announcement.
1819+ // We only include outbound HTLCs if it will not be included in their next commitment_signed,
1820+ // i.e. if they've responded to us with an RAA after announcement.
17761821 match htlc. state {
1777- OutboundHTLCState :: Committed => their_acked_htlcs += 1 ,
1778- OutboundHTLCState :: RemoteRemoved { ..} => their_acked_htlcs += 1 ,
1822+ OutboundHTLCState :: Committed => included_htlcs += 1 ,
1823+ OutboundHTLCState :: RemoteRemoved { ..} => included_htlcs += 1 ,
17791824 _ => { } ,
17801825 }
17811826 }
17821827
1783- self . commit_tx_fee_msat ( their_acked_htlcs + addl_htlcs)
1828+ self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
17841829 }
17851830
17861831 pub fn update_add_htlc < F , L : Deref > ( & mut self , msg : & msgs:: UpdateAddHTLC , mut pending_forward_status : PendingHTLCStatus , create_pending_htlc_status : F , logger : & L ) -> Result < ( ) , ChannelError >
@@ -1848,8 +1893,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18481893 // Check that the remote can afford to pay for this HTLC on-chain at the current
18491894 // feerate_per_kw, while maintaining their channel reserve (as required by the spec).
18501895 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 )
1896+ self . next_remote_commit_tx_fee_msat ( msg. amount_msat , false , None ) // Don't include the extra fee spike buffer HTLC in calculations
18531897 } ;
18541898 if pending_remote_value_msat - msg. amount_msat < remote_commit_tx_fee_msat {
18551899 return Err ( ChannelError :: Close ( "Remote HTLC add would not leave enough to pay for fees" . to_owned ( ) ) ) ;
@@ -1862,14 +1906,15 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18621906 }
18631907
18641908 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 ) ;
1909+ // `2 *` and `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
1910+ // the spec because in the spec, the fee spike buffer requirement doesn't exist on the
1911+ // receiver's side, only on the sender's.
1912+ // Note that when we eventually remove support for fee updates and switch to anchor output
1913+ // fees, we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep
1914+ // the extra htlc when calculating the next remote commitment transaction fee as we should
1915+ // still be able to afford adding this HTLC plus one more future HTLC, regardless of being
1916+ // sensitive to fee spikes.
1917+ let remote_fee_cost_incl_stuck_buffer_msat = 2 * self . next_remote_commit_tx_fee_msat ( msg. amount_msat , false , Some ( ( ) ) ) ;
18731918 if pending_remote_value_msat - msg. amount_msat - chan_reserve_msat < remote_fee_cost_incl_stuck_buffer_msat {
18741919 // Note that if the pending_forward_status is not updated here, then it's because we're already failing
18751920 // the HTLC, i.e. its status is already set to failing.
@@ -1878,9 +1923,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18781923 }
18791924 } else {
18801925 // 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 ) ;
1926+ let local_commit_tx_fee_msat = self . next_local_commit_tx_fee_msat ( msg. amount_msat , false , None ) ;
18841927 if self . value_to_self_msat < self . counterparty_selected_channel_reserve_satoshis * 1000 + local_commit_tx_fee_msat {
18851928 return Err ( ChannelError :: Close ( "Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value" . to_owned ( ) ) ) ;
18861929 }
@@ -3738,11 +3781,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37383781
37393782 if !self . channel_outbound {
37403783 // Check that we won't violate the remote channel reserve by adding this HTLC.
3741-
37423784 let counterparty_balance_msat = self . channel_value_satoshis * 1000 - self . value_to_self_msat ;
37433785 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 ) ;
3786+ let counterparty_commit_tx_fee_msat = self . next_remote_commit_tx_fee_msat ( amount_msat, true , None ) ;
37463787 if counterparty_balance_msat < holder_selected_chan_reserve_msat + counterparty_commit_tx_fee_msat {
37473788 return Err ( ChannelError :: Ignore ( "Cannot send value that would put counterparty balance under holder-announced channel reserve value" . to_owned ( ) ) ) ;
37483789 }
@@ -3753,10 +3794,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37533794 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) ) ) ;
37543795 }
37553796
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.
3797+ // `2 *` and extra HTLC are for the fee spike buffer.
37583798 let commit_tx_fee_msat = if self . channel_outbound {
3759- 2 * self . next_local_commit_tx_fee_msat ( 1 + 1 )
3799+ 2 * self . next_local_commit_tx_fee_msat ( amount_msat , true , Some ( ( ) ) )
37603800 } else { 0 } ;
37613801 if pending_value_to_self_msat - amount_msat < commit_tx_fee_msat {
37623802 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 +4627,73 @@ mod tests {
45874627 assert_eq ! ( open_channel_msg. feerate_per_kw, original_fee) ;
45884628 }
45894629
4630+ #[ test]
4631+ fn test_commit_tx_fees_with_dust ( ) {
4632+ // Test that when calculating the local and remote commitment transaction fees, the correct
4633+ // dust limits are used.
4634+ let feeest = TestFeeEstimator { fee_est : 15000 } ;
4635+ let secp_ctx = Secp256k1 :: new ( ) ;
4636+ let seed = [ 42 ; 32 ] ;
4637+ let network = Network :: Testnet ;
4638+ let keys_provider = test_utils:: TestKeysInterface :: new ( & seed, network) ;
4639+
4640+ // Go through the flow of opening a channel between two nodes, making sure
4641+ // they have different dust limits.
4642+
4643+ // Create Node A's channel pointing to Node B's pubkey
4644+ let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
4645+ let config = UserConfig :: default ( ) ;
4646+ let mut node_a_chan = Channel :: < EnforcingChannelKeys > :: new_outbound ( & & feeest, & & keys_provider, node_b_node_id, 10000000 , 100000 , 42 , & config) . unwrap ( ) ;
4647+
4648+ // Create Node B's channel by receiving Node A's open_channel message
4649+ // Make sure A's dust limit is as we expect.
4650+ let open_channel_msg = node_a_chan. get_open_channel ( genesis_block ( network) . header . block_hash ( ) ) ;
4651+ assert_eq ! ( open_channel_msg. dust_limit_satoshis, 1560 ) ;
4652+ let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 7 ; 32 ] ) . unwrap ( ) ) ;
4653+ let node_b_chan = Channel :: < EnforcingChannelKeys > :: new_from_req ( & & feeest, & & keys_provider, node_b_node_id, InitFeatures :: known ( ) , & open_channel_msg, 7 , & config) . unwrap ( ) ;
4654+
4655+ // Node B --> Node A: accept channel, explicitly setting B's dust limit.
4656+ let mut accept_channel_msg = node_b_chan. get_accept_channel ( ) ;
4657+ accept_channel_msg. dust_limit_satoshis = 546 ;
4658+ node_a_chan. accept_channel ( & accept_channel_msg, & config, InitFeatures :: known ( ) ) . unwrap ( ) ;
4659+
4660+ // Put some inbound and outbound HTLCs in A's channel.
4661+ let htlc_amount_msat = 11_092_000 ; // put an amount below A's effective dust amount but above B's.
4662+ node_a_chan. pending_inbound_htlcs . push ( InboundHTLCOutput {
4663+ htlc_id : 0 ,
4664+ amount_msat : htlc_amount_msat,
4665+ payment_hash : PaymentHash ( Sha256 :: hash ( & [ 42 ; 32 ] ) . into_inner ( ) ) ,
4666+ cltv_expiry : 300000000 ,
4667+ state : InboundHTLCState :: Committed ,
4668+ } ) ;
4669+
4670+ node_a_chan. pending_outbound_htlcs . push ( OutboundHTLCOutput {
4671+ htlc_id : 1 ,
4672+ amount_msat : htlc_amount_msat, // put an amount below A's dust amount but above B's.
4673+ payment_hash : PaymentHash ( Sha256 :: hash ( & [ 43 ; 32 ] ) . into_inner ( ) ) ,
4674+ cltv_expiry : 200000000 ,
4675+ state : OutboundHTLCState :: Committed ,
4676+ source : HTLCSource :: OutboundRoute {
4677+ path : Vec :: new ( ) ,
4678+ session_priv : SecretKey :: from_slice ( & hex:: decode ( "0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ) . unwrap ( ) [ ..] ) . unwrap ( ) ,
4679+ first_hop_htlc_msat : 548 ,
4680+ }
4681+ } ) ;
4682+
4683+ // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
4684+ // the dust limit check.
4685+ let local_commit_tx_fee = node_a_chan. next_local_commit_tx_fee_msat ( htlc_amount_msat, true , None ) ;
4686+ let local_commit_fee_0_htlcs = node_a_chan. commit_tx_fee_msat ( 0 ) ;
4687+ assert_eq ! ( local_commit_tx_fee, local_commit_fee_0_htlcs) ;
4688+
4689+ // Finally, make sure that when Node A calculates the remote's commitment transaction fees, all
4690+ // of the HTLCs are seen to be above the dust limit.
4691+ node_a_chan. channel_outbound = false ;
4692+ let remote_commit_fee_3_htlcs = node_a_chan. commit_tx_fee_msat ( 3 ) ;
4693+ let remote_commit_tx_fee = node_a_chan. next_remote_commit_tx_fee_msat ( htlc_amount_msat, true , None ) ;
4694+ assert_eq ! ( remote_commit_tx_fee, remote_commit_fee_3_htlcs) ;
4695+ }
4696+
45904697 #[ test]
45914698 fn channel_reestablish_no_updates ( ) {
45924699 let feeest = TestFeeEstimator { fee_est : 15000 } ;
0 commit comments