/// [`find_route`].
///
/// [`ScoreLookUp`]: crate::routing::scoring::ScoreLookUp
-pub struct ScorerAccountingForInFlightHtlcs<'a, SP: Sized, Sc: 'a + ScoreLookUp<ScoreParams = SP>, S: Deref<Target = Sc>> {
+pub struct ScorerAccountingForInFlightHtlcs<'a, S: Deref> where S::Target: ScoreLookUp {
scorer: S,
// Maps a channel's short channel id and its direction to the liquidity used up.
inflight_htlcs: &'a InFlightHtlcs,
}
-impl<'a, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>, S: Deref<Target = Sc>> ScorerAccountingForInFlightHtlcs<'a, SP, Sc, S> {
+impl<'a, S: Deref> ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: ScoreLookUp {
/// Initialize a new `ScorerAccountingForInFlightHtlcs`.
pub fn new(scorer: S, inflight_htlcs: &'a InFlightHtlcs) -> Self {
ScorerAccountingForInFlightHtlcs {
}
}
-#[cfg(c_bindings)]
-impl<'a, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>, S: Deref<Target = Sc>> Writeable for ScorerAccountingForInFlightHtlcs<'a, SP, Sc, S> {
- fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> { self.scorer.write(writer) }
-}
-
-impl<'a, SP: Sized, Sc: 'a + ScoreLookUp<ScoreParams = SP>, S: Deref<Target = Sc>> ScoreLookUp for ScorerAccountingForInFlightHtlcs<'a, SP, Sc, S> {
- type ScoreParams = Sc::ScoreParams;
+impl<'a, S: Deref> ScoreLookUp for ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: ScoreLookUp {
+ type ScoreParams = <S::Target as ScoreLookUp>::ScoreParams;
fn channel_penalty_msat(&self, short_channel_id: u64, source: &NodeId, target: &NodeId, usage: ChannelUsage, score_params: &Self::ScoreParams) -> u64 {
if let Some(used_liquidity) = self.inflight_htlcs.used_liquidity_msat(
source, target, short_channel_id
|info| info.features.supports_basic_mpp()))
} else { false };
- log_trace!(logger, "Searching for a route from payer {} to {} {} MPP and {} first hops {}overriding the network graph", our_node_pubkey,
- LoggedPayeePubkey(payment_params.payee.node_id()), if allow_mpp { "with" } else { "without" },
- first_hops.map(|hops| hops.len()).unwrap_or(0), if first_hops.is_some() { "" } else { "not " });
+ let max_total_routing_fee_msat = route_params.max_total_routing_fee_msat.unwrap_or(u64::max_value());
+
+ log_trace!(logger, "Searching for a route from payer {} to {} {} MPP and {} first hops {}overriding the network graph with a fee limit of {} msat",
+ our_node_pubkey, LoggedPayeePubkey(payment_params.payee.node_id()),
+ if allow_mpp { "with" } else { "without" },
+ first_hops.map(|hops| hops.len()).unwrap_or(0), if first_hops.is_some() { "" } else { "not " },
+ max_total_routing_fee_msat);
// Step (1).
// Prepare the data we'll use for payee-to-payer search by
}
// Ignore hops if augmenting the current path to them would put us over `max_total_routing_fee_msat`
- let max_total_routing_fee_msat = route_params.max_total_routing_fee_msat.unwrap_or(u64::max_value());
if total_fee_msat > max_total_routing_fee_msat {
if should_log_candidate {
log_trace!(logger, "Ignoring {} due to exceeding max total routing fee limit.", LoggedCandidateHop(&$candidate));
// Make sure we would never create a route with more paths than we allow.
debug_assert!(paths.len() <= payment_params.max_path_count.into());
- // Make sure we would never create a route whose total fees exceed max_total_routing_fee_msat.
- if let Some(max_total_routing_fee_msat) = route_params.max_total_routing_fee_msat {
- if paths.iter().map(|p| p.fee_msat()).sum::<u64>() > max_total_routing_fee_msat {
- return Err(LightningError{err: format!("Failed to find route that adheres to the maximum total fee limit of {}msat",
- max_total_routing_fee_msat), action: ErrorAction::IgnoreError});
- }
- }
-
if let Some(node_features) = payment_params.payee.node_features() {
for path in paths.iter_mut() {
path.hops.last_mut().unwrap().node_features = node_features.clone();
}
let route = Route { paths, route_params: Some(route_params.clone()) };
+
+ // Make sure we would never create a route whose total fees exceed max_total_routing_fee_msat.
+ if let Some(max_total_routing_fee_msat) = route_params.max_total_routing_fee_msat {
+ if route.get_total_fees() > max_total_routing_fee_msat {
+ return Err(LightningError{err: format!("Failed to find route that adheres to the maximum total fee limit of {}msat",
+ max_total_routing_fee_msat), action: ErrorAction::IgnoreError});
+ }
+ }
+
log_info!(logger, "Got route: {}", log_route!(route));
Ok(route)
}
inbound_scid_alias: None,
channel_value_satoshis: 0,
user_channel_id: 0,
+ balance_msat: 0,
outbound_capacity_msat,
next_outbound_htlc_limit_msat: outbound_capacity_msat,
next_outbound_htlc_minimum_msat: 0,
excess_data: Vec::new()
});
- // Now check that we'll find a path if the htlc_minimum is overrun substantially.
+ // Now check that we'll fail to find a path if we fail to find a path if the htlc_minimum
+ // is overrun. Note that the fees are actually calculated on 3*payment amount as that's
+ // what we try to find a route for, so this test only just happens to work out to exactly
+ // the fee limit.
let mut route_params = RouteParameters::from_payment_params_and_value(
payment_params.clone(), 5_000);
- // TODO: This can even overrun the fee limit set by the recipient!
route_params.max_total_routing_fee_msat = Some(9_999);
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id,
+ &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer,
+ &Default::default(), &random_seed_bytes) {
+ assert_eq!(err, "Failed to find route that adheres to the maximum total fee limit of 9999msat");
+ } else { panic!(); }
+
+ let mut route_params = RouteParameters::from_payment_params_and_value(
+ payment_params.clone(), 5_000);
+ route_params.max_total_routing_fee_msat = Some(10_000);
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.get_total_fees(), 10_000);
outbound_scid_alias: None,
channel_value_satoshis: 10_000_000_000,
user_channel_id: 0,
+ balance_msat: 10_000_000_000,
outbound_capacity_msat: 10_000_000_000,
next_outbound_htlc_minimum_msat: 0,
next_outbound_htlc_limit_msat: 10_000_000_000,