X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=08fe95d2305293e7440a04bc407a4110b87c3901;hb=c60543c0ed9f1c469fb8b1836ef7796c696642f3;hp=c53e46157d5dc74941bb0dee94886a06f3d5f83f;hpb=bb62420b0f020d539944c8df8799b65a93f7cf7f;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index c53e4615..08fe95d2 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -117,8 +117,8 @@ impl Readable for Route { } /// A channel descriptor which provides a last-hop route to get_route -#[derive(Clone)] -pub struct RouteHint { +#[derive(Eq, PartialEq, Debug, Clone)] +pub struct RouteHintHop { /// The node_id of the non-target end of the route pub src_node_id: PublicKey, /// The short_channel_id of this channel @@ -176,7 +176,7 @@ struct DummyDirectionalChannelInfo { /// These fee values are useful to choose hops as we traverse the graph "payee-to-payer". #[derive(Clone)] struct PathBuildingHop<'a> { - // The RouteHint fields which will eventually be used if this hop is used in a final Route. + // The RouteHintHop fields which will eventually be used if this hop is used in a final Route. // Note that node_features is calculated separately after our initial graph walk. pubkey: PublicKey, short_channel_id: u64, @@ -249,14 +249,12 @@ impl<'a> PaymentPath<'a> { // If the amount transferred by the path is updated, the fees should be adjusted. Any other way // to change fees may result in an inconsistency. // - // Sometimes we call this function right after constructing a path which has inconsistent - // (in terms of reaching htlc_minimum_msat), so that this function puts the fees in order. - // In that case we call it on the "same" amount we initially allocated for this path, and which - // could have been reduced on the way. In that case, there is also a risk of exceeding - // available_liquidity inside this function, because the function is unaware of this bound. - // In our specific recomputation cases where we never increase the value the risk is pretty low. - // This function, however, does not support arbitrarily increasing the value being transferred, - // and the exception will be triggered. + // Sometimes we call this function right after constructing a path which is inconsistent in + // that it the value being transferred has decreased while we were doing path finding, leading + // to the fees being paid not lining up with the actual limits. + // + // Note that this function is not aware of the available_liquidity limit, and thus does not + // support increasing the value being transferred. fn update_value_and_recompute_fees(&mut self, value_msat: u64) { assert!(value_msat <= self.hops.last().unwrap().0.fee_msat); @@ -355,7 +353,7 @@ fn compute_fees(amount_msat: u64, channel_fees: RoutingFees) -> Option { /// 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(our_node_id: &PublicKey, network: &NetworkGraph, payee: &PublicKey, payee_features: Option, first_hops: Option<&[&ChannelDetails]>, - last_hops: &[&RouteHint], final_value_msat: u64, final_cltv: u32, logger: L) -> Result where L::Target: Logger { + last_hops: &[&RouteHintHop], final_value_msat: u64, final_cltv: u32, logger: L) -> Result where L::Target: Logger { // TODO: Obviously *only* using total fee cost sucks. We should consider weighting by // uptime/success in using a node in the past. if *payee == *our_node_id { @@ -478,7 +476,13 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye let empty_channel_features = ChannelFeatures::empty(); - let mut targets = BinaryHeap::new(); //TODO: Do we care about switching to eg Fibbonaci heap? + // The main heap containing all candidate next-hops sorted by their score (max(A* fee, + // htlc_minimum)). Ideally this would be a heap which allowed cheap score reduction instead of + // adding duplicate entries when we find a better path to a given node. + let mut targets = BinaryHeap::new(); + + // Map from node_id to information about the best current path to that node, including feerate + // information. let mut dist = HashMap::with_capacity(network.get_nodes().len()); // During routing, if we ignore a path due to an htlc_minimum_msat limit, we set this, @@ -1159,7 +1163,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye #[cfg(test)] mod tests { - use routing::router::{get_route, RouteHint, RoutingFees}; + use routing::router::{get_route, RouteHintHop, RoutingFees}; use routing::network_graph::{NetworkGraph, NetGraphMsgHandler}; use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures}; use ln::msgs::{ErrorAction, LightningError, OptionalField, UnsignedChannelAnnouncement, ChannelAnnouncement, RoutingMessageHandler, @@ -2080,19 +2084,19 @@ mod tests { assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags(13)); } - fn last_hops(nodes: &Vec) -> Vec { + fn last_hops(nodes: &Vec) -> Vec { let zero_fees = RoutingFees { base_msat: 0, proportional_millionths: 0, }; - vec!(RouteHint { + vec!(RouteHintHop { src_node_id: nodes[3].clone(), short_channel_id: 8, fees: zero_fees, cltv_expiry_delta: (8 << 8) | 1, htlc_minimum_msat: None, htlc_maximum_msat: None, - }, RouteHint { + }, RouteHintHop { src_node_id: nodes[4].clone(), short_channel_id: 9, fees: RoutingFees { @@ -2102,7 +2106,7 @@ mod tests { cltv_expiry_delta: (9 << 8) | 1, htlc_minimum_msat: None, htlc_maximum_msat: None, - }, RouteHint { + }, RouteHintHop { src_node_id: nodes[5].clone(), short_channel_id: 10, fees: zero_fees, @@ -2120,7 +2124,7 @@ mod tests { // Simple test across 2, 3, 5, and 4 via a last_hop channel // First check that lst hop can't have its source as the payee. - let invalid_last_hop = RouteHint { + let invalid_last_hop = RouteHintHop { src_node_id: nodes[6], short_channel_id: 8, fees: RoutingFees { @@ -2305,7 +2309,7 @@ mod tests { let target_node_id = PublicKey::from_secret_key(&Secp256k1::new(), &SecretKey::from_slice(&hex::decode(format!("{:02}", 43).repeat(32)).unwrap()[..]).unwrap()); // If we specify a channel to a middle hop, that overrides our local channel view and that gets used - let last_hops = vec![RouteHint { + let last_hops = vec![RouteHintHop { src_node_id: middle_node_id, short_channel_id: 8, fees: RoutingFees { @@ -3847,7 +3851,8 @@ mod tests { }); #[cfg(require_route_graph_test)] return Ok(res.expect("Didn't have route graph and was configured to require it")); - res + #[cfg(not(require_route_graph_test))] + return res; } pub(super) fn random_init_seed() -> u64 { @@ -3918,7 +3923,6 @@ mod benches { use super::*; use util::logger::{Logger, Record}; - use std::fs::File; use test::Bencher; struct DummyLogger {}