use lightning::ln::msgs::DecodeError;
use lightning::ln::script::ShutdownScript;
use lightning::routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
-use lightning::routing::router::{get_route, Payee};
+use lightning::routing::router::{find_route, Payee, RouteParameters};
use lightning::routing::scorer::Scorer;
use lightning::util::config::UserConfig;
use lightning::util::errors::APIError;
}
},
4 => {
- let value = slice_to_be24(get_slice!(3)) as u64;
+ let final_value_msat = slice_to_be24(get_slice!(3)) as u64;
let payee = Payee::new(get_pubkey!());
- let route = match get_route(&our_id, &payee, &net_graph_msg_handler.network_graph, None, value, 42, Arc::clone(&logger), &scorer) {
+ let params = RouteParameters {
+ payee,
+ final_value_msat,
+ final_cltv_expiry_delta: 42,
+ };
+ let route = match find_route(&our_id, ¶ms, &net_graph_msg_handler.network_graph, None, Arc::clone(&logger), &scorer) {
Ok(route) => route,
Err(_) => return,
};
}
},
15 => {
- let value = slice_to_be24(get_slice!(3)) as u64;
+ let final_value_msat = slice_to_be24(get_slice!(3)) as u64;
let payee = Payee::new(get_pubkey!());
- let mut route = match get_route(&our_id, &payee, &net_graph_msg_handler.network_graph, None, value, 42, Arc::clone(&logger), &scorer) {
+ let params = RouteParameters {
+ payee,
+ final_value_msat,
+ final_cltv_expiry_delta: 42,
+ };
+ let mut route = match find_route(&our_id, ¶ms, &net_graph_msg_handler.network_graph, None, Arc::clone(&logger), &scorer) {
Ok(route) => route,
Err(_) => return,
};
use lightning::ln::channelmanager::{ChannelDetails, ChannelCounterparty};
use lightning::ln::features::InitFeatures;
use lightning::ln::msgs;
-use lightning::routing::router::{get_route, Payee, RouteHint, RouteHintHop};
+use lightning::routing::router::{find_route, Payee, RouteHint, RouteHintHop, RouteParameters};
use lightning::routing::scorer::Scorer;
use lightning::util::logger::Logger;
use lightning::util::ser::Readable;
}
let scorer = Scorer::new(0);
for target in node_pks.iter() {
- let payee = Payee::new(*target).with_route_hints(last_hops.clone());
- let _ = get_route(&our_pubkey, &payee, &net_graph,
+ let params = RouteParameters {
+ payee: Payee::new(*target).with_route_hints(last_hops.clone()),
+ final_value_msat: slice_to_be64(get_slice!(8)),
+ final_cltv_expiry_delta: slice_to_be32(get_slice!(4)),
+ };
+ let _ = find_route(&our_pubkey, ¶ms, &net_graph,
first_hops.map(|c| c.iter().collect::<Vec<_>>()).as_ref().map(|a| a.as_slice()),
- slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)), Arc::clone(&logger), &scorer);
+ Arc::clone(&logger), &scorer);
}
},
}
use lightning::ln::functional_test_utils::*;
use lightning::ln::features::InitFeatures;
use lightning::ln::msgs::ChannelMessageHandler;
- use lightning::routing::router;
+ use lightning::routing::router::{Payee, RouteParameters, find_route};
use lightning::routing::scorer::Scorer;
use lightning::util::events::MessageSendEventsProvider;
use lightning::util::test_utils;
assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
- let payee = router::Payee::new(invoice.recover_payee_pub_key())
+ let payee = Payee::new(invoice.recover_payee_pub_key())
.with_features(invoice.features().unwrap().clone())
.with_route_hints(invoice.route_hints());
- let amt_msat = invoice.amount_pico_btc().unwrap() / 10;
+ let params = RouteParameters {
+ payee,
+ final_value_msat: invoice.amount_milli_satoshis().unwrap(),
+ final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
+ };
let first_hops = nodes[0].node.list_usable_channels();
let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let logger = test_utils::TestLogger::new();
let scorer = Scorer::new(0);
- let route = router::get_route(
- &nodes[0].node.get_our_node_id(),
- &payee,
- network_graph,
- Some(&first_hops.iter().collect::<Vec<_>>()),
- amt_msat,
- invoice.min_final_cltv_expiry() as u32,
- &logger,
- &scorer,
+ let route = find_route(
+ &nodes[0].node.get_our_node_id(), ¶ms, network_graph,
+ Some(&first_hops.iter().collect::<Vec<_>>()), &logger, &scorer,
).unwrap();
let payment_event = {
use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use ln::channel::{Channel, ChannelError, ChannelUpdateStatus, UpdateFulfillCommitFetch};
use ln::features::{InitFeatures, NodeFeatures};
-use routing::router::{Payee, PaymentPathRetry, Route, RouteHop};
+use routing::router::{Payee, Route, RouteHop, RouteParameters};
use ln::msgs;
use ln::msgs::NetAddress;
use ln::onion_utils;
!payment.get().is_fulfilled()
{
let retry = if let Some(payee_data) = payee {
- Some(PaymentPathRetry {
+ Some(RouteParameters {
payee: payee_data,
final_value_msat: path_last_hop.fee_msat,
final_cltv_expiry_delta: path_last_hop.cltv_expiry_delta,
}
mem::drop(channel_state_lock);
let retry = if let Some(payee_data) = payee {
- Some(PaymentPathRetry {
+ Some(RouteParameters {
payee: payee_data.clone(),
final_value_msat: path_last_hop.fee_msat,
final_cltv_expiry_delta: path_last_hop.cltv_expiry_delta,
use core::time::Duration;
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
use ln::channelmanager::{PaymentId, PaymentSendFailure};
- use ln::features::{InitFeatures, InvoiceFeatures};
+ use ln::features::InitFeatures;
use ln::functional_test_utils::*;
use ln::msgs;
use ln::msgs::ChannelMessageHandler;
- use routing::router::{Payee, get_keysend_route, get_route};
+ use routing::router::{Payee, RouteParameters, find_route};
use routing::scorer::Scorer;
use util::errors::APIError;
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
- use util::test_utils;
#[cfg(feature = "std")]
#[test]
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
- let logger = test_utils::TestLogger::new();
let scorer = Scorer::new(0);
// To start (1), send a regular payment but don't claim it.
let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &expected_route, 100_000);
// Next, attempt a keysend payment and make sure it fails.
- let payee = Payee::new(expected_route.last().unwrap().node.get_our_node_id())
- .with_features(InvoiceFeatures::known());
- let route = get_route(&nodes[0].node.get_our_node_id(), &payee, &nodes[0].net_graph_msg_handler.network_graph, None, 100_000, TEST_FINAL_CLTV, &logger, &scorer).unwrap();
+ let params = RouteParameters {
+ payee: Payee::for_keysend(expected_route.last().unwrap().node.get_our_node_id()),
+ final_value_msat: 100_000,
+ final_cltv_expiry_delta: TEST_FINAL_CLTV,
+ };
+ let route = find_route(
+ &nodes[0].node.get_our_node_id(), ¶ms,
+ &nodes[0].net_graph_msg_handler.network_graph, None, nodes[0].logger, &scorer
+ ).unwrap();
nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
// To start (2), send a keysend payment but don't claim it.
let payment_preimage = PaymentPreimage([42; 32]);
- let route = get_route(&nodes[0].node.get_our_node_id(), &payee, &nodes[0].net_graph_msg_handler.network_graph, None, 100_000, TEST_FINAL_CLTV, &logger, &scorer).unwrap();
+ let route = find_route(
+ &nodes[0].node.get_our_node_id(), ¶ms,
+ &nodes[0].net_graph_msg_handler.network_graph, None, nodes[0].logger, &scorer
+ ).unwrap();
let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
+ let params = RouteParameters {
+ payee: Payee::for_keysend(payee_pubkey),
+ final_value_msat: 10000,
+ final_cltv_expiry_delta: 40,
+ };
let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let scorer = Scorer::new(0);
- let route = get_keysend_route(&payer_pubkey, network_graph, &payee_pubkey,
- Some(&first_hops.iter().collect::<Vec<_>>()), &vec![], 10000, 40,
- nodes[0].logger, &scorer).unwrap();
+ let route = find_route(
+ &payer_pubkey, ¶ms, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
+ nodes[0].logger, &scorer
+ ).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
let mismatch_payment_hash = PaymentHash([43; 32]);
nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
+ let params = RouteParameters {
+ payee: Payee::for_keysend(payee_pubkey),
+ final_value_msat: 10000,
+ final_cltv_expiry_delta: 40,
+ };
let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let scorer = Scorer::new(0);
- let route = get_keysend_route(&payer_pubkey, network_graph, &payee_pubkey,
- Some(&first_hops.iter().collect::<Vec<_>>()), &vec![], 10000, 40,
- nodes[0].logger, &scorer).unwrap();
+ let route = find_route(
+ &payer_pubkey, ¶ms, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
+ nodes[0].logger, &scorer
+ ).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
let test_secret = PaymentSecret([43; 32]);
/// Getting a route for a keysend payment to a private node requires providing the payee's
/// features (since they were not announced in a node announcement). However, keysend payments
/// don't have an invoice to pull the payee's features from, so this method is provided for use in
- /// [`get_keysend_route`], thus omitting the need for payers to manually construct an
- /// `InvoiceFeatures` for [`get_route`].
+ /// [`Payee::for_keysend`], thus omitting the need for payers to manually construct an
+ /// `InvoiceFeatures` for [`find_route`].
///
- /// [`get_keysend_route`]: crate::routing::router::get_keysend_route
- /// [`get_route`]: crate::routing::router::get_route
+ /// [`Payee::for_keysend`]: crate::routing::router::Payee::for_keysend
+ /// [`find_route`]: crate::routing::router::find_route
pub(crate) fn for_keysend() -> InvoiceFeatures {
InvoiceFeatures::empty().set_variable_length_onion_optional()
}
use ln::{chan_utils, onion_utils};
use ln::chan_utils::HTLC_SUCCESS_TX_WEIGHT;
use routing::network_graph::{NetworkUpdate, RoutingFees};
-use routing::router::{Payee, Route, RouteHop, RouteHint, RouteHintHop, get_route, get_keysend_route};
+use routing::router::{Payee, Route, RouteHop, RouteHint, RouteHintHop, RouteParameters, find_route, get_route};
use routing::scorer::Scorer;
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
use ln::msgs;
let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let payer_pubkey = nodes[0].node.get_our_node_id();
let payee_pubkey = nodes[1].node.get_our_node_id();
+ let params = RouteParameters {
+ payee: Payee::for_keysend(payee_pubkey),
+ final_value_msat: 10000,
+ final_cltv_expiry_delta: 40,
+ };
let scorer = Scorer::new(0);
- let route = get_keysend_route(
- &payer_pubkey, &network_graph, &payee_pubkey, None, &vec![], 10000, 40, nodes[0].logger, &scorer
- ).unwrap();
+ let route = find_route(&payer_pubkey, ¶ms, &network_graph, None, nodes[0].logger, &scorer).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(test_preimage)).unwrap();
nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
+ let params = RouteParameters {
+ payee: Payee::for_keysend(payee_pubkey),
+ final_value_msat: 10000,
+ final_cltv_expiry_delta: 40,
+ };
let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let scorer = Scorer::new(0);
- let route = get_keysend_route(
- &payer_pubkey, &network_graph, &payee_pubkey, Some(&first_hops.iter().collect::<Vec<_>>()),
- &vec![], 10000, 40, nodes[0].logger, &scorer
+ let route = find_route(
+ &payer_pubkey, ¶ms, &network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
+ nodes[0].logger, &scorer
).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
/// given path is variable, keeping the length of any path to less than 20 should currently
/// ensure it is viable.
pub paths: Vec<Vec<RouteHop>>,
- /// The `payee` parameter passed to [`get_route`].
+ /// The `payee` parameter passed to [`find_route`].
/// This is used by `ChannelManager` to track information which may be required for retries,
/// provided back to you via [`Event::PaymentPathFailed`].
///
/// Returns the total amount of fees paid on this [`Route`].
///
/// This doesn't include any extra payment made to the recipient, which can happen in excess of
- /// the amount passed to [`get_route`]'s `final_value_msat`.
+ /// the amount passed to [`find_route`]'s `params.final_value_msat`.
pub fn get_total_fees(&self) -> u64 {
// Do not count last hop of each path since that's the full value of the payment
return self.paths.iter()
}
}
-/// Parameters needed to re-compute a [`Route`] for retrying a failed payment path.
+/// Parameters needed to find a [`Route`] for paying a [`Payee`].
///
-/// Provided in [`Event::PaymentPathFailed`] and passed to [`get_retry_route`].
+/// Passed to [`find_route`] and also provided in [`Event::PaymentPathFailed`] for retrying a failed
+/// payment path.
///
/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
#[derive(Clone, Debug)]
-pub struct PaymentPathRetry {
+pub struct RouteParameters {
/// The recipient of the failed payment path.
pub payee: Payee,
pub final_cltv_expiry_delta: u32,
}
-impl_writeable_tlv_based!(PaymentPathRetry, {
+impl_writeable_tlv_based!(RouteParameters, {
(0, payee, required),
(2, final_value_msat, required),
(4, final_cltv_expiry_delta, required),
}
}
-/// Gets a keysend route from us (payer) to the given target node (payee). This is needed because
-/// keysend payments do not have an invoice from which to pull the payee's supported features, which
-/// makes it tricky to otherwise supply the `payee` parameter of `get_route`.
-pub fn get_keysend_route<L: Deref, S: routing::Score>(
- our_node_pubkey: &PublicKey, network: &NetworkGraph, payee: &PublicKey,
- first_hops: Option<&[&ChannelDetails]>, last_hops: &[&RouteHint], final_value_msat: u64,
- final_cltv_expiry_delta: u32, logger: L, scorer: &S
-) -> Result<Route, LightningError>
-where L::Target: Logger {
- let route_hints = last_hops.iter().map(|hint| (*hint).clone()).collect();
- let payee = Payee::for_keysend(*payee).with_route_hints(route_hints);
- get_route(
- our_node_pubkey, &payee, network, first_hops, final_value_msat, final_cltv_expiry_delta,
- logger, scorer
- )
-}
-
-/// Gets a route suitable for retrying a failed payment path.
+/// Finds a route from us (payer) to the given target node (payee).
+///
+/// If the payee provided features in their invoice, they should be provided via `params.payee`.
+/// Without this, MPP will only be used if the payee's features are available in the network graph.
+///
+/// Private routing paths between a public node and the target may be included in `params.payee`.
+///
+/// If some channels aren't announced, it may be useful to fill in `first_hops` with the results
+/// from [`ChannelManager::list_usable_channels`]. If it is filled in, the view of our local
+/// channels from [`NetworkGraph`] will be ignored, and only those in `first_hops` will be used.
///
-/// Used to re-compute a [`Route`] when handling a [`Event::PaymentPathFailed`]. Any adjustments to
-/// the [`NetworkGraph`] and channel scores should be made prior to calling this function.
+/// The fees on channels from us to the next hop are ignored as they are assumed to all be equal.
+/// However, the enabled/disabled bit on such channels as well as the `htlc_minimum_msat` /
+/// `htlc_maximum_msat` *are* checked as they may change based on the receiving node.
///
+/// # Note
+///
+/// May be used to re-compute a [`Route`] when handling a [`Event::PaymentPathFailed`]. Any
+/// adjustments to the [`NetworkGraph`] and channel scores should be made prior to calling this
+/// function.
+///
+/// # Panics
+///
+/// Panics if first_hops contains channels without short_channel_ids;
+/// [`ChannelManager::list_usable_channels`] will never include such channels.
+///
+/// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels
/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
-pub fn get_retry_route<L: Deref, S: routing::Score>(
- our_node_pubkey: &PublicKey, retry: &PaymentPathRetry, network: &NetworkGraph,
+pub fn find_route<L: Deref, S: routing::Score>(
+ our_node_pubkey: &PublicKey, params: &RouteParameters, network: &NetworkGraph,
first_hops: Option<&[&ChannelDetails]>, logger: L, scorer: &S
) -> Result<Route, LightningError>
where L::Target: Logger {
get_route(
- our_node_pubkey, &retry.payee, network, first_hops, retry.final_value_msat,
- retry.final_cltv_expiry_delta, logger, scorer
+ our_node_pubkey, ¶ms.payee, network, first_hops, params.final_value_msat,
+ params.final_cltv_expiry_delta, logger, scorer
)
}
-/// Gets a route from us (payer) to the given target node (payee).
-///
-/// If the payee provided features in their invoice, they should be provided via `payee`. Without
-/// this, MPP will only be used if the payee's features are available in the network graph.
-///
-/// Private routing paths between a public node and the target may be included in `payee`.
-///
-/// If some channels aren't announced, it may be useful to fill in a first_hops with the
-/// results from a local ChannelManager::list_usable_channels() call. If it is filled in, our
-/// view of our local channels (from net_graph_msg_handler) will be ignored, and only those
-/// in first_hops will be used.
-///
-/// Panics if first_hops contains channels without short_channel_ids
-/// (ChannelManager::list_usable_channels will never include such channels).
-///
-/// The fees on channels from us to next-hops are ignored (as they are assumed to all be
-/// equal), however the enabled/disabled bit on such channels as well as the
-/// htlc_minimum_msat/htlc_maximum_msat *are* checked as they may change based on the receiving node.
-pub fn get_route<L: Deref, S: routing::Score>(
+pub(crate) fn get_route<L: Deref, S: routing::Score>(
our_node_pubkey: &PublicKey, payee: &Payee, network: &NetworkGraph,
first_hops: Option<&[&ChannelDetails]>, final_value_msat: u64, final_cltv_expiry_delta: u32,
logger: L, scorer: &S
//! Utilities for scoring payment channels.
//!
-//! [`Scorer`] may be given to [`get_route`] to score payment channels during path finding when a
+//! [`Scorer`] may be given to [`find_route`] to score payment channels during path finding when a
//! custom [`routing::Score`] implementation is not needed.
//!
//! # Example
//! # extern crate secp256k1;
//! #
//! # use lightning::routing::network_graph::NetworkGraph;
-//! # use lightning::routing::router::{Payee, get_route};
+//! # use lightning::routing::router::{RouteParameters, find_route};
//! # use lightning::routing::scorer::Scorer;
//! # use lightning::util::logger::{Logger, Record};
//! # use secp256k1::key::PublicKey;
//! # impl Logger for FakeLogger {
//! # fn log(&self, record: &Record) { unimplemented!() }
//! # }
-//! # fn find_scored_route(payer: PublicKey, payee: Payee, network_graph: NetworkGraph) {
+//! # fn find_scored_route(payer: PublicKey, params: RouteParameters, network_graph: NetworkGraph) {
//! # let logger = FakeLogger {};
//! #
//! // Use the default channel penalty.
//! // Or use a custom channel penalty.
//! let scorer = Scorer::new(1_000);
//!
-//! let route = get_route(&payer, &payee, &network_graph, None, 1_000, 42, &logger, &scorer);
+//! let route = find_route(&payer, ¶ms, &network_graph, None, &logger, &scorer);
//! # }
//! ```
//!
-//! [`get_route`]: crate::routing::router::get_route
+//! [`find_route`]: crate::routing::router::find_route
use routing;
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
use routing::network_graph::NetworkUpdate;
use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
-use routing::router::{PaymentPathRetry, RouteHop};
+use routing::router::{RouteHop, RouteParameters};
use bitcoin::blockdata::script::Script;
use bitcoin::hashes::Hash;
/// If this is `Some`, then the corresponding channel should be avoided when the payment is
/// retried. May be `None` for older [`Event`] serializations.
short_channel_id: Option<u64>,
- /// Parameters needed to re-compute a [`Route`] for retrying the failed path.
+ /// Parameters needed to compute a new [`Route`] when retrying the failed payment path.
///
- /// See [`get_retry_route`] for details.
+ /// See [`find_route`] for details.
///
/// [`Route`]: crate::routing::router::Route
- /// [`get_retry_route`]: crate::routing::router::get_retry_route
- retry: Option<PaymentPathRetry>,
+ /// [`find_route`]: crate::routing::router::find_route
+ retry: Option<RouteParameters>,
#[cfg(test)]
error_code: Option<u16>,
#[cfg(test)]