X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=inline;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=2fc0d1745206d5986a0a6375e273b72b23ccb035;hb=4395b92cc8bfe0cc803e70bba11f4db58d5d0dbf;hp=dfdfb5e8f877bc515e92cb2de6559bb64bd80ede;hpb=0133739e9e585ebe966ba4a1d41b003f4f4769bf;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index dfdfb5e8..2fc0d174 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1,3 +1,12 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + //! The top-level routing/network map tracking logic lives here. //! //! You probably want to create a NetGraphMsgHandler and use that as your RoutingMessageHandler and then @@ -7,7 +16,7 @@ use bitcoin::secp256k1::key::PublicKey; use ln::channelmanager; use ln::features::{ChannelFeatures, NodeFeatures}; -use ln::msgs::{DecodeError,ErrorAction,LightningError}; +use ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT}; use routing::network_graph::{NetworkGraph, RoutingFees}; use util::ser::{Writeable, Readable}; use util::logger::Logger; @@ -144,7 +153,7 @@ struct DummyDirectionalChannelInfo { } -/// Gets a route from us (as specified in the provided NetworkGraph) to the given target node. +/// Gets a route from us to the given target node. /// /// Extra routing hops between known nodes and the target will be used if they are included in /// last_hops. @@ -165,11 +174,11 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, targ // 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}); + if final_value_msat > MAX_VALUE_MSAT { + 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 @@ -209,7 +218,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, targ 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}); } } @@ -244,7 +253,8 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, targ channel_features: $chan_features.clone(), fee_msat: 0, cltv_expiry_delta: 0, - }) + }, + ) }); if $src_node_id != *our_node_id { // Ignore new_fee for channel-from-us as we assume all channels-from-us @@ -374,7 +384,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, targ 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; @@ -395,7 +405,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, targ } } - 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)] @@ -404,7 +414,7 @@ mod tests { 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, + use ln::msgs::{ErrorAction, LightningError, OptionalField, UnsignedChannelAnnouncement, ChannelAnnouncement, RoutingMessageHandler, NodeAnnouncement, UnsignedNodeAnnouncement, ChannelUpdate, UnsignedChannelUpdate}; use ln::channelmanager; use util::test_utils; @@ -603,6 +613,7 @@ mod tests { flags: 1, cltv_expiry_delta: 0, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -617,6 +628,7 @@ mod tests { flags: 0, cltv_expiry_delta: u16::max_value(), htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: u32::max_value(), fee_proportional_millionths: u32::max_value(), excess_data: Vec::new() @@ -628,6 +640,7 @@ mod tests { flags: 1, cltv_expiry_delta: 0, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -643,6 +656,7 @@ mod tests { flags: 0, cltv_expiry_delta: u16::max_value(), htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: u32::max_value(), fee_proportional_millionths: u32::max_value(), excess_data: Vec::new() @@ -654,6 +668,7 @@ mod tests { flags: 1, cltv_expiry_delta: 0, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -670,6 +685,7 @@ mod tests { flags: 0, cltv_expiry_delta: (3 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -681,6 +697,7 @@ mod tests { flags: 1, cltv_expiry_delta: (3 << 8) | 2, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 100, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -695,6 +712,7 @@ mod tests { flags: 0, cltv_expiry_delta: (4 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 1000000, excess_data: Vec::new() @@ -706,6 +724,7 @@ mod tests { flags: 1, cltv_expiry_delta: (4 << 8) | 2, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -719,6 +738,7 @@ mod tests { flags: 0, cltv_expiry_delta: (13 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 2000000, excess_data: Vec::new() @@ -730,6 +750,7 @@ mod tests { flags: 1, cltv_expiry_delta: (13 << 8) | 2, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -744,6 +765,7 @@ mod tests { flags: 0, cltv_expiry_delta: (6 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -755,6 +777,7 @@ mod tests { flags: 1, cltv_expiry_delta: (6 << 8) | 2, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -768,6 +791,7 @@ mod tests { flags: 0, cltv_expiry_delta: (11 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -779,6 +803,7 @@ mod tests { flags: 1, cltv_expiry_delta: (11 << 8) | 2, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -795,6 +820,7 @@ mod tests { flags: 0, cltv_expiry_delta: (7 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 1000000, excess_data: Vec::new() @@ -806,6 +832,7 @@ mod tests { flags: 1, cltv_expiry_delta: (7 << 8) | 2, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -840,6 +867,7 @@ mod tests { flags: 2, // to disable cltv_expiry_delta: 0, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -851,6 +879,7 @@ mod tests { flags: 2, // to disable cltv_expiry_delta: 0, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 0, excess_data: Vec::new() @@ -881,7 +910,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); @@ -898,6 +927,7 @@ mod tests { flags: 0, // to enable cltv_expiry_delta: (4 << 8) | 1, htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: 0, fee_proportional_millionths: 1000000, excess_data: Vec::new() @@ -909,6 +939,7 @@ mod tests { flags: 0, // to enable cltv_expiry_delta: u16::max_value(), htlc_minimum_msat: 0, + htlc_maximum_msat: OptionalField::Absent, fee_base_msat: u32::max_value(), fee_proportional_millionths: u32::max_value(), excess_data: Vec::new() @@ -945,7 +976,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); @@ -1008,7 +1039,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); @@ -1082,8 +1113,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 { @@ -1105,14 +1136,14 @@ 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; @@ -1147,8 +1178,8 @@ 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.network_graph.read().unwrap(), &node7, None, &last_hops, 2000, 42, Arc::clone(&logger)).unwrap(); @@ -1188,7 +1219,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 } }