use bitcoin::secp256k1::key::PublicKey;
-use ln::channelmanager;
+use ln::channelmanager::ChannelDetails;
use ln::features::{ChannelFeatures, NodeFeatures};
use ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
use routing::network_graph::{NetworkGraph, RoutingFees};
}
/// A channel descriptor which provides a last-hop route to get_route
+#[derive(Clone)]
pub struct RouteHint {
/// The node_id of the non-target end of the route
pub src_node_id: PublicKey,
/// 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<L: Deref>(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<Route, LightningError> where L::Target: Logger {
+pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, target: &PublicKey, first_hops: Option<&[&ChannelDetails]>,
+ last_hops: &[&RouteHint], final_value_msat: u64, final_cltv: u32, logger: L) -> Result<Route, LightningError> 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 {
#[cfg(test)]
mod tests {
- use chain::chaininterface;
use routing::router::{get_route, RouteHint, RoutingFees};
use routing::network_graph::NetGraphMsgHandler;
use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
use bitcoin::hashes::Hash;
use bitcoin::network::constants::Network;
use bitcoin::blockdata::constants::genesis_block;
- use bitcoin::util::hash::BitcoinHash;
use hex;
use std::sync::Arc;
// Using the same keys for LN and BTC ids
- fn add_channel(net_graph_msg_handler: &NetGraphMsgHandler<Arc<chaininterface::ChainWatchInterfaceUtil>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_1_privkey: &SecretKey,
+ fn add_channel(net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, 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);
let unsigned_announcement = UnsignedChannelAnnouncement {
features,
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id,
node_id_1,
node_id_2,
};
}
- fn update_channel(net_graph_msg_handler: &NetGraphMsgHandler<Arc<chaininterface::ChainWatchInterfaceUtil>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey, update: UnsignedChannelUpdate) {
+ fn update_channel(net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, 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),
}
- fn add_or_update_node(net_graph_msg_handler: &NetGraphMsgHandler<Arc<chaininterface::ChainWatchInterfaceUtil>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey,
+ fn add_or_update_node(net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey,
features: NodeFeatures, timestamp: u32) {
let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey);
let unsigned_announcement = UnsignedNodeAnnouncement {
}
}
- fn build_graph() -> (Secp256k1<All>, NetGraphMsgHandler<std::sync::Arc<crate::chain::chaininterface::ChainWatchInterfaceUtil>, std::sync::Arc<crate::util::test_utils::TestLogger>>, std::sync::Arc<test_utils::TestLogger>) {
+ fn build_graph() -> (Secp256k1<All>, NetGraphMsgHandler<std::sync::Arc<crate::util::test_utils::TestChainSource>, std::sync::Arc<crate::util::test_utils::TestLogger>>, std::sync::Arc<test_utils::TestLogger>) {
let secp_ctx = Secp256k1::new();
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));
+ let net_graph_msg_handler = NetGraphMsgHandler::new(None, Arc::clone(&logger));
// Build network from our_id to node7:
//
// -1(1)2- node0 -1(3)2-
add_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, &privkeys[0], ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), 1);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(2)), 2);
update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, &privkeys[7], ChannelFeatures::from_le_bytes(id_to_feature_flags(12)), 12);
update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 3);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(4)), 4);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(13)), 13);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(11)), 11);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 1,
flags: 1,
add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], &privkeys[5], ChannelFeatures::from_le_bytes(id_to_feature_flags(7)), 7);
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 1,
flags: 0,
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[5], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 1,
flags: 1,
// // Disable channels 4 and 12 by flags=2
update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
flags: 2, // to disable
excess_data: Vec::new()
});
update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+ chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
flags: 2, // to disable
inbound_capacity_msat: 0,
is_live: true,
}];
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], 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(), &nodes[2], Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[7]);
inbound_capacity_msat: 0,
is_live: true,
}];
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], 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(), &nodes[2], Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[7]);
inbound_capacity_msat: 0,
is_live: true,
}];
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], 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(), &nodes[2], Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[7]);
let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
// Simple test across 2, 3, 5, and 4 via a last_hop channel
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, &last_hops(&nodes), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, &last_hops(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 5);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
is_live: true,
}];
let mut last_hops = last_hops(&nodes);
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], 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(), &nodes[6], Some(&our_chans.iter().collect::<Vec<_>>()), &last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[3]);
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.network_graph.read().unwrap(), &nodes[6], None, &last_hops, 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, &last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 4);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
assert_eq!(route.paths[0][3].channel_features.le_flags(), &Vec::<u8>::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(), &nodes[6], None, &last_hops, 2000, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, &last_hops.iter().collect::<Vec<_>>(), 2000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 5);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);