@@ -9901,6 +9901,8 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
99019901 let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
99029902 open_channel.common_fields.max_htlc_value_in_flight_msat = 50_000_000;
99039903 open_channel.common_fields.max_accepted_htlcs = 60;
9904+ // --
9905+
99049906 if on_holder_tx {
99059907 open_channel.common_fields.dust_limit_satoshis = 546;
99069908 }
@@ -9935,141 +9937,148 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
99359937 let (channel_ready, channel_id) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
99369938 let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
99379939 update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
9940+ // Node A < - > Node B channel is now established
99389941
99399942 // Fetch a route in advance as we will be unable to once we're unable to send.
99409943 let (mut route, payment_hash, _, payment_secret) =
99419944 get_route_and_payment_hash!(nodes[0], nodes[1], 1000);
99429945
9946+
99439947 let (dust_buffer_feerate, max_dust_htlc_exposure_msat) = {
99449948 let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
99459949 let chan_lock = per_peer_state.get(&nodes[1].node.get_our_node_id()).unwrap().lock().unwrap();
99469950 let chan = chan_lock.channel_by_id.get(&channel_id).unwrap();
99479951 (chan.context().get_dust_buffer_feerate(None) as u64,
99489952 chan.context().get_max_dust_htlc_exposure_msat(&LowerBoundedFeeEstimator(nodes[0].fee_estimator)))
99499953 };
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();
1005210061}
1005310062
1005410063fn 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);
1005610065 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);
1006710076}
1006810077
1006910078#[test]
1007010079fn test_max_dust_htlc_exposure() {
1007110080 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);
1007310082}
1007410083
1007510084#[test]
0 commit comments