Use multiplier in dust exposure threshold calculation
[rust-lightning] / lightning / src / ln / functional_tests.rs
index cfef6adb24550843c4ac2bd4e7bd9c1e537b819d..271ff541a84981733090b30600956886c2845d40 100644 (file)
@@ -9515,7 +9515,7 @@ enum ExposureEvent {
        AtUpdateFeeOutbound,
 }
 
-fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_event: ExposureEvent, on_holder_tx: bool) {
+fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_event: ExposureEvent, on_holder_tx: bool, multiplier_dust_limit: bool) {
        // Test that we properly reject dust HTLC violating our `max_dust_htlc_exposure_msat`
        // policy.
        //
@@ -9530,7 +9530,12 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
 
        let chanmon_cfgs = create_chanmon_cfgs(2);
        let mut config = test_default_channel_config();
-       config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FixedLimitMsat(5_000_000); // default setting value
+       config.channel_config.max_dust_htlc_exposure = if multiplier_dust_limit {
+               // Default test fee estimator rate is 253 sat/kw, so we set the multiplier to 5_000_000 / 253
+               // to get roughly the same initial value as the default setting when this test was
+               // originally written.
+               MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253)
+       } else { MaxDustHTLCExposure::FixedLimitMsat(5_000_000) }; // initial default setting value
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config), None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -9640,7 +9645,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
                                ), true, APIError::ChannelUnavailable { .. }, {});
                }
        } else if exposure_breach_event == ExposureEvent::AtHTLCReception {
-               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 });
+               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 });
                nodes[1].node.send_payment_with_route(&route, payment_hash,
                        RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
                check_added_monitors!(nodes[1], 1);
@@ -9658,13 +9663,19 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
                        // Outbound dust balance: 5200 sats
                        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 counterparty commitment tx",
-                                       dust_htlc_on_counterparty_tx_msat * (dust_htlc_on_counterparty_tx - 1) + dust_htlc_on_counterparty_tx_msat + 1,
+                                       dust_htlc_on_counterparty_tx_msat * (dust_htlc_on_counterparty_tx - 1) + dust_htlc_on_counterparty_tx_msat + 4,
                                        max_dust_htlc_exposure_msat), 1);
                }
        } else if exposure_breach_event == ExposureEvent::AtUpdateFeeOutbound {
                route.paths[0].hops.last_mut().unwrap().fee_msat = 2_500_000;
-               nodes[0].node.send_payment_with_route(&route, payment_hash,
-                       RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
+               // For the multiplier dust exposure limit, since it scales with feerate,
+               // we need to add a lot of HTLCs that will become dust at the new feerate
+               // to cross the threshold.
+               for _ in 0..20 {
+                       let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[1], Some(1_000), None);
+                       nodes[0].node.send_payment_with_route(&route, payment_hash,
+                               RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
+               }
                {
                        let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
                        *feerate_lock = *feerate_lock * 10;
@@ -9679,20 +9690,25 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
        added_monitors.clear();
 }
 
+fn do_test_max_dust_htlc_exposure_by_threshold_type(multiplier_dust_limit: bool) {
+       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, true, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, false, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, false, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, true, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, true, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, false, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, false, multiplier_dust_limit);
+       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, true, multiplier_dust_limit);
+}
+
 #[test]
 fn test_max_dust_htlc_exposure() {
-       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, true);
-       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, true);
-       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, true);
-       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, false);
-       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, false);
-       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, false);
-       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, true);
-       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, false);
-       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, true);
-       do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, false);
-       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, false);
-       do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, true);
+       do_test_max_dust_htlc_exposure_by_threshold_type(false);
+       do_test_max_dust_htlc_exposure_by_threshold_type(true);
 }
 
 #[test]