@@ -9901,6 +9901,8 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
9901
9901
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
9902
9902
open_channel.common_fields.max_htlc_value_in_flight_msat = 50_000_000;
9903
9903
open_channel.common_fields.max_accepted_htlcs = 60;
9904
+ // --
9905
+
9904
9906
if on_holder_tx {
9905
9907
open_channel.common_fields.dust_limit_satoshis = 546;
9906
9908
}
@@ -9935,141 +9937,148 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
9935
9937
let (channel_ready, channel_id) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
9936
9938
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
9937
9939
update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
9940
+ // Node A < - > Node B channel is now established
9938
9941
9939
9942
// Fetch a route in advance as we will be unable to once we're unable to send.
9940
9943
let (mut route, payment_hash, _, payment_secret) =
9941
9944
get_route_and_payment_hash!(nodes[0], nodes[1], 1000);
9942
9945
9946
+
9943
9947
let (dust_buffer_feerate, max_dust_htlc_exposure_msat) = {
9944
9948
let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
9945
9949
let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
9946
9950
let chan = chan_lock.channel_by_id.get(&channel_id).unwrap();
9947
9951
(chan.context().get_dust_buffer_feerate(None) as u64,
9948
9952
chan.context().get_max_dust_htlc_exposure_msat(&LowerBoundedFeeEstimator(nodes[0].fee_estimator)))
9949
9953
};
9950
- let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
9951
- let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
9952
-
9953
- let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
9954
- let dust_inbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
9955
-
9956
- let dust_htlc_on_counterparty_tx: u64 = 4;
9957
- let dust_htlc_on_counterparty_tx_msat: u64 = max_dust_htlc_exposure_msat / dust_htlc_on_counterparty_tx;
9958
-
9959
- if on_holder_tx {
9960
- if dust_outbound_balance {
9961
- // Outbound dust threshold: 2223 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + holder's `dust_limit_satoshis`)
9962
- // Outbound dust balance: 4372 sats
9963
- // Note, we need sent payment to be above outbound dust threshold on counterparty_tx of 2132 sats
9964
- for _ in 0..dust_outbound_htlc_on_holder_tx {
9965
- let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_outbound_htlc_on_holder_tx_msat);
9966
- nodes[0].node.send_payment_with_route(&route, payment_hash,
9967
- RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
9968
- }
9969
- } else {
9970
- // Inbound dust threshold: 2324 sats (`dust_buffer_feerate` * HTLC_SUCCESS_TX_WEIGHT / 1000 + holder's `dust_limit_satoshis`)
9971
- // Inbound dust balance: 4372 sats
9972
- // Note, we need sent payment to be above outbound dust threshold on counterparty_tx of 2031 sats
9973
- for _ in 0..dust_inbound_htlc_on_holder_tx {
9974
- route_payment(&nodes[1], &[&nodes[0]], dust_inbound_htlc_on_holder_tx_msat);
9975
- }
9976
- }
9977
- } else {
9978
- if dust_outbound_balance {
9979
- // Outbound dust threshold: 2132 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + counteparty's `dust_limit_satoshis`)
9980
- // Outbound dust balance: 5000 sats
9981
- for _ in 0..dust_htlc_on_counterparty_tx - 1 {
9982
- let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_htlc_on_counterparty_tx_msat);
9983
- nodes[0].node.send_payment_with_route(&route, payment_hash,
9984
- RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
9985
- }
9986
- } else {
9987
- // Inbound dust threshold: 2031 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + counteparty's `dust_limit_satoshis`)
9988
- // Inbound dust balance: 5000 sats
9989
- for _ in 0..dust_htlc_on_counterparty_tx - 1 {
9990
- route_payment(&nodes[1], &[&nodes[0]], dust_htlc_on_counterparty_tx_msat);
9991
- }
9992
- }
9993
- }
9994
-
9995
- if exposure_breach_event == ExposureEvent::AtHTLCForward {
9996
- route.paths[0].hops.last_mut().unwrap().fee_msat =
9997
- if on_holder_tx { dust_outbound_htlc_on_holder_tx_msat } else { dust_htlc_on_counterparty_tx_msat + 1 };
9998
- // With default dust exposure: 5000 sats
9999
- if on_holder_tx {
10000
- unwrap_send_err!(nodes[0].node.send_payment_with_route(&route, payment_hash,
10001
- RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)
10002
- ), true, APIError::ChannelUnavailable { .. }, {});
10003
- } else {
10004
- unwrap_send_err!(nodes[0].node.send_payment_with_route(&route, payment_hash,
10005
- RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)
10006
- ), true, APIError::ChannelUnavailable { .. }, {});
10007
- }
10008
- } else if exposure_breach_event == ExposureEvent::AtHTLCReception {
10009
- 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 });
10010
- nodes[1].node.send_payment_with_route(&route, payment_hash,
10011
- RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
10012
- check_added_monitors!(nodes[1], 1);
10013
- let mut events = nodes[1].node.get_and_clear_pending_msg_events();
10014
- assert_eq!(events.len(), 1);
10015
- let payment_event = SendEvent::from_event(events.remove(0));
10016
- nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]);
10017
- // With default dust exposure: 5000 sats
10018
- if on_holder_tx {
10019
- // Outbound dust balance: 6399 sats
10020
- let dust_inbound_overflow = dust_inbound_htlc_on_holder_tx_msat * (dust_inbound_htlc_on_holder_tx + 1);
10021
- let dust_outbound_overflow = dust_outbound_htlc_on_holder_tx_msat * dust_outbound_htlc_on_holder_tx + dust_inbound_htlc_on_holder_tx_msat;
10022
- nodes[0].logger.assert_log("lightning::ln::channel", 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);
10023
- } else {
10024
- // Outbound dust balance: 5200 sats
10025
- nodes[0].logger.assert_log("lightning::ln::channel",
10026
- format!("Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx",
10027
- dust_htlc_on_counterparty_tx_msat * (dust_htlc_on_counterparty_tx - 1) + dust_htlc_on_counterparty_tx_msat + 4,
10028
- max_dust_htlc_exposure_msat), 1);
10029
- }
10030
- } else if exposure_breach_event == ExposureEvent::AtUpdateFeeOutbound {
10031
- route.paths[0].hops.last_mut().unwrap().fee_msat = 2_500_000;
10032
- // For the multiplier dust exposure limit, since it scales with feerate,
10033
- // we need to add a lot of HTLCs that will become dust at the new feerate
10034
- // to cross the threshold.
10035
- for _ in 0..20 {
10036
- let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[1], Some(1_000), None);
10037
- nodes[0].node.send_payment_with_route(&route, payment_hash,
10038
- RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
10039
- }
10040
- {
10041
- let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
10042
- *feerate_lock = *feerate_lock * 10;
10043
- }
10044
- nodes[0].node.timer_tick_occurred();
10045
- check_added_monitors!(nodes[0], 1);
10046
- nodes[0].logger.assert_log_contains("lightning::ln::channel", "Cannot afford to send new feerate at 2530 without infringing max dust htlc exposure", 1);
10047
- }
10048
-
10049
- let _ = nodes[0].node.get_and_clear_pending_msg_events();
10050
- let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap();
10051
- added_monitors.clear();
9954
+ dbg!(&dust_buffer_feerate);
9955
+ dbg!(&max_dust_htlc_exposure_msat);
9956
+ assert!(false);
9957
+ // cargo watch -x 't ln::functional_tests::test_max_dust_htlc_exposure'
9958
+
9959
+ // let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
9960
+ // let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
9961
+
9962
+ // let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
9963
+ // let dust_inbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
9964
+
9965
+ // let dust_htlc_on_counterparty_tx: u64 = 4;
9966
+ // let dust_htlc_on_counterparty_tx_msat: u64 = max_dust_htlc_exposure_msat / dust_htlc_on_counterparty_tx;
9967
+
9968
+ // if on_holder_tx {
9969
+ // if dust_outbound_balance {
9970
+ // // Outbound dust threshold: 2223 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + holder's `dust_limit_satoshis`)
9971
+ // // Outbound dust balance: 4372 sats
9972
+ // // Note, we need sent payment to be above outbound dust threshold on counterparty_tx of 2132 sats
9973
+ // for _ in 0..dust_outbound_htlc_on_holder_tx {
9974
+ // let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_outbound_htlc_on_holder_tx_msat);
9975
+ // nodes[0].node.send_payment_with_route(&route, payment_hash,
9976
+ // RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
9977
+ // }
9978
+ // } else {
9979
+ // // Inbound dust threshold: 2324 sats (`dust_buffer_feerate` * HTLC_SUCCESS_TX_WEIGHT / 1000 + holder's `dust_limit_satoshis`)
9980
+ // // Inbound dust balance: 4372 sats
9981
+ // // Note, we need sent payment to be above outbound dust threshold on counterparty_tx of 2031 sats
9982
+ // for _ in 0..dust_inbound_htlc_on_holder_tx {
9983
+ // route_payment(&nodes[1], &[&nodes[0]], dust_inbound_htlc_on_holder_tx_msat);
9984
+ // }
9985
+ // }
9986
+ // } else {
9987
+ // if dust_outbound_balance {
9988
+ // // Outbound dust threshold: 2132 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + counteparty's `dust_limit_satoshis`)
9989
+ // // Outbound dust balance: 5000 sats
9990
+ // for _ in 0..dust_htlc_on_counterparty_tx - 1 {
9991
+ // let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], dust_htlc_on_counterparty_tx_msat);
9992
+ // nodes[0].node.send_payment_with_route(&route, payment_hash,
9993
+ // RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
9994
+ // }
9995
+ // } else {
9996
+ // // Inbound dust threshold: 2031 sats (`dust_buffer_feerate` * HTLC_TIMEOUT_TX_WEIGHT / 1000 + counteparty's `dust_limit_satoshis`)
9997
+ // // Inbound dust balance: 5000 sats
9998
+ // for _ in 0..dust_htlc_on_counterparty_tx - 1 {
9999
+ // route_payment(&nodes[1], &[&nodes[0]], dust_htlc_on_counterparty_tx_msat);
10000
+ // }
10001
+ // }
10002
+ // }
10003
+
10004
+ // if exposure_breach_event == ExposureEvent::AtHTLCForward {
10005
+ // route.paths[0].hops.last_mut().unwrap().fee_msat =
10006
+ // if on_holder_tx { dust_outbound_htlc_on_holder_tx_msat } else { dust_htlc_on_counterparty_tx_msat + 1 };
10007
+ // // With default dust exposure: 5000 sats
10008
+ // if on_holder_tx {
10009
+ // unwrap_send_err!(nodes[0].node.send_payment_with_route(&route, payment_hash,
10010
+ // RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)
10011
+ // ), true, APIError::ChannelUnavailable { .. }, {});
10012
+ // } else {
10013
+ // unwrap_send_err!(nodes[0].node.send_payment_with_route(&route, payment_hash,
10014
+ // RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)
10015
+ // ), true, APIError::ChannelUnavailable { .. }, {});
10016
+ // }
10017
+ // } else if exposure_breach_event == ExposureEvent::AtHTLCReception {
10018
+ // 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 });
10019
+ // nodes[1].node.send_payment_with_route(&route, payment_hash,
10020
+ // RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
10021
+ // check_added_monitors!(nodes[1], 1);
10022
+ // let mut events = nodes[1].node.get_and_clear_pending_msg_events();
10023
+ // assert_eq!(events.len(), 1);
10024
+ // let payment_event = SendEvent::from_event(events.remove(0));
10025
+ // nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]);
10026
+ // // With default dust exposure: 5000 sats
10027
+ // if on_holder_tx {
10028
+ // // Outbound dust balance: 6399 sats
10029
+ // let dust_inbound_overflow = dust_inbound_htlc_on_holder_tx_msat * (dust_inbound_htlc_on_holder_tx + 1);
10030
+ // let dust_outbound_overflow = dust_outbound_htlc_on_holder_tx_msat * dust_outbound_htlc_on_holder_tx + dust_inbound_htlc_on_holder_tx_msat;
10031
+ // nodes[0].logger.assert_log("lightning::ln::channel", 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);
10032
+ // } else {
10033
+ // // Outbound dust balance: 5200 sats
10034
+ // nodes[0].logger.assert_log("lightning::ln::channel",
10035
+ // format!("Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx",
10036
+ // dust_htlc_on_counterparty_tx_msat * (dust_htlc_on_counterparty_tx - 1) + dust_htlc_on_counterparty_tx_msat + 4,
10037
+ // max_dust_htlc_exposure_msat), 1);
10038
+ // }
10039
+ // } else if exposure_breach_event == ExposureEvent::AtUpdateFeeOutbound {
10040
+ // route.paths[0].hops.last_mut().unwrap().fee_msat = 2_500_000;
10041
+ // // For the multiplier dust exposure limit, since it scales with feerate,
10042
+ // // we need to add a lot of HTLCs that will become dust at the new feerate
10043
+ // // to cross the threshold.
10044
+ // for _ in 0..20 {
10045
+ // let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[1], Some(1_000), None);
10046
+ // nodes[0].node.send_payment_with_route(&route, payment_hash,
10047
+ // RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap();
10048
+ // }
10049
+ // {
10050
+ // let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
10051
+ // *feerate_lock = *feerate_lock * 10;
10052
+ // }
10053
+ // nodes[0].node.timer_tick_occurred();
10054
+ // check_added_monitors!(nodes[0], 1);
10055
+ // nodes[0].logger.assert_log_contains("lightning::ln::channel", "Cannot afford to send new feerate at 2530 without infringing max dust htlc exposure", 1);
10056
+ // }
10057
+
10058
+ // let _ = nodes[0].node.get_and_clear_pending_msg_events();
10059
+ // let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap();
10060
+ // added_monitors.clear();
10052
10061
}
10053
10062
10054
10063
fn do_test_max_dust_htlc_exposure_by_threshold_type(multiplier_dust_limit: bool) {
10055
- do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
10064
+ // do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
10056
10065
do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, true, multiplier_dust_limit);
10057
- do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, true, multiplier_dust_limit);
10058
- do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, false, multiplier_dust_limit);
10059
- do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
10060
- do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, false, multiplier_dust_limit);
10061
- do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, true, multiplier_dust_limit);
10062
- do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
10063
- do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, true, multiplier_dust_limit);
10064
- do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, false, multiplier_dust_limit);
10065
- do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, false, multiplier_dust_limit);
10066
- do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, true, multiplier_dust_limit);
10066
+ // do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, true, multiplier_dust_limit);
10067
+ // do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCReception, false, multiplier_dust_limit);
10068
+ // do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
10069
+ // do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, false, multiplier_dust_limit);
10070
+ // do_test_max_dust_htlc_exposure(true, ExposureEvent::AtHTLCReception, true, multiplier_dust_limit);
10071
+ // do_test_max_dust_htlc_exposure(false, ExposureEvent::AtHTLCForward, false, multiplier_dust_limit);
10072
+ // do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, true, multiplier_dust_limit);
10073
+ // do_test_max_dust_htlc_exposure(true, ExposureEvent::AtUpdateFeeOutbound, false, multiplier_dust_limit);
10074
+ // do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, false, multiplier_dust_limit);
10075
+ // do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, true, multiplier_dust_limit);
10067
10076
}
10068
10077
10069
10078
#[test]
10070
10079
fn test_max_dust_htlc_exposure() {
10071
10080
do_test_max_dust_htlc_exposure_by_threshold_type(false);
10072
- do_test_max_dust_htlc_exposure_by_threshold_type(true);
10081
+ // do_test_max_dust_htlc_exposure_by_threshold_type(true);
10073
10082
}
10074
10083
10075
10084
#[test]
0 commit comments