X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=883d0015fbb464a3d3ec994db838ead6930104aa;hb=ed84b02a0aef7d97a887d187ea0429dcd780a6b3;hp=d593e8c2d3c9e6e315fe45622f701c2fff39455c;hpb=8467223a5d7ea744c2af8557ed2e6a7a20991bdd;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index d593e8c2..883d0015 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1,6 +1,6 @@ //! The top-level routing/network map tracking logic lives here. //! -//! You probably want to create a Router and use that as your RoutingMessageHandler and then +//! You probably want to create a NetGraphMsgHandler and use that as your RoutingMessageHandler and then //! interrogate it to get routes for your own payments. use bitcoin::secp256k1::key::PublicKey; @@ -8,13 +8,13 @@ use bitcoin::secp256k1::key::PublicKey; use ln::channelmanager; use ln::features::{ChannelFeatures, NodeFeatures}; use ln::msgs::{DecodeError,ErrorAction,LightningError}; -use routing::network_graph::{NetGraphMsgHandler, RoutingFees}; +use routing::network_graph::{NetworkGraph, RoutingFees}; use util::ser::{Writeable, Readable}; -use util::logger::{Logger, LogHolder}; +use util::logger::Logger; use std::cmp; -use std::sync::Arc; use std::collections::{HashMap,BinaryHeap}; +use std::ops::Deref; /// A hop in a route #[derive(Clone, PartialEq)] @@ -144,14 +144,14 @@ struct DummyDirectionalChannelInfo { } -/// Gets a route from us (as specified in the provided NetGraphMsgHandler) to the given target node. +/// Gets a route from us (as specified in the provided NetworkGraph) to the given target node. /// /// Extra routing hops between known nodes and the target will be used if they are included in /// last_hops. /// /// 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 -/// (this Router's) view of our local channels will be ignored, and only those in first_hops +/// 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 @@ -160,16 +160,16 @@ struct DummyDirectionalChannelInfo { /// 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 /// *is* checked as they may change based on the receiving node. -pub fn get_route(our_node_id: &PublicKey, net_graph_msg_handler: &NetGraphMsgHandler, target: &PublicKey, first_hops: Option<&[channelmanager::ChannelDetails]>, - last_hops: &[RouteHint], final_value_msat: u64, final_cltv: u32, logger: Arc) -> Result { +pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, target: &PublicKey, first_hops: Option<&[channelmanager::ChannelDetails]>, + last_hops: &[RouteHint], 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 *target == *our_node_id { - return Err(LightningError{err: "Cannot generate a route to ourselves", action: ErrorAction::IgnoreError}); + return Err(LightningError{err: "Cannot generate a route to ourselves".to_owned(), action: ErrorAction::IgnoreError}); } if final_value_msat > 21_000_000 * 1_0000_0000 * 1000 { - return Err(LightningError{err: "Cannot generate a route of more value than all existing satoshis", action: ErrorAction::IgnoreError}); + return Err(LightningError{err: "Cannot generate a route of more value than all existing satoshis".to_owned(), action: ErrorAction::IgnoreError}); } // We do a dest-to-source Dijkstra's sorting by each node's distance from the destination @@ -187,7 +187,6 @@ pub fn get_route(our_node_id: &PublicKey, net_graph_msg_handler: &NetGraphMsgHan } }; - let network = net_graph_msg_handler.network_graph.read().unwrap(); let mut targets = BinaryHeap::new(); //TODO: Do we care about switching to eg Fibbonaci heap? let mut dist = HashMap::with_capacity(network.get_nodes().len()); @@ -210,7 +209,7 @@ pub fn get_route(our_node_id: &PublicKey, net_graph_msg_handler: &NetGraphMsgHan first_hop_targets.insert(chan.remote_network_id, (short_channel_id, chan.counterparty_features.clone())); } if first_hop_targets.is_empty() { - return Err(LightningError{err: "Cannot route when there are no outbound routes away from us", action: ErrorAction::IgnoreError}); + return Err(LightningError{err: "Cannot route when there are no outbound routes away from us".to_owned(), action: ErrorAction::IgnoreError}); } } @@ -375,7 +374,7 @@ pub fn get_route(our_node_id: &PublicKey, net_graph_msg_handler: &NetGraphMsgHan let new_entry = match dist.remove(&res.last().unwrap().pubkey) { Some(hop) => hop.3, - None => return Err(LightningError{err: "Failed to find a non-fee-overflowing path to the given destination", action: ErrorAction::IgnoreError}), + None => return Err(LightningError{err: "Failed to find a non-fee-overflowing path to the given destination".to_owned(), action: ErrorAction::IgnoreError}), }; res.last_mut().unwrap().fee_msat = new_entry.fee_msat; res.last_mut().unwrap().cltv_expiry_delta = new_entry.cltv_expiry_delta; @@ -384,8 +383,7 @@ pub fn get_route(our_node_id: &PublicKey, net_graph_msg_handler: &NetGraphMsgHan res.last_mut().unwrap().fee_msat = final_value_msat; res.last_mut().unwrap().cltv_expiry_delta = final_cltv; let route = Route { paths: vec![res] }; - let log_holder = LogHolder { logger: &logger }; - log_trace!(log_holder, "Got route: {}", log_route!(route)); + log_trace!(logger, "Got route: {}", log_route!(route)); return Ok(route); } @@ -397,20 +395,19 @@ pub fn get_route(our_node_id: &PublicKey, net_graph_msg_handler: &NetGraphMsgHan } } - Err(LightningError{err: "Failed to find a path to the given destination", action: ErrorAction::IgnoreError}) + Err(LightningError{err: "Failed to find a path to the given destination".to_owned(), action: ErrorAction::IgnoreError}) } #[cfg(test)] mod tests { use chain::chaininterface; - use routing::router::{NetGraphMsgHandler, RoutingFees}; - use routing::router::{get_route, RouteHint}; + use routing::router::{get_route, RouteHint, RoutingFees}; + use routing::network_graph::NetGraphMsgHandler; use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; use ln::msgs::{ErrorAction, LightningError, UnsignedChannelAnnouncement, ChannelAnnouncement, RoutingMessageHandler, NodeAnnouncement, UnsignedNodeAnnouncement, ChannelUpdate, UnsignedChannelUpdate}; use ln::channelmanager; use util::test_utils; - use util::logger::Logger; use util::ser::Writeable; use bitcoin::hashes::sha256d::Hash as Sha256dHash; @@ -427,7 +424,7 @@ mod tests { use std::sync::Arc; // Using the same keys for LN and BTC ids - fn add_channel(net_graph_msg_handler: &NetGraphMsgHandler, secp_ctx: &Secp256k1, node_1_privkey: &SecretKey, + fn add_channel(net_graph_msg_handler: &NetGraphMsgHandler, Arc>, secp_ctx: &Secp256k1, node_1_privkey: &SecretKey, node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64) { let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_id_2 = PublicKey::from_secret_key(&secp_ctx, node_2_privkey); @@ -457,7 +454,7 @@ mod tests { }; } - fn update_channel(net_graph_msg_handler: &NetGraphMsgHandler, secp_ctx: &Secp256k1, node_privkey: &SecretKey, update: UnsignedChannelUpdate) { + fn update_channel(net_graph_msg_handler: &NetGraphMsgHandler, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, update: UnsignedChannelUpdate) { let msghash = hash_to_message!(&Sha256dHash::hash(&update.encode()[..])[..]); let valid_channel_update = ChannelUpdate { signature: secp_ctx.sign(&msghash, node_privkey), @@ -472,7 +469,7 @@ mod tests { } - fn add_or_update_node(net_graph_msg_handler: &NetGraphMsgHandler, secp_ctx: &Secp256k1, node_privkey: &SecretKey, + fn add_or_update_node(net_graph_msg_handler: &NetGraphMsgHandler, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, features: NodeFeatures, timestamp: u32) { let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey); let unsigned_announcement = UnsignedNodeAnnouncement { @@ -502,8 +499,8 @@ mod tests { let secp_ctx = Secp256k1::new(); let our_privkey = &SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap(); let our_id = PublicKey::from_secret_key(&secp_ctx, our_privkey); - let logger: Arc = Arc::new(test_utils::TestLogger::new()); - let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&logger))); + let logger = Arc::new(test_utils::TestLogger::new()); + let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet)); let net_graph_msg_handler = NetGraphMsgHandler::new(chain_monitor, Arc::clone(&logger)); // Build network from our_id to node8: // @@ -817,7 +814,7 @@ mod tests { add_or_update_node(&net_graph_msg_handler, &secp_ctx, node6_privkey, NodeFeatures::from_le_bytes(id_to_feature_flags!(6)), 0); // Simple route to 3 via 2 - let route = get_route(&our_id, &net_graph_msg_handler, &node3, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node3, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, node2); @@ -860,7 +857,7 @@ mod tests { }); // If all the channels require some features we don't understand, route should fail - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler, &node3, None, &Vec::new(), 100, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node3, None, &Vec::new(), 100, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } @@ -876,7 +873,7 @@ mod tests { inbound_capacity_msat: 0, is_live: true, }]; - let route = get_route(&our_id, &net_graph_msg_handler, &node3, Some(&our_chans), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node3, Some(&our_chans), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, node8); @@ -884,7 +881,7 @@ mod tests { assert_eq!(route.paths[0][0].fee_msat, 200); assert_eq!(route.paths[0][0].cltv_expiry_delta, (13 << 8) | 1); assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]); // it should also override our view of their features - assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion + assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::::new()); // No feature flags will meet the relevant-to-channel conversion assert_eq!(route.paths[0][1].pubkey, node3); assert_eq!(route.paths[0][1].short_channel_id, 13); @@ -940,7 +937,7 @@ mod tests { inbound_capacity_msat: 0, is_live: true, }]; - let route = get_route(&our_id, &net_graph_msg_handler, &node3, Some(&our_chans), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node3, Some(&our_chans), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, node8); @@ -948,7 +945,7 @@ mod tests { assert_eq!(route.paths[0][0].fee_msat, 200); assert_eq!(route.paths[0][0].cltv_expiry_delta, (13 << 8) | 1); assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]); // it should also override our view of their features - assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion + assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::::new()); // No feature flags will meet the relevant-to-channel conversion assert_eq!(route.paths[0][1].pubkey, node3); assert_eq!(route.paths[0][1].short_channel_id, 13); @@ -967,7 +964,7 @@ mod tests { // the node_announcement. // Route to 1 via 2 and 3 because our channel to 1 is disabled - let route = get_route(&our_id, &net_graph_msg_handler, &node1, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node1, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 3); assert_eq!(route.paths[0][0].pubkey, node2); @@ -1003,7 +1000,7 @@ mod tests { inbound_capacity_msat: 0, is_live: true, }]; - let route = get_route(&our_id, &net_graph_msg_handler, &node3, Some(&our_chans), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node3, Some(&our_chans), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, node8); @@ -1011,7 +1008,7 @@ mod tests { assert_eq!(route.paths[0][0].fee_msat, 200); assert_eq!(route.paths[0][0].cltv_expiry_delta, (13 << 8) | 1); assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]); - assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion + assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::::new()); // No feature flags will meet the relevant-to-channel conversion assert_eq!(route.paths[0][1].pubkey, node3); assert_eq!(route.paths[0][1].short_channel_id, 13); @@ -1048,7 +1045,7 @@ mod tests { }); // Simple test across 2, 3, 5, and 4 via a last_hop channel - let route = get_route(&our_id, &net_graph_msg_handler, &node7, None, &last_hops, 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node7, None, &last_hops, 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 5); assert_eq!(route.paths[0][0].pubkey, node2); @@ -1085,8 +1082,8 @@ mod tests { assert_eq!(route.paths[0][4].short_channel_id, 8); assert_eq!(route.paths[0][4].fee_msat, 100); assert_eq!(route.paths[0][4].cltv_expiry_delta, 42); - assert_eq!(route.paths[0][4].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet - assert_eq!(route.paths[0][4].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly + assert_eq!(route.paths[0][4].node_features.le_flags(), &Vec::::new()); // We dont pass flags in from invoices yet + assert_eq!(route.paths[0][4].channel_features.le_flags(), &Vec::::new()); // We can't learn any flags from invoices, sadly // Simple test with outbound channel to 4 to test that last_hops and first_hops connect let our_chans = vec![channelmanager::ChannelDetails { @@ -1100,7 +1097,7 @@ mod tests { inbound_capacity_msat: 0, is_live: true, }]; - let route = get_route(&our_id, &net_graph_msg_handler, &node7, Some(&our_chans), &last_hops, 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node7, Some(&our_chans), &last_hops, 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, node4); @@ -1108,19 +1105,19 @@ mod tests { assert_eq!(route.paths[0][0].fee_msat, 0); assert_eq!(route.paths[0][0].cltv_expiry_delta, (8 << 8) | 1); assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]); - assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion + assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::::new()); // No feature flags will meet the relevant-to-channel conversion assert_eq!(route.paths[0][1].pubkey, node7); assert_eq!(route.paths[0][1].short_channel_id, 8); assert_eq!(route.paths[0][1].fee_msat, 100); assert_eq!(route.paths[0][1].cltv_expiry_delta, 42); - assert_eq!(route.paths[0][1].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet - assert_eq!(route.paths[0][1].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly + assert_eq!(route.paths[0][1].node_features.le_flags(), &Vec::::new()); // We dont pass flags in from invoices yet + assert_eq!(route.paths[0][1].channel_features.le_flags(), &Vec::::new()); // We can't learn any flags from invoices, sadly last_hops[0].fees.base_msat = 1000; // Revert to via 6 as the fee on 8 goes up - let route = get_route(&our_id, &net_graph_msg_handler, &node7, None, &last_hops, 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node7, None, &last_hops, 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 4); assert_eq!(route.paths[0][0].pubkey, node2); @@ -1150,11 +1147,11 @@ mod tests { assert_eq!(route.paths[0][3].short_channel_id, 10); assert_eq!(route.paths[0][3].fee_msat, 100); assert_eq!(route.paths[0][3].cltv_expiry_delta, 42); - assert_eq!(route.paths[0][3].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet - assert_eq!(route.paths[0][3].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly + assert_eq!(route.paths[0][3].node_features.le_flags(), &Vec::::new()); // We dont pass flags in from invoices yet + assert_eq!(route.paths[0][3].channel_features.le_flags(), &Vec::::new()); // We can't learn any flags from invoices, sadly // ...but still use 8 for larger payments as 6 has a variable feerate - let route = get_route(&our_id, &net_graph_msg_handler, &node7, None, &last_hops, 2000, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &node7, None, &last_hops, 2000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 5); assert_eq!(route.paths[0][0].pubkey, node2); @@ -1191,7 +1188,7 @@ mod tests { assert_eq!(route.paths[0][4].short_channel_id, 8); assert_eq!(route.paths[0][4].fee_msat, 2000); assert_eq!(route.paths[0][4].cltv_expiry_delta, 42); - assert_eq!(route.paths[0][4].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet - assert_eq!(route.paths[0][4].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly + assert_eq!(route.paths[0][4].node_features.le_flags(), &Vec::::new()); // We dont pass flags in from invoices yet + assert_eq!(route.paths[0][4].channel_features.le_flags(), &Vec::::new()); // We can't learn any flags from invoices, sadly } }