let outbound_payments = OutboundPayments::new();
let payment_id = PaymentId([0; 32]);
- assert!(
- outbound_payments.add_new_awaiting_invoice(payment_id, Retry::Attempts(0), None).is_ok()
- );
- assert!(outbound_payments.has_pending_payments());
-
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
.amount_msats(1000)
.build().unwrap()
.build().unwrap()
.sign(recipient_sign).unwrap();
+ assert!(outbound_payments.add_new_awaiting_invoice(
+ payment_id, Retry::Attempts(0), Some(invoice.amount_msats() / 100 + 50_000))
+ .is_ok()
+ );
+ assert!(outbound_payments.has_pending_payments());
+
router.expect_find_route(
RouteParameters::from_payment_params_and_value(
PaymentParameters::from_bolt12_invoice(&invoice),
let outbound_payments = OutboundPayments::new();
let payment_id = PaymentId([0; 32]);
- assert!(
- outbound_payments.add_new_awaiting_invoice(payment_id, Retry::Attempts(0), None).is_ok()
- );
- assert!(outbound_payments.has_pending_payments());
-
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
.amount_msats(1000)
.build().unwrap()
.build().unwrap()
.sign(recipient_sign).unwrap();
+ assert!(outbound_payments.add_new_awaiting_invoice(
+ payment_id, Retry::Attempts(0), Some(invoice.amount_msats() / 100 + 50_000))
+ .is_ok()
+ );
+ assert!(outbound_payments.has_pending_payments());
+
let route_params = RouteParameters::from_payment_params_and_value(
PaymentParameters::from_bolt12_invoice(&invoice),
invoice.amount_msats(),
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
.with_expiry_time(payment_expiry_secs as u64)
.with_bolt11_features(invoice_features).unwrap();
- let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
+ let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
+ route_params.max_total_routing_fee_msat = None;
// Configure the initial send, retry1 and retry2's paths.
let send_route = Route {
nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route));
let mut payment_params = route_params.payment_params.clone();
payment_params.previously_failed_channels.push(chan_2_id);
- nodes[0].router.expect_find_route(
- RouteParameters::from_payment_params_and_value(payment_params, amt_msat / 2),
- Ok(retry_1_route));
+
+ let mut retry_1_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat / 2);
+ retry_1_params.max_total_routing_fee_msat = None;
+ nodes[0].router.expect_find_route(retry_1_params, Ok(retry_1_route));
+
let mut payment_params = route_params.payment_params.clone();
payment_params.previously_failed_channels.push(chan_3_id);
- nodes[0].router.expect_find_route(
- RouteParameters::from_payment_params_and_value(payment_params, amt_msat / 4),
- Ok(retry_2_route));
+ let mut retry_2_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat / 4);
+ retry_2_params.max_total_routing_fee_msat = None;
+ nodes[0].router.expect_find_route(retry_2_params, Ok(retry_2_route));
// Send a payment that will partially fail on send, then partially fail on retry, then succeed.
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
.with_expiry_time(payment_expiry_secs as u64)
.with_bolt11_features(invoice_features).unwrap();
- let route_params = RouteParameters::from_payment_params_and_value(
+ let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params.clone(), amt_msat);
+ route_params.max_total_routing_fee_msat = None;
let chans = nodes[0].node.list_usable_channels();
let mut route = Route {
route.paths[1].hops[0].fee_msat = 50_000_000;
let mut pay_params = route.route_params.clone().unwrap().payment_params;
pay_params.previously_failed_channels.push(chans[1].short_channel_id.unwrap());
- nodes[0].router.expect_find_route(
- // Note that the second request here requests the amount we originally failed to send,
- // not the amount remaining on the full payment, which should be changed.
- RouteParameters::from_payment_params_and_value(pay_params, 100_000_001),
- Ok(route.clone()));
+
+ // Note that the second request here requests the amount we originally failed to send,
+ // not the amount remaining on the full payment, which should be changed.
+ let mut retry_params = RouteParameters::from_payment_params_and_value(pay_params, 100_000_001);
+ retry_params.max_total_routing_fee_msat = None;
+ nodes[0].router.expect_find_route(retry_params, Ok(route.clone()));
{
let scorer = chanmon_cfgs[0].scorer.read().unwrap();
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
.with_expiry_time(payment_expiry_secs as u64)
.with_bolt11_features(invoice_features).unwrap();
- let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
+ let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
+ route_params.max_total_routing_fee_msat = None;
let mut route = Route {
paths: vec![
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
100_000_000)),
};
+ route.route_params.as_mut().unwrap().max_total_routing_fee_msat = None;
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
let mut second_payment_params = route_params.payment_params.clone();
second_payment_params.previously_failed_channels = vec![chan_2_scid, chan_2_scid];
// On retry, we'll only return one path
route.paths.remove(1);
route.paths[0].hops[1].fee_msat = amt_msat;
- nodes[0].router.expect_find_route(
- RouteParameters::from_payment_params_and_value(second_payment_params, amt_msat),
- Ok(route.clone()));
+ let mut retry_params = RouteParameters::from_payment_params_and_value(second_payment_params, amt_msat);
+ retry_params.max_total_routing_fee_msat = None;
+ nodes[0].router.expect_find_route(retry_params, Ok(route.clone()));
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
.with_expiry_time(payment_expiry_secs as u64)
.with_bolt11_features(invoice_features).unwrap();
- let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
+ let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
+ route_params.max_total_routing_fee_msat = None;
let mut route = Route {
paths: vec![
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
100_000_000)),
};
+ route.route_params.as_mut().unwrap().max_total_routing_fee_msat = None;
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
let mut second_payment_params = route_params.payment_params.clone();
second_payment_params.previously_failed_channels = vec![chan_2_scid];
// On retry, we'll only be asked for one path (or 100k sats)
route.paths.remove(0);
- nodes[0].router.expect_find_route(
- RouteParameters::from_payment_params_and_value(second_payment_params, amt_msat / 2),
- Ok(route.clone()));
+ let mut retry_params = RouteParameters::from_payment_params_and_value(second_payment_params, amt_msat / 2);
+ retry_params.max_total_routing_fee_msat = None;
+ nodes[0].router.expect_find_route(retry_params, Ok(route.clone()));
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
/// This limit also applies to the total fees that may arise while retrying failed payment
/// paths.
///
- /// Default value: `None`
+ /// Note that values below a few sats may result in some paths being spuriously ignored.
pub max_total_routing_fee_msat: Option<u64>,
}
impl RouteParameters {
/// Constructs [`RouteParameters`] from the given [`PaymentParameters`] and a payment amount.
+ ///
+ /// [`Self::max_total_routing_fee_msat`] defaults to 1% of the payment amount + 50 sats
pub fn from_payment_params_and_value(payment_params: PaymentParameters, final_value_msat: u64) -> Self {
- Self { payment_params, final_value_msat, max_total_routing_fee_msat: None }
+ Self { payment_params, final_value_msat, max_total_routing_fee_msat: Some(final_value_msat / 100 + 50_000) }
}
}
excess_data: Vec::new()
});
- let route_params = RouteParameters::from_payment_params_and_value(
+ let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params.clone(), 60_000);
+ route_params.max_total_routing_fee_msat = Some(15_000);
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
// Overpay fees to hit htlc_minimum_msat.
{
// Now, attempt to route 90 sats, which is exactly 90 sats at the last hop, plus the
// 200% fee charged channel 13 in the 1-to-2 direction.
- let route_params = RouteParameters::from_payment_params_and_value(
+ let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params, 90_000);
+ route_params.max_total_routing_fee_msat = Some(90_000*2);
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 1);
// Now, attempt to route 90 sats, hitting the htlc_minimum on channel 4, but
// overshooting the htlc_maximum on channel 2. Thus, we should pick the (absurdly
// expensive) channels 12-13 path.
- let route_params = RouteParameters::from_payment_params_and_value(
+ let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params, 90_000);
+ route_params.max_total_routing_fee_msat = Some(90_000*2);
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 1);
// Make sure we'll error if our route hints don't have enough liquidity according to their
// htlc_maximum_msat.
- let route_params = RouteParameters::from_payment_params_and_value(
+ let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params, max_htlc_msat + 1);
+ route_params.max_total_routing_fee_msat = None;
if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id,
&route_params, &netgraph, None, Arc::clone(&logger), &scorer, &Default::default(),
&random_seed_bytes)
let payment_params = PaymentParameters::from_node_id(dest_node_id, 42)
.with_route_hints(vec![route_hint_1, route_hint_2]).unwrap()
.with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap();
- let route_params = RouteParameters::from_payment_params_and_value(
+ let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params, max_htlc_msat + 1);
+ route_params.max_total_routing_fee_msat = Some(max_htlc_msat * 2);
let route = get_route(&our_id, &route_params, &netgraph, None, Arc::clone(&logger),
&scorer, &Default::default(), &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 2);
let payment_params = PaymentParameters::blinded(blinded_hints.clone())
.with_bolt12_features(bolt12_features.clone()).unwrap();
- let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100_000);
+ let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, 100_000);
+ route_params.max_total_routing_fee_msat = Some(100_000);
let route = get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger),
&scorer, &Default::default(), &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 2);