@@ -35,7 +35,7 @@ use crate::util::test_utils;
35
35
use crate :: util:: errors:: APIError ;
36
36
use crate :: util:: ser:: { Writeable , ReadableArgs } ;
37
37
use crate :: util:: string:: UntrustedString ;
38
- use crate :: util:: config:: UserConfig ;
38
+ use crate :: util:: config:: { UserConfig , MaxDustHTLCExposure } ;
39
39
40
40
use bitcoin:: hash_types:: BlockHash ;
41
41
use bitcoin:: blockdata:: script:: { Builder , Script } ;
@@ -9515,7 +9515,7 @@ enum ExposureEvent {
9515
9515
AtUpdateFeeOutbound ,
9516
9516
}
9517
9517
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 ) {
9519
9519
// Test that we properly reject dust HTLC violating our `max_dust_htlc_exposure_msat`
9520
9520
// policy.
9521
9521
//
@@ -9530,7 +9530,12 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
9530
9530
9531
9531
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
9532
9532
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
9534
9539
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
9535
9540
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( config) , None ] ) ;
9536
9541
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
9574
9579
let ( mut route, payment_hash, _, payment_secret) =
9575
9580
get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 1 ] , 1000 ) ;
9576
9581
9577
- let dust_buffer_feerate = {
9582
+ let ( dust_buffer_feerate, max_dust_htlc_exposure_msat ) = {
9578
9583
let per_peer_state = nodes[ 0 ] . node . per_peer_state . read ( ) . unwrap ( ) ;
9579
9584
let chan_lock = per_peer_state. get ( & nodes[ 1 ] . node . get_our_node_id ( ) ) . unwrap ( ) . lock ( ) . unwrap ( ) ;
9580
9585
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 ) ) )
9582
9588
} ;
9583
9589
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;
9585
9591
9586
9592
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;
9588
9594
9589
9595
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;
9591
9597
9592
9598
if on_holder_tx {
9593
9599
if dust_outbound_balance {
@@ -9639,7 +9645,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
9639
9645
) , true , APIError :: ChannelUnavailable { .. } , { } ) ;
9640
9646
}
9641
9647
} 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 } ) ;
9643
9649
nodes[ 1 ] . node . send_payment_with_route ( & route, payment_hash,
9644
9650
RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
9645
9651
check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
@@ -9652,18 +9658,24 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
9652
9658
// Outbound dust balance: 6399 sats
9653
9659
let dust_inbound_overflow = dust_inbound_htlc_on_holder_tx_msat * ( dust_inbound_htlc_on_holder_tx + 1 ) ;
9654
9660
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 ) ;
9656
9662
} else {
9657
9663
// Outbound dust balance: 5200 sats
9658
9664
nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" . to_string ( ) ,
9659
9665
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 ) ;
9662
9668
}
9663
9669
} else if exposure_breach_event == ExposureEvent :: AtUpdateFeeOutbound {
9664
9670
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
+ }
9667
9679
{
9668
9680
let mut feerate_lock = chanmon_cfgs[ 0 ] . fee_estimator . sat_per_kw . lock ( ) . unwrap ( ) ;
9669
9681
* feerate_lock = * feerate_lock * 10 ;
@@ -9678,20 +9690,25 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
9678
9690
added_monitors. clear ( ) ;
9679
9691
}
9680
9692
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
+
9681
9708
#[ test]
9682
9709
fn 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 ) ;
9695
9712
}
9696
9713
9697
9714
#[ test]
0 commit comments