//! 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
+//! You probably want to create a P2PGossipSync and use that as your RoutingMessageHandler and then
//! interrogate it to get routes for your own payments.
use bitcoin::secp256k1::PublicKey;
use ln::channelmanager::ChannelDetails;
use ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures};
use ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
+use routing::gossip::{DirectedChannelInfoWithUpdate, EffectiveCapacity, ReadOnlyNetworkGraph, NodeId, RoutingFees};
use routing::scoring::{ChannelUsage, Score};
-use routing::network_graph::{DirectedChannelInfoWithUpdate, EffectiveCapacity, NetworkGraph, ReadOnlyNetworkGraph, NodeId, RoutingFees};
use util::ser::{Writeable, Readable, Writer};
use util::logger::{Level, Logger};
use util::chacha20::ChaCha20;
/// Maximum total CTLV difference we allow for a full payment path.
pub const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA: u32 = 1008;
+/// Maximum number of paths we allow an MPP payment to have.
+// The default limit is currently set rather arbitrary - there aren't any real fundamental path-count
+// limits, but for now more than 10 paths likely carries too much one-path failure.
+pub const DEFAULT_MAX_MPP_PATH_COUNT: u8 = 10;
+
// The median hop CLTV expiry delta currently seen in the network.
const MEDIAN_HOP_CLTV_EXPIRY_DELTA: u32 = 40;
pub expiry_time: Option<u64>,
/// The maximum total CLTV delta we accept for the route.
+ /// Defaults to [`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`].
pub max_total_cltv_expiry_delta: u32,
+
+ /// The maximum number of paths that may be used by MPP payments.
+ /// Defaults to [`DEFAULT_MAX_MPP_PATH_COUNT`].
+ pub max_mpp_path_count: u8,
}
impl_writeable_tlv_based!(PaymentParameters, {
(0, payee_pubkey, required),
(1, max_total_cltv_expiry_delta, (default_value, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA)),
(2, features, option),
+ (3, max_mpp_path_count, (default_value, DEFAULT_MAX_MPP_PATH_COUNT)),
(4, route_hints, vec_type),
(6, expiry_time, option),
});
route_hints: vec![],
expiry_time: None,
max_total_cltv_expiry_delta: DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
+ max_mpp_path_count: DEFAULT_MAX_MPP_PATH_COUNT,
}
}
pub fn with_max_total_cltv_expiry_delta(self, max_total_cltv_expiry_delta: u32) -> Self {
Self { max_total_cltv_expiry_delta, ..self }
}
+
+ /// Includes a limit for the maximum number of payment paths that may be used by MPP.
+ ///
+ /// (C-not exported) since bindings don't support move semantics
+ pub fn with_max_mpp_path_count(self, max_mpp_path_count: u8) -> Self {
+ Self { max_mpp_path_count, ..self }
+ }
}
/// A list of hops along a payment path terminating with a channel to the recipient.
FirstHop {
details: &'a ChannelDetails,
},
- /// A hop found in the [`NetworkGraph`], where the channel capacity may or may not be known.
+ /// A hop found in the [`ReadOnlyNetworkGraph`], where the channel capacity may be unknown.
PublicHop {
info: DirectedChannelInfoWithUpdate<'a>,
short_channel_id: u64,
/// Private routing paths between a public node and the target may be included in `params.payee`.
///
/// If some channels aren't announced, it may be useful to fill in `first_hops` with the results
-/// from [`ChannelManager::list_usable_channels`]. If it is filled in, the view of our local
-/// channels from [`NetworkGraph`] will be ignored, and only those in `first_hops` will be used.
+/// from [`ChannelManager::list_usable_channels`]. If it is filled in, the view of these channels
+/// from `network_graph` will be ignored, and only those in `first_hops` will be used.
///
/// The fees on channels from us to the next hop 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` /
///
/// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels
/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
+/// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph
pub fn find_route<L: Deref, S: Score>(
- our_node_pubkey: &PublicKey, route_params: &RouteParameters, network: &NetworkGraph,
- first_hops: Option<&[&ChannelDetails]>, logger: L, scorer: &S, random_seed_bytes: &[u8; 32]
+ our_node_pubkey: &PublicKey, route_params: &RouteParameters,
+ network_graph: &ReadOnlyNetworkGraph, first_hops: Option<&[&ChannelDetails]>, logger: L,
+ scorer: &S, random_seed_bytes: &[u8; 32]
) -> Result<Route, LightningError>
where L::Target: Logger {
- let network_graph = network.read_only();
- let mut route = get_route(our_node_pubkey, &route_params.payment_params, &network_graph, first_hops,
+ let mut route = get_route(our_node_pubkey, &route_params.payment_params, network_graph, first_hops,
route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, scorer,
random_seed_bytes)?;
- add_random_cltv_offset(&mut route, &route_params.payment_params, &network_graph, random_seed_bytes);
+ add_random_cltv_offset(&mut route, &route_params.payment_params, network_graph, random_seed_bytes);
Ok(route)
}
node_info.features.supports_basic_mpp()
} else { false }
} else { false };
+
+ if allow_mpp && payment_params.max_mpp_path_count == 0 {
+ return Err(LightningError{err: "Can't find an MPP route with no paths allowed.".to_owned(), action: ErrorAction::IgnoreError});
+ }
+
log_trace!(logger, "Searching for a route from payer {} to payee {} {} MPP and {} first hops {}overriding the network graph", our_node_pubkey,
payment_params.payee_pubkey, if allow_mpp { "with" } else { "without" },
first_hops.map(|hops| hops.len()).unwrap_or(0), if first_hops.is_some() { "" } else { "not " });
let recommended_value_msat = final_value_msat * ROUTE_CAPACITY_PROVISION_FACTOR as u64;
let mut path_value_msat = final_value_msat;
+ // Routing Fragmentation Mitigation heuristic:
+ //
+ // Routing fragmentation across many payment paths increases the overall routing
+ // fees as you have irreducible routing fees per-link used (`fee_base_msat`).
+ // Taking too many smaller paths also increases the chance of payment failure.
+ // Thus to avoid this effect, we require from our collected links to provide
+ // at least a minimal contribution to the recommended value yet-to-be-fulfilled.
+ // This requirement is currently set to be 1/max_mpp_path_count of the payment
+ // value to ensure we only ever return routes that do not violate this limit.
+ let minimal_value_contribution_msat: u64 = if allow_mpp {
+ (final_value_msat + (payment_params.max_mpp_path_count as u64 - 1)) / payment_params.max_mpp_path_count as u64
+ } else {
+ final_value_msat
+ };
+
// Keep track of how much liquidity has been used in selected channels. Used to determine
// if the channel can be used by additional MPP paths or to inform path finding decisions. It is
// aware of direction *only* to ensure that the correct htlc_maximum_msat value is used. Hence,
let mut used_channel_liquidities: HashMap<(u64, bool), u64> =
HashMap::with_capacity(network_nodes.len());
- // Keeping track of how much value we already collected across other paths. Helps to decide:
- // - how much a new path should be transferring (upper bound);
- // - whether a channel should be disregarded because
- // it's available liquidity is too small comparing to how much more we need to collect;
- // - when we want to stop looking for new paths.
+ // Keeping track of how much value we already collected across other paths. Helps to decide
+ // when we want to stop looking for new paths.
let mut already_collected_value_msat = 0;
for (_, channels) in first_hop_targets.iter_mut() {
*used_liquidity_msat
});
- // Routing Fragmentation Mitigation heuristic:
- //
- // Routing fragmentation across many payment paths increases the overall routing
- // fees as you have irreducible routing fees per-link used (`fee_base_msat`).
- // Taking too many smaller paths also increases the chance of payment failure.
- // Thus to avoid this effect, we require from our collected links to provide
- // at least a minimal contribution to the recommended value yet-to-be-fulfilled.
- //
- // This requirement is currently 5% of the remaining-to-be-collected value.
- // This means as we successfully advance in our collection,
- // the absolute liquidity contribution is lowered,
- // thus increasing the number of potential channels to be selected.
-
- // Derive the minimal liquidity contribution with a ratio of 20 (5%, rounded up)
- // or 100% if we're not allowed to do multipath payments.
- let minimal_value_contribution_msat: u64 = if allow_mpp {
- (recommended_value_msat - already_collected_value_msat + 19) / 20
- } else {
- final_value_msat
- };
// Verify the liquidity offered by this channel complies to the minimal contribution.
let contributes_sufficient_value = available_value_contribution_msat >= minimal_value_contribution_msat;
// Do not consider candidate hops that would exceed the maximum path length.
*used_channel_liquidities.entry((victim_scid, true)).or_default() = exhausted;
}
- // Track the total amount all our collected paths allow to send so that we:
- // - know when to stop looking for more paths
- // - know which of the hops are useless considering how much more sats we need
- // (contributes_sufficient_value)
+ // Track the total amount all our collected paths allow to send so that we know
+ // when to stop looking for more paths
already_collected_value_msat += value_contribution_msat;
payment_paths.push(payment_path);
});
selected_paths.push(path);
}
+ // Make sure we would never create a route with more paths than we allow.
+ debug_assert!(selected_paths.len() <= payment_params.max_mpp_path_count.into());
if let Some(features) = &payment_params.features {
for path in selected_paths.iter_mut() {
///
/// Re-uses logic from `find_route`, so the restrictions described there also apply here.
pub fn build_route_from_hops<L: Deref>(
- our_node_pubkey: &PublicKey, hops: &[PublicKey], route_params: &RouteParameters, network: &NetworkGraph,
- logger: L, random_seed_bytes: &[u8; 32]
+ our_node_pubkey: &PublicKey, hops: &[PublicKey], route_params: &RouteParameters,
+ network_graph: &ReadOnlyNetworkGraph, logger: L, random_seed_bytes: &[u8; 32]
) -> Result<Route, LightningError>
where L::Target: Logger {
- let network_graph = network.read_only();
let mut route = build_route_from_hops_internal(
our_node_pubkey, hops, &route_params.payment_params, &network_graph,
route_params.final_value_msat, route_params.final_cltv_expiry_delta, logger, random_seed_bytes)?;
#[cfg(test)]
mod tests {
- use routing::network_graph::{NetworkGraph, NetGraphMsgHandler, NodeId};
+ use routing::gossip::{NetworkGraph, P2PGossipSync, NodeId};
use routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features,
PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees,
DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE};
// Using the same keys for LN and BTC ids
fn add_channel(
- net_graph_msg_handler: &NetGraphMsgHandler<Arc<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+ gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, 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);
bitcoin_signature_2: secp_ctx.sign_ecdsa(&msghash, node_2_privkey),
contents: unsigned_announcement.clone(),
};
- match net_graph_msg_handler.handle_channel_announcement(&valid_announcement) {
+ match gossip_sync.handle_channel_announcement(&valid_announcement) {
Ok(res) => assert!(res),
_ => panic!()
};
}
fn update_channel(
- net_graph_msg_handler: &NetGraphMsgHandler<Arc<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+ gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, 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()[..])[..]);
contents: update.clone()
};
- match net_graph_msg_handler.handle_channel_update(&valid_channel_update) {
+ match gossip_sync.handle_channel_update(&valid_channel_update) {
Ok(res) => assert!(res),
Err(_) => panic!()
};
}
fn add_or_update_node(
- net_graph_msg_handler: &NetGraphMsgHandler<Arc<NetworkGraph>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+ gossip_sync: &P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, 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);
contents: unsigned_announcement.clone()
};
- match net_graph_msg_handler.handle_node_announcement(&valid_announcement) {
+ match gossip_sync.handle_node_announcement(&valid_announcement) {
Ok(_) => (),
Err(_) => panic!()
};
}
fn build_line_graph() -> (
- Secp256k1<All>, sync::Arc<NetworkGraph>, NetGraphMsgHandler<sync::Arc<NetworkGraph>,
- sync::Arc<test_utils::TestChainSource>, sync::Arc<crate::util::test_utils::TestLogger>>,
+ Secp256k1<All>, sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
+ P2PGossipSync<sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>>,
sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>,
) {
let secp_ctx = Secp256k1::new();
let logger = Arc::new(test_utils::TestLogger::new());
let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
- let network_graph = Arc::new(NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()));
- let net_graph_msg_handler = NetGraphMsgHandler::new(Arc::clone(&network_graph), None, Arc::clone(&logger));
+ let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
+ let network_graph = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+ let gossip_sync = P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger));
// Build network from our_id to node 19:
// our_id -1(1)2- node0 -1(2)2- node1 - ... - node19
for (idx, (cur_privkey, next_privkey)) in core::iter::once(&our_privkey)
.chain(privkeys.iter()).zip(privkeys.iter()).enumerate() {
let cur_short_channel_id = (idx as u64) + 1;
- add_channel(&net_graph_msg_handler, &secp_ctx, &cur_privkey, &next_privkey,
+ add_channel(&gossip_sync, &secp_ctx, &cur_privkey, &next_privkey,
ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), cur_short_channel_id);
- update_channel(&net_graph_msg_handler, &secp_ctx, &cur_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &cur_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: cur_short_channel_id,
timestamp: idx as u32,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &next_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &next_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: cur_short_channel_id,
timestamp: (idx as u32)+1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, next_privkey,
+ add_or_update_node(&gossip_sync, &secp_ctx, next_privkey,
NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
}
- (secp_ctx, network_graph, net_graph_msg_handler, chain_monitor, logger)
+ (secp_ctx, network_graph, gossip_sync, chain_monitor, logger)
}
fn build_graph() -> (
Secp256k1<All>,
- sync::Arc<NetworkGraph>,
- NetGraphMsgHandler<sync::Arc<NetworkGraph>, sync::Arc<test_utils::TestChainSource>, sync::Arc<crate::util::test_utils::TestLogger>>,
+ sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
+ P2PGossipSync<sync::Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>>,
sync::Arc<test_utils::TestChainSource>,
sync::Arc<test_utils::TestLogger>,
) {
let secp_ctx = Secp256k1::new();
let logger = Arc::new(test_utils::TestLogger::new());
let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
- let network_graph = Arc::new(NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()));
- let net_graph_msg_handler = NetGraphMsgHandler::new(Arc::clone(&network_graph), None, Arc::clone(&logger));
+ let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
+ let network_graph = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+ let gossip_sync = P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger));
// Build network from our_id to node6:
//
// -1(1)2- node0 -1(3)2-
let (our_privkey, _, privkeys, _) = get_nodes(&secp_ctx);
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[0], ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), 1);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 1,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[0], NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[0], NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(2)), 2);
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 1,
fee_proportional_millionths: u32::max_value(),
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 1,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[1], NodeFeatures::from_le_bytes(id_to_feature_flags(2)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[1], NodeFeatures::from_le_bytes(id_to_feature_flags(2)), 0);
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[7], ChannelFeatures::from_le_bytes(id_to_feature_flags(12)), 12);
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 1,
fee_proportional_millionths: u32::max_value(),
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 1,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[7], NodeFeatures::from_le_bytes(id_to_feature_flags(8)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[7], NodeFeatures::from_le_bytes(id_to_feature_flags(8)), 0);
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 3);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 1,
excess_data: Vec::new()
});
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[1], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(4)), 4);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 1,
fee_proportional_millionths: 1000000,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 1,
excess_data: Vec::new()
});
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[7], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(13)), 13);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 1,
fee_proportional_millionths: 2000000,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 1,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[2], NodeFeatures::from_le_bytes(id_to_feature_flags(3)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[2], NodeFeatures::from_le_bytes(id_to_feature_flags(3)), 0);
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 1,
excess_data: Vec::new(),
});
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(11)), 11);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 1,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[4], NodeFeatures::from_le_bytes(id_to_feature_flags(5)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[4], NodeFeatures::from_le_bytes(id_to_feature_flags(5)), 0);
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[3], NodeFeatures::from_le_bytes(id_to_feature_flags(4)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[3], NodeFeatures::from_le_bytes(id_to_feature_flags(4)), 0);
- 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 {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[5], ChannelFeatures::from_le_bytes(id_to_feature_flags(7)), 7);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 1,
fee_proportional_millionths: 1000000,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[5], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[5], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 1,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[5], NodeFeatures::from_le_bytes(id_to_feature_flags(6)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[5], NodeFeatures::from_le_bytes(id_to_feature_flags(6)), 0);
- (secp_ctx, network_graph, net_graph_msg_handler, chain_monitor, logger)
+ (secp_ctx, network_graph, gossip_sync, chain_monitor, logger)
}
#[test]
#[test]
fn htlc_minimum_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let payment_params = PaymentParameters::from_node_id(nodes[2]);
let scorer = test_utils::TestScorer::with_penalty(0);
// Simple route to 2 via 1
// Disable other paths
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
// Check against amount_to_transfer_over_msat.
// Set minimal HTLC of 200_000_000 msat.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 3,
// Second hop only allows to forward 199_999_999 at most, thus not allowing the first hop to
// be used.
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 3,
} else { panic!(); }
// Lift the restriction on the first hop.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 4,
#[test]
fn htlc_minimum_overpay_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let payment_params = PaymentParameters::from_node_id(nodes[2]).with_features(InvoiceFeatures::known());
let scorer = test_utils::TestScorer::with_penalty(0);
// A route to node#2 via two paths.
// One path allows transferring 35-40 sats, another one also allows 35-40 sats.
// Thus, they can't send 60 without overpaying.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 3,
});
// Make 0 fee.
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
});
// Disable other paths
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 3,
// Now, test that if there are 2 paths, a "cheaper" by fee path wouldn't be prioritized
// while taking even more fee to match htlc_minimum_msat.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 4,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 3,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 4,
#[test]
fn disable_channels_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let payment_params = PaymentParameters::from_node_id(nodes[2]);
let scorer = test_utils::TestScorer::with_penalty(0);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
// // Disable channels 4 and 12 by flags=2
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
#[test]
fn disable_node_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let payment_params = PaymentParameters::from_node_id(nodes[2]);
let scorer = test_utils::TestScorer::with_penalty(0);
// Disable nodes 1, 2, and 8 by requiring unknown feature bits
let mut unknown_features = NodeFeatures::known();
unknown_features.set_unknown_feature_required();
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[0], unknown_features.clone(), 1);
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[1], unknown_features.clone(), 1);
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[7], unknown_features.clone(), 1);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[0], unknown_features.clone(), 1);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[1], unknown_features.clone(), 1);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[7], unknown_features.clone(), 1);
// If all nodes require some features we don't understand, route should fail
if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes) {
#[test]
fn multi_hint_last_hops_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let last_hops = multi_hop_last_hops_hint([nodes[2], nodes[3]]);
let payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops.clone());
// Test shows that multiple hop hints are considered.
// Disabling channels 6 & 7 by flags=2
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
#[test]
fn private_multi_hint_last_hops_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let non_announced_privkey = SecretKey::from_slice(&hex::decode(format!("{:02x}", 0xf0).repeat(32)).unwrap()[..]).unwrap();
// Test shows that multiple hop hints are considered.
// Disabling channels 6 & 7 by flags=2
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
- get_route(&source_node_id, &payment_params, &NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()).read_only(),
- Some(&our_chans.iter().collect::<Vec<_>>()), route_val, 42, &test_utils::TestLogger::new(), &scorer, &random_seed_bytes)
+ let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
+ let logger = test_utils::TestLogger::new();
+ let network_graph = NetworkGraph::new(genesis_hash, &logger);
+ let route = get_route(&source_node_id, &payment_params, &network_graph.read_only(),
+ Some(&our_chans.iter().collect::<Vec<_>>()), route_val, 42, &logger, &scorer, &random_seed_bytes);
+ route
}
#[test]
fn available_amount_while_routing_test() {
// Tests whether we choose the correct available channel amount while routing.
- let (secp_ctx, network_graph, mut net_graph_msg_handler, chain_monitor, logger) = build_graph();
+ let (secp_ctx, network_graph, mut gossip_sync, chain_monitor, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// our node to node2 via node0: channels {1, 3}.
// First disable all other paths.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
// Make the first channel (#1) very permissive,
// and we will be testing all limits on the second channel.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
// First, let's see if routing works if we have absolutely no idea about the available amount.
// In this case, it should be set to 250_000 sats.
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
// Check that setting next_outbound_htlc_limit_msat in first_hops limits the channels.
// Disable channel #1 and use another first hop.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 3,
}
// Enable channel #1 back.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 4,
// Now let's see if routing works if we know only htlc_maximum_msat.
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 3,
// We can't change UTXO capacity on the fly, so we'll disable
// the existing channel and add another one with the capacity we need.
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 4,
.push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script().to_v0_p2wsh();
*chain_monitor.utxo_ret.lock().unwrap() = Ok(TxOut { value: 15, script_pubkey: good_script.clone() });
- net_graph_msg_handler.add_chain_access(Some(chain_monitor));
+ gossip_sync.add_chain_access(Some(chain_monitor));
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 333);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 333);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 333,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 333,
timestamp: 1,
}
// Now let's see if routing chooses htlc_maximum_msat over UTXO capacity.
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 333,
timestamp: 6,
fn available_liquidity_last_hop_test() {
// Check that available liquidity properly limits the path even when only
// one of the latter hops is limited.
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// Total capacity: 50 sats.
// Disable other potential paths.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
// Limit capacities
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 2,
#[test]
fn ignore_fee_first_hop_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let payment_params = PaymentParameters::from_node_id(nodes[2]);
// Path via node0 is channels {1, 3}. Limit them to 100 and 50 sats (total limit 50).
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
#[test]
fn simple_mpp_route_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// Their aggregate capacity will be 50 + 60 + 180 = 290 sats.
// Path via node0 is channels {1, 3}. Limit them to 100 and 50 sats (total limit 50).
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
// Path via node7 is channels {12, 13}. Limit them to 60 and 60 sats
// (total limit 60).
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
// Path via node1 is channels {2, 4}. Limit them to 200 and 180 sats
// (total capacity 180 sats).
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
#[test]
fn long_mpp_route_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// are used twice will have 200 sats capacity.
// Disable other potential paths.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
});
// Path via {node0, node2} is channels {1, 3, 5}.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
});
// Capacity of 200 sats because this channel will be used by 3rd path as well.
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 5,
timestamp: 2,
// Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
// Add 100 sats to the capacities of {12, 13}, because these channels
// are also used for 3rd path. 100 sats for the rest. Total capacity: 100 sats.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 2,
#[test]
fn mpp_cheaper_route_test() {
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// are used twice will have 200 sats capacity.
// Disable other potential paths.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
});
// Path via {node0, node2} is channels {1, 3, 5}.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
});
// Capacity of 200 sats because this channel will be used by 3rd path as well.
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 5,
timestamp: 2,
// Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
// Add 100 sats to the capacities of {12, 13}, because these channels
// are also used for 3rd path. 100 sats for the rest. Total capacity: 100 sats.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 2,
// This test makes sure that MPP algorithm properly takes into account
// fees charged on the channels, by making the fees impactful:
// if the fee is not properly accounted for, the behavior is different.
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// It's fine to ignore this concern for now.
// Disable other potential paths.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 7,
timestamp: 2,
});
// Path via {node0, node2} is channels {1, 3, 5}.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
excess_data: Vec::new()
});
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 5,
timestamp: 2,
// - channel 12 capacity is 250 sats
// - fee for channel 6 is 150 sats
// Let's test this by enforcing these 2 conditions and removing other limits.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 11,
timestamp: 2,
// to only have the remaining to-collect amount in available liquidity.
//
// This bug appeared in production in some specific channel configurations.
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// would first use the no-fee route and then fail to find a path along the second route as
// we think we can only send up to 1 additional sat over the last-hop but refuse to as its
// under 5% of our payment amount.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: u32::max_value(),
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: u32::max_value(),
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
fn drop_lowest_channel_mpp_route_test() {
// This test checks that low-capacity channel is dropped when after
// path finding we realize that we found more capacity than we need.
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// Their aggregate capacity will be 50 + 60 + 20 = 130 sats.
// Path via node0 is channels {1, 3}. Limit them to 100 and 50 sats (total limit 50);
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 2,
});
// Path via node7 is channels {12, 13}. Limit them to 60 and 60 sats (total limit 60);
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 13,
timestamp: 2,
});
// Path via node1 is channels {2, 4}. Limit them to 20 and 20 sats (total capacity 20 sats).
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
// payment) htlc_minimum_msat. In the original algorithm, this resulted in node4's
// "previous hop" being set to node 3, creating a loop in the path.
let secp_ctx = Secp256k1::new();
+ let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
let logger = Arc::new(test_utils::TestLogger::new());
- let network = Arc::new(NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()));
- let net_graph_msg_handler = NetGraphMsgHandler::new(Arc::clone(&network), None, Arc::clone(&logger));
+ let network = Arc::new(NetworkGraph::new(genesis_hash, Arc::clone(&logger)));
+ let gossip_sync = P2PGossipSync::new(Arc::clone(&network), None, Arc::clone(&logger));
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let payment_params = PaymentParameters::from_node_id(nodes[6]);
- add_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 6,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[1], NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[1], NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[1], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 5,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[4], NodeFeatures::from_le_bytes(id_to_feature_flags(4)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[4], NodeFeatures::from_le_bytes(id_to_feature_flags(4)), 0);
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(4)), 4);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(4)), 4);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[3], NodeFeatures::from_le_bytes(id_to_feature_flags(3)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[3], NodeFeatures::from_le_bytes(id_to_feature_flags(3)), 0);
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[3], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 3);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[3], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 3);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 3,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[2], NodeFeatures::from_le_bytes(id_to_feature_flags(2)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[2], NodeFeatures::from_le_bytes(id_to_feature_flags(2)), 0);
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(2)), 2);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(2)), 2);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 1,
excess_data: Vec::new()
});
- add_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], &privkeys[6], ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), 1);
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
+ add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[6], ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), 1);
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 1,
timestamp: 1,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[6], NodeFeatures::from_le_bytes(id_to_feature_flags(6)), 0);
+ add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[6], NodeFeatures::from_le_bytes(id_to_feature_flags(6)), 0);
{
// Now ensure the route flows simply over nodes 1 and 4 to 6.
// Test that if, while walking the graph, we find a hop that has exactly enough liquidity
// for us, including later hop fees, we take it. In the first version of our MPP algorithm
// we calculated fees on a higher value, resulting in us ignoring such paths.
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, _, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// We modify the graph to set the htlc_maximum of channel 2 to below the value we wish to
// send.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 12,
timestamp: 2,
// htlc_maximum_msat, we don't end up undershooting a later htlc_minimum_msat. In the
// initial version of MPP we'd accept such routes but reject them while recalculating fees,
// resulting in us thinking there is no possible path, even if other paths exist.
- let (secp_ctx, network_graph, net_graph_msg_handler, _, logger) = build_graph();
+ let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
let scorer = test_utils::TestScorer::with_penalty(0);
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
// We modify the graph to set the htlc_minimum of channel 2 and 4 as needed - channel 2
// gets an htlc_maximum_msat of 80_000 and channel 4 an htlc_minimum_msat of 90_000. We
// then try to send 90_000.
- update_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 2,
timestamp: 2,
fee_proportional_millionths: 0,
excess_data: Vec::new()
});
- update_channel(&net_graph_msg_handler, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
+ update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
short_channel_id: 4,
timestamp: 2,
// route over multiple channels with the same first hop.
let secp_ctx = Secp256k1::new();
let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
+ let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
let logger = Arc::new(test_utils::TestLogger::new());
- let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash());
+ let network_graph = NetworkGraph::new(genesis_hash, Arc::clone(&logger));
let scorer = test_utils::TestScorer::with_penalty(0);
let payment_params = PaymentParameters::from_node_id(nodes[0]).with_features(InvoiceFeatures::known());
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
seed
}
#[cfg(not(feature = "no-std"))]
- use util::ser::Readable;
+ use util::ser::ReadableArgs;
#[test]
#[cfg(not(feature = "no-std"))]
return;
},
};
- let graph = NetworkGraph::read(&mut d).unwrap();
+ let logger = test_utils::TestLogger::new();
+ let graph = NetworkGraph::read(&mut d, &logger).unwrap();
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let payment_params = PaymentParameters::from_node_id(dst);
let amt = seed as u64 % 200_000_000;
let params = ProbabilisticScoringParameters::default();
- let logger = test_utils::TestLogger::new();
let scorer = ProbabilisticScorer::new(params, &graph, &logger);
if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() {
continue 'load_endpoints;
return;
},
};
- let graph = NetworkGraph::read(&mut d).unwrap();
+ let logger = test_utils::TestLogger::new();
+ let graph = NetworkGraph::read(&mut d, &logger).unwrap();
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
let payment_params = PaymentParameters::from_node_id(dst).with_features(InvoiceFeatures::known());
let amt = seed as u64 % 200_000_000;
let params = ProbabilisticScoringParameters::default();
- let logger = test_utils::TestLogger::new();
let scorer = ProbabilisticScorer::new(params, &graph, &logger);
if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() {
continue 'load_endpoints;
use chain::keysinterface::{KeysManager,KeysInterface};
use ln::channelmanager::{ChannelCounterparty, ChannelDetails};
use ln::features::{InitFeatures, InvoiceFeatures};
+ use routing::gossip::NetworkGraph;
use routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
use util::logger::{Logger, Record};
- use util::test_utils::TestLogger;
+ use util::ser::ReadableArgs;
use test::Bencher;
fn log(&self, _record: &Record) {}
}
- fn read_network_graph() -> NetworkGraph {
+ fn read_network_graph(logger: &DummyLogger) -> NetworkGraph<&DummyLogger> {
let mut d = test_utils::get_route_file().unwrap();
- NetworkGraph::read(&mut d).unwrap()
+ NetworkGraph::read(&mut d, logger).unwrap()
}
fn payer_pubkey() -> PublicKey {
#[bench]
fn generate_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
- let network_graph = read_network_graph();
+ let logger = DummyLogger {};
+ let network_graph = read_network_graph(&logger);
let scorer = FixedPenaltyScorer::with_penalty(0);
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
}
#[bench]
fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
- let network_graph = read_network_graph();
+ let logger = DummyLogger {};
+ let network_graph = read_network_graph(&logger);
let scorer = FixedPenaltyScorer::with_penalty(0);
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::known());
}
#[bench]
fn generate_routes_with_probabilistic_scorer(bench: &mut Bencher) {
- let logger = TestLogger::new();
- let network_graph = read_network_graph();
+ let logger = DummyLogger {};
+ let network_graph = read_network_graph(&logger);
let params = ProbabilisticScoringParameters::default();
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
#[bench]
fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) {
- let logger = TestLogger::new();
- let network_graph = read_network_graph();
+ let logger = DummyLogger {};
+ let network_graph = read_network_graph(&logger);
let params = ProbabilisticScoringParameters::default();
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::known());
}
fn generate_routes<S: Score>(
- bench: &mut Bencher, graph: &NetworkGraph, mut scorer: S, features: InvoiceFeatures
+ bench: &mut Bencher, graph: &NetworkGraph<&DummyLogger>, mut scorer: S,
+ features: InvoiceFeatures
) {
let nodes = graph.read_only().nodes().clone();
let payer = payer_pubkey();