@@ -35,7 +35,7 @@ use crate::util::test_utils;
3535use crate :: util:: errors:: APIError ;
3636use crate :: util:: ser:: { Writeable , ReadableArgs } ;
3737use crate :: util:: string:: UntrustedString ;
38- use crate :: util:: config:: UserConfig ;
38+ use crate :: util:: config:: { UserConfig , MaxDustHTLCExposure } ;
3939
4040use bitcoin:: hash_types:: BlockHash ;
4141use bitcoin:: blockdata:: script:: { Builder , Script } ;
@@ -9515,7 +9515,7 @@ enum ExposureEvent {
95159515 AtUpdateFeeOutbound ,
95169516}
95179517
9518- fn do_test_max_dust_htlc_exposure ( dust_outbound_balance : bool , exposure_breach_event : ExposureEvent , on_holder_tx : bool ) {
9518+ fn do_test_max_dust_htlc_exposure ( dust_outbound_balance : bool , exposure_breach_event : ExposureEvent , on_holder_tx : bool , multiplier_dust_limit : bool ) {
95199519 // Test that we properly reject dust HTLC violating our `max_dust_htlc_exposure_msat`
95209520 // policy.
95219521 //
@@ -9530,7 +9530,12 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
95309530
95319531 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
95329532 let mut config = test_default_channel_config ( ) ;
9533- config. channel_config . max_dust_htlc_exposure_msat = 5_000_000 ; // default setting value
9533+ config. channel_config . max_dust_htlc_exposure = if multiplier_dust_limit {
9534+ // Default test fee estimator rate is 253 sat/kw, so we set the multiplier to 5_000_000 / 253
9535+ // to get roughly the same initial value as the default setting when this test was
9536+ // originally written.
9537+ MaxDustHTLCExposure :: FeeRateMultiplier ( 5_000_000 / 253 )
9538+ } else { MaxDustHTLCExposure :: FixedLimitMsat ( 5_000_000 ) } ; // initial default setting value
95349539 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
95359540 let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( config) , None ] ) ;
95369541 let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
@@ -9574,20 +9579,21 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
95749579 let ( mut route, payment_hash, _, payment_secret) =
95759580 get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 1 ] , 1000 ) ;
95769581
9577- let dust_buffer_feerate = {
9582+ let ( dust_buffer_feerate, max_dust_htlc_exposure_msat ) = {
95789583 let per_peer_state = nodes[ 0 ] . node . per_peer_state . read ( ) . unwrap ( ) ;
95799584 let chan_lock = per_peer_state. get ( & nodes[ 1 ] . node . get_our_node_id ( ) ) . unwrap ( ) . lock ( ) . unwrap ( ) ;
95809585 let chan = chan_lock. channel_by_id . get ( & channel_id) . unwrap ( ) ;
9581- chan. context . get_dust_buffer_feerate ( None ) as u64
9586+ ( chan. context . get_dust_buffer_feerate ( None ) as u64 ,
9587+ chan. context . get_max_dust_htlc_exposure_msat ( & LowerBoundedFeeEstimator ( nodes[ 0 ] . fee_estimator ) ) )
95829588 } ;
95839589 let dust_outbound_htlc_on_holder_tx_msat: u64 = ( dust_buffer_feerate * htlc_timeout_tx_weight ( & channel_type_features) / 1000 + open_channel. dust_limit_satoshis - 1 ) * 1000 ;
9584- let dust_outbound_htlc_on_holder_tx: u64 = config . channel_config . max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
9590+ let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
95859591
95869592 let dust_inbound_htlc_on_holder_tx_msat: u64 = ( dust_buffer_feerate * htlc_success_tx_weight ( & channel_type_features) / 1000 + open_channel. dust_limit_satoshis - 1 ) * 1000 ;
9587- let dust_inbound_htlc_on_holder_tx: u64 = config . channel_config . max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
9593+ let dust_inbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
95889594
95899595 let dust_htlc_on_counterparty_tx: u64 = 4 ;
9590- let dust_htlc_on_counterparty_tx_msat: u64 = config . channel_config . max_dust_htlc_exposure_msat / dust_htlc_on_counterparty_tx;
9596+ let dust_htlc_on_counterparty_tx_msat: u64 = max_dust_htlc_exposure_msat / dust_htlc_on_counterparty_tx;
95919597
95929598 if on_holder_tx {
95939599 if dust_outbound_balance {
@@ -9639,7 +9645,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
96399645 ) , true , APIError :: ChannelUnavailable { .. } , { } ) ;
96409646 }
96419647 } else if exposure_breach_event == ExposureEvent :: AtHTLCReception {
9642- let ( route, payment_hash, _, payment_secret) = get_route_and_payment_hash ! ( nodes[ 1 ] , nodes[ 0 ] , if on_holder_tx { dust_inbound_htlc_on_holder_tx_msat } else { dust_htlc_on_counterparty_tx_msat + 1 } ) ;
9648+ let ( route, payment_hash, _, payment_secret) = get_route_and_payment_hash ! ( nodes[ 1 ] , nodes[ 0 ] , if on_holder_tx { dust_inbound_htlc_on_holder_tx_msat } else { dust_htlc_on_counterparty_tx_msat + 4 } ) ;
96439649 nodes[ 1 ] . node . send_payment_with_route ( & route, payment_hash,
96449650 RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
96459651 check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
@@ -9652,18 +9658,24 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
96529658 // Outbound dust balance: 6399 sats
96539659 let dust_inbound_overflow = dust_inbound_htlc_on_holder_tx_msat * ( dust_inbound_htlc_on_holder_tx + 1 ) ;
96549660 let dust_outbound_overflow = dust_outbound_htlc_on_holder_tx_msat * dust_outbound_htlc_on_holder_tx + dust_inbound_htlc_on_holder_tx_msat;
9655- nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" . to_string ( ) , format ! ( "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx" , if dust_outbound_balance { dust_outbound_overflow } else { dust_inbound_overflow } , config . channel_config . max_dust_htlc_exposure_msat) , 1 ) ;
9661+ nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" . to_string ( ) , format ! ( "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx" , if dust_outbound_balance { dust_outbound_overflow } else { dust_inbound_overflow } , max_dust_htlc_exposure_msat) , 1 ) ;
96569662 } else {
96579663 // Outbound dust balance: 5200 sats
96589664 nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" . to_string ( ) ,
96599665 format ! ( "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx" ,
9660- dust_htlc_on_counterparty_tx_msat * ( dust_htlc_on_counterparty_tx - 1 ) + dust_htlc_on_counterparty_tx_msat + 1 ,
9661- config . channel_config . max_dust_htlc_exposure_msat) , 1 ) ;
9666+ dust_htlc_on_counterparty_tx_msat * ( dust_htlc_on_counterparty_tx - 1 ) + dust_htlc_on_counterparty_tx_msat + 4 ,
9667+ max_dust_htlc_exposure_msat) , 1 ) ;
96629668 }
96639669 } else if exposure_breach_event == ExposureEvent :: AtUpdateFeeOutbound {
96649670 route. paths [ 0 ] . hops . last_mut ( ) . unwrap ( ) . fee_msat = 2_500_000 ;
9665- nodes[ 0 ] . node . send_payment_with_route ( & route, payment_hash,
9666- RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
9671+ // For the multiplier dust exposure limit, since it scales with feerate,
9672+ // we need to add a lot of HTLCs that will become dust at the new feerate
9673+ // to cross the threshold.
9674+ for _ in 0 ..20 {
9675+ let ( _, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 1 ] , Some ( 1_000 ) , None ) ;
9676+ nodes[ 0 ] . node . send_payment_with_route ( & route, payment_hash,
9677+ RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
9678+ }
96679679 {
96689680 let mut feerate_lock = chanmon_cfgs[ 0 ] . fee_estimator . sat_per_kw . lock ( ) . unwrap ( ) ;
96699681 * feerate_lock = * feerate_lock * 10 ;
@@ -9678,20 +9690,25 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
96789690 added_monitors. clear ( ) ;
96799691}
96809692
9693+ fn do_test_max_dust_htlc_exposure_by_threshold_type ( multiplier_dust_limit : bool ) {
9694+ do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCForward , true , multiplier_dust_limit) ;
9695+ do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCForward , true , multiplier_dust_limit) ;
9696+ do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCReception , true , multiplier_dust_limit) ;
9697+ do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCReception , false , multiplier_dust_limit) ;
9698+ do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCForward , false , multiplier_dust_limit) ;
9699+ do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCReception , false , multiplier_dust_limit) ;
9700+ do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCReception , true , multiplier_dust_limit) ;
9701+ do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCForward , false , multiplier_dust_limit) ;
9702+ do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtUpdateFeeOutbound , true , multiplier_dust_limit) ;
9703+ do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtUpdateFeeOutbound , false , multiplier_dust_limit) ;
9704+ do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtUpdateFeeOutbound , false , multiplier_dust_limit) ;
9705+ do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtUpdateFeeOutbound , true , multiplier_dust_limit) ;
9706+ }
9707+
96819708#[ test]
96829709fn test_max_dust_htlc_exposure ( ) {
9683- do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCForward , true ) ;
9684- do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCForward , true ) ;
9685- do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCReception , true ) ;
9686- do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCReception , false ) ;
9687- do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCForward , false ) ;
9688- do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCReception , false ) ;
9689- do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtHTLCReception , true ) ;
9690- do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtHTLCForward , false ) ;
9691- do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtUpdateFeeOutbound , true ) ;
9692- do_test_max_dust_htlc_exposure ( true , ExposureEvent :: AtUpdateFeeOutbound , false ) ;
9693- do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtUpdateFeeOutbound , false ) ;
9694- do_test_max_dust_htlc_exposure ( false , ExposureEvent :: AtUpdateFeeOutbound , true ) ;
9710+ do_test_max_dust_htlc_exposure_by_threshold_type ( false ) ;
9711+ do_test_max_dust_htlc_exposure_by_threshold_type ( true ) ;
96959712}
96969713
96979714#[ test]
0 commit comments