Skip to content

Commit 0fadb54

Browse files
authored
Merge pull request #2436 from tnull/2023-07-improve-router-logging
Improve router logging and update documentation
2 parents d7e3320 + 1db53a9 commit 0fadb54

File tree

1 file changed

+67
-24
lines changed

1 file changed

+67
-24
lines changed

lightning/src/routing/router.rs

+67-24
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,21 @@ impl< G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref, SP: Sized, Sc: Sco
8282

8383
/// A trait defining behavior for routing a payment.
8484
pub trait Router {
85-
/// Finds a [`Route`] between `payer` and `payee` for a payment with the given values.
85+
/// Finds a [`Route`] for a payment between the given `payer` and a payee.
86+
///
87+
/// The `payee` and the payment's value are given in [`RouteParameters::payment_params`]
88+
/// and [`RouteParameters::final_value_msat`], respectively.
8689
fn find_route(
8790
&self, payer: &PublicKey, route_params: &RouteParameters,
8891
first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs
8992
) -> Result<Route, LightningError>;
90-
/// Finds a [`Route`] between `payer` and `payee` for a payment with the given values. Includes
91-
/// `PaymentHash` and `PaymentId` to be able to correlate the request with a specific payment.
93+
/// Finds a [`Route`] for a payment between the given `payer` and a payee.
94+
///
95+
/// The `payee` and the payment's value are given in [`RouteParameters::payment_params`]
96+
/// and [`RouteParameters::final_value_msat`], respectively.
97+
///
98+
/// Includes a [`PaymentHash`] and a [`PaymentId`] to be able to correlate the request with a specific
99+
/// payment.
92100
fn find_route_with_id(
93101
&self, payer: &PublicKey, route_params: &RouteParameters,
94102
first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs,
@@ -346,19 +354,17 @@ pub struct Route {
346354
/// [`BlindedTail`]s are present, then the pubkey of the last [`RouteHop`] in each path must be
347355
/// the same.
348356
pub paths: Vec<Path>,
349-
/// The `payment_params` parameter passed to [`find_route`].
350-
/// This is used by `ChannelManager` to track information which may be required for retries,
351-
/// provided back to you via [`Event::PaymentPathFailed`].
357+
/// The `payment_params` parameter passed via [`RouteParameters`] to [`find_route`].
352358
///
353-
/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
359+
/// This is used by `ChannelManager` to track information which may be required for retries.
354360
pub payment_params: Option<PaymentParameters>,
355361
}
356362

357363
impl Route {
358364
/// Returns the total amount of fees paid on this [`Route`].
359365
///
360366
/// This doesn't include any extra payment made to the recipient, which can happen in excess of
361-
/// the amount passed to [`find_route`]'s `params.final_value_msat`.
367+
/// the amount passed to [`find_route`]'s `route_params.final_value_msat`.
362368
pub fn get_total_fees(&self) -> u64 {
363369
self.paths.iter().map(|path| path.fee_msat()).sum()
364370
}
@@ -436,10 +442,7 @@ impl Readable for Route {
436442

437443
/// Parameters needed to find a [`Route`].
438444
///
439-
/// Passed to [`find_route`] and [`build_route_from_hops`], but also provided in
440-
/// [`Event::PaymentPathFailed`].
441-
///
442-
/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
445+
/// Passed to [`find_route`] and [`build_route_from_hops`].
443446
#[derive(Clone, Debug, PartialEq, Eq)]
444447
pub struct RouteParameters {
445448
/// The parameters of the failed payment path.
@@ -1330,6 +1333,14 @@ impl<'a> fmt::Display for LoggedCandidateHop<'a> {
13301333
" and blinding point ".fmt(f)?;
13311334
hint.1.blinding_point.fmt(f)
13321335
},
1336+
CandidateRouteHop::FirstHop { .. } => {
1337+
"first hop with SCID ".fmt(f)?;
1338+
self.0.short_channel_id().unwrap().fmt(f)
1339+
},
1340+
CandidateRouteHop::PrivateHop { .. } => {
1341+
"route hint with SCID ".fmt(f)?;
1342+
self.0.short_channel_id().unwrap().fmt(f)
1343+
},
13331344
_ => {
13341345
"SCID ".fmt(f)?;
13351346
self.0.short_channel_id().unwrap().fmt(f)
@@ -1375,10 +1386,12 @@ fn sort_first_hop_channels(
13751386

13761387
/// Finds a route from us (payer) to the given target node (payee).
13771388
///
1378-
/// If the payee provided features in their invoice, they should be provided via `params.payee`.
1389+
/// If the payee provided features in their invoice, they should be provided via the `payee` field
1390+
/// in the given [`RouteParameters::payment_params`].
13791391
/// Without this, MPP will only be used if the payee's features are available in the network graph.
13801392
///
1381-
/// Private routing paths between a public node and the target may be included in `params.payee`.
1393+
/// Private routing paths between a public node and the target may be included in the `payee` field
1394+
/// of [`RouteParameters::payment_params`].
13821395
///
13831396
/// If some channels aren't announced, it may be useful to fill in `first_hops` with the results
13841397
/// from [`ChannelManager::list_usable_channels`]. If it is filled in, the view of these channels
@@ -1388,15 +1401,9 @@ fn sort_first_hop_channels(
13881401
/// However, the enabled/disabled bit on such channels as well as the `htlc_minimum_msat` /
13891402
/// `htlc_maximum_msat` *are* checked as they may change based on the receiving node.
13901403
///
1391-
/// # Note
1392-
///
1393-
/// May be used to re-compute a [`Route`] when handling a [`Event::PaymentPathFailed`]. Any
1394-
/// adjustments to the [`NetworkGraph`] and channel scores should be made prior to calling this
1395-
/// function.
1396-
///
13971404
/// # Panics
13981405
///
1399-
/// Panics if first_hops contains channels without short_channel_ids;
1406+
/// Panics if first_hops contains channels without `short_channel_id`s;
14001407
/// [`ChannelManager::list_usable_channels`] will never include such channels.
14011408
///
14021409
/// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels
@@ -1641,6 +1648,12 @@ where L::Target: Logger {
16411648
log_trace!(logger, "Building path from {} to payer {} for value {} msat.",
16421649
LoggedPayeePubkey(payment_params.payee.node_id()), our_node_pubkey, final_value_msat);
16431650

1651+
// Remember how many candidates we ignored to allow for some logging afterwards.
1652+
let mut num_ignored_value_contribution = 0;
1653+
let mut num_ignored_path_length_limit = 0;
1654+
let mut num_ignored_cltv_delta_limit = 0;
1655+
let mut num_ignored_previously_failed = 0;
1656+
16441657
macro_rules! add_entry {
16451658
// Adds entry which goes from $src_node_id to $dest_node_id over the $candidate hop.
16461659
// $next_hops_fee_msat represents the fees paid for using all the channels *after* this one,
@@ -1715,13 +1728,37 @@ where L::Target: Logger {
17151728
let payment_failed_on_this_channel = scid_opt.map_or(false,
17161729
|scid| payment_params.previously_failed_channels.contains(&scid));
17171730

1731+
let should_log_candidate = match $candidate {
1732+
CandidateRouteHop::FirstHop { .. } => true,
1733+
CandidateRouteHop::PrivateHop { .. } => true,
1734+
CandidateRouteHop::Blinded { .. } => true,
1735+
_ => false,
1736+
};
1737+
17181738
// If HTLC minimum is larger than the amount we're going to transfer, we shouldn't
17191739
// bother considering this channel. If retrying with recommended_value_msat may
17201740
// allow us to hit the HTLC minimum limit, set htlc_minimum_limit so that we go
17211741
// around again with a higher amount.
1722-
if !contributes_sufficient_value || exceeds_max_path_length ||
1723-
exceeds_cltv_delta_limit || payment_failed_on_this_channel {
1724-
// Path isn't useful, ignore it and move on.
1742+
if !contributes_sufficient_value {
1743+
if should_log_candidate {
1744+
log_trace!(logger, "Ignoring {} due to insufficient value contribution.", LoggedCandidateHop(&$candidate));
1745+
}
1746+
num_ignored_value_contribution += 1;
1747+
} else if exceeds_max_path_length {
1748+
if should_log_candidate {
1749+
log_trace!(logger, "Ignoring {} due to exceeding maximum path length limit.", LoggedCandidateHop(&$candidate));
1750+
}
1751+
num_ignored_path_length_limit += 1;
1752+
} else if exceeds_cltv_delta_limit {
1753+
if should_log_candidate {
1754+
log_trace!(logger, "Ignoring {} due to exceeding CLTV delta limit.", LoggedCandidateHop(&$candidate));
1755+
}
1756+
num_ignored_cltv_delta_limit += 1;
1757+
} else if payment_failed_on_this_channel {
1758+
if should_log_candidate {
1759+
log_trace!(logger, "Ignoring {} due to a failed previous payment attempt.", LoggedCandidateHop(&$candidate));
1760+
}
1761+
num_ignored_previously_failed += 1;
17251762
} else if may_overpay_to_meet_path_minimum_msat {
17261763
hit_minimum_limit = true;
17271764
} else if over_path_minimum_msat {
@@ -2323,6 +2360,12 @@ where L::Target: Logger {
23232360
}
23242361
}
23252362

2363+
let num_ignored_total = num_ignored_value_contribution + num_ignored_path_length_limit +
2364+
num_ignored_cltv_delta_limit + num_ignored_previously_failed;
2365+
if num_ignored_total > 0 {
2366+
log_trace!(logger, "Ignored {} candidate hops due to insufficient value contribution, {} due to path length limit, {} due to CLTV delta limit, {} due to previous payment failure. Total: {} ignored candidates.", num_ignored_value_contribution, num_ignored_path_length_limit, num_ignored_cltv_delta_limit, num_ignored_previously_failed, num_ignored_total);
2367+
}
2368+
23262369
// Step (5).
23272370
if payment_paths.len() == 0 {
23282371
return Err(LightningError{err: "Failed to find a path to the given destination".to_owned(), action: ErrorAction::IgnoreError});

0 commit comments

Comments
 (0)