X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=1d4234d9db4f0f6154d801d06f90f892d7f21730;hb=0dfcacd22c23f69b6526c9c6507d21427a2b7ccb;hp=44b8c8a24aec4260a0b016c45ce774fd0b566354;hpb=1f1d7c6890c6c9bef70eeb4ec4c6841e3344159b;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 44b8c8a2..1d4234d9 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -21,6 +21,7 @@ use routing::network_graph::{NetworkGraph, RoutingFees}; use util::ser::{Writeable, Readable}; use util::logger::Logger; +use io; use prelude::*; use alloc::collections::BinaryHeap; use core::cmp; @@ -74,7 +75,7 @@ const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; impl Writeable for Route { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); (self.paths.len() as u64).write(writer)?; for hops in self.paths.iter() { @@ -89,7 +90,7 @@ impl Writeable for Route { } impl Readable for Route { - fn read(reader: &mut R) -> Result { + fn read(reader: &mut R) -> Result { let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION); let path_count: u64 = Readable::read(reader)?; let mut paths = Vec::with_capacity(cmp::min(path_count, 128) as usize); @@ -327,6 +328,18 @@ fn compute_fees(amount_msat: u64, channel_fees: RoutingFees) -> Option { } } +/// 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_features` parameter of `get_route`. +pub fn get_keysend_route(our_node_id: &PublicKey, network: &NetworkGraph, payee: + &PublicKey, first_hops: Option<&[&ChannelDetails]>, last_hops: &[&RouteHint], + final_value_msat: u64, final_cltv: u32, logger: L) -> Result where L::Target: Logger { + let invoice_features = InvoiceFeatures::for_keysend(); + get_route(our_node_id, network, payee, Some(invoice_features), first_hops, last_hops, + final_value_msat, final_cltv, logger) +} + /// 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_features. @@ -882,7 +895,11 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye htlc_maximum_msat: hop.htlc_maximum_msat, fees: hop.fees, }; - if add_entry!(hop.short_channel_id, hop.src_node_id, payee, directional_info, None::, &empty_channel_features, 0, path_value_msat, 0) { + // We assume that the recipient only included route hints for routes which had + // sufficient value to route `final_value_msat`. Note that in the case of "0-value" + // invoices where the invoice does not specify value this may not be the case, but + // better to include the hints than not. + if add_entry!(hop.short_channel_id, hop.src_node_id, payee, directional_info, Some((final_value_msat + 999) / 1000), &empty_channel_features, 0, path_value_msat, 0) { // If this hop connects to a node with which we have a direct channel, // ignore the network graph and, if the last hop was added, add our // direct channel to the candidate set. @@ -1198,7 +1215,7 @@ mod tests { use bitcoin::secp256k1::{Secp256k1, All}; use prelude::*; - use std::sync::Arc; + use sync::{self, Arc}; fn get_channel_details(short_channel_id: Option, node_id: PublicKey, features: InitFeatures, outbound_capacity_msat: u64) -> channelmanager::ChannelDetails { @@ -1321,7 +1338,7 @@ mod tests { } } - fn build_graph() -> (Secp256k1, NetGraphMsgHandler, std::sync::Arc>, std::sync::Arc, std::sync::Arc) { + fn build_graph() -> (Secp256k1, NetGraphMsgHandler, sync::Arc>, sync::Arc, sync::Arc) { let secp_ctx = Secp256k1::new(); let logger = Arc::new(test_utils::TestLogger::new()); let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));