From a6e650630d7696a0f4de4776d8543d4cfd1a1ed0 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 17 Aug 2021 11:12:18 -0500 Subject: [PATCH 01/10] Pass Event by reference to EventHandler Passing an Event by reference rather and by move gives more flexibility for composing event handlers without needing to clone events. --- lightning-background-processor/src/lib.rs | 20 ++++++++++---------- lightning-net-tokio/src/lib.rs | 22 ++++++++++------------ lightning/src/chain/chainmonitor.rs | 4 ++-- lightning/src/ln/channelmanager.rs | 4 ++-- lightning/src/util/events.rs | 6 +++--- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 34cddd1a6aa..45b33fd1fc5 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -345,7 +345,7 @@ mod tests { begin_open_channel!($node_a, $node_b, $channel_value); let events = $node_a.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); - let (temporary_channel_id, tx) = handle_funding_generation_ready!(events[0], $channel_value); + let (temporary_channel_id, tx) = handle_funding_generation_ready!(&events[0], $channel_value); end_open_channel!($node_a, $node_b, temporary_channel_id, tx); tx }} @@ -362,14 +362,14 @@ mod tests { macro_rules! handle_funding_generation_ready { ($event: expr, $channel_value: expr) => {{ match $event { - Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => { - assert_eq!(*channel_value_satoshis, $channel_value); + &Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, ref output_script, user_channel_id } => { + assert_eq!(channel_value_satoshis, $channel_value); assert_eq!(user_channel_id, 42); let tx = Transaction { version: 1 as i32, lock_time: 0, input: Vec::new(), output: vec![TxOut { - value: *channel_value_satoshis, script_pubkey: output_script.clone(), + value: channel_value_satoshis, script_pubkey: output_script.clone(), }]}; - (*temporary_channel_id, tx) + (temporary_channel_id, tx) }, _ => panic!("Unexpected event"), } @@ -423,7 +423,7 @@ mod tests { // Initiate the background processors to watch each node. let data_dir = nodes[0].persister.get_data_dir(); let persister = move |node: &ChannelManager, Arc, Arc, Arc, Arc>| FilesystemPersister::persist_manager(data_dir.clone(), node); - let event_handler = |_| {}; + let event_handler = |_: &_| {}; let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); macro_rules! check_persisted_data { @@ -476,7 +476,7 @@ mod tests { let nodes = create_nodes(1, "test_timer_tick_called".to_string()); let data_dir = nodes[0].persister.get_data_dir(); let persister = move |node: &ChannelManager, Arc, Arc, Arc, Arc>| FilesystemPersister::persist_manager(data_dir.clone(), node); - let event_handler = |_| {}; + let event_handler = |_: &_| {}; let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); loop { let log_entries = nodes[0].logger.lines.lock().unwrap(); @@ -498,7 +498,7 @@ mod tests { open_channel!(nodes[0], nodes[1], 100000); let persister = |_: &_| Err(std::io::Error::new(std::io::ErrorKind::Other, "test")); - let event_handler = |_| {}; + let event_handler = |_: &_| {}; let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); match bg_processor.join() { Ok(_) => panic!("Expected error persisting manager"), @@ -518,7 +518,7 @@ mod tests { // Set up a background event handler for FundingGenerationReady events. let (sender, receiver) = std::sync::mpsc::sync_channel(1); - let event_handler = move |event| { + let event_handler = move |event: &Event| { sender.send(handle_funding_generation_ready!(event, channel_value)).unwrap(); }; let bg_processor = BackgroundProcessor::start(persister.clone(), event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); @@ -544,7 +544,7 @@ mod tests { // Set up a background event handler for SpendableOutputs events. let (sender, receiver) = std::sync::mpsc::sync_channel(1); - let event_handler = move |event| sender.send(event).unwrap(); + let event_handler = move |event: &Event| sender.send(event.clone()).unwrap(); let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); // Force close the channel and check that the SpendableOutputs event was handled. diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index 25c161d2aeb..bf411211fdb 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -43,13 +43,12 @@ //! async fn connect_to_node(peer_manager: PeerManager, chain_monitor: Arc, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) { //! lightning_net_tokio::connect_outbound(peer_manager, their_node_id, addr).await; //! loop { -//! channel_manager.await_persistable_update(); -//! channel_manager.process_pending_events(&|event| { -//! // Handle the event! -//! }); -//! chain_monitor.process_pending_events(&|event| { +//! let event_handler = |event: &Event| { //! // Handle the event! -//! }); +//! }; +//! channel_manager.await_persistable_update(); +//! channel_manager.process_pending_events(&event_handler); +//! chain_monitor.process_pending_events(&event_handler); //! } //! } //! @@ -57,13 +56,12 @@ //! async fn accept_socket(peer_manager: PeerManager, chain_monitor: Arc, channel_manager: ChannelManager, socket: TcpStream) { //! lightning_net_tokio::setup_inbound(peer_manager, socket); //! loop { -//! channel_manager.await_persistable_update(); -//! channel_manager.process_pending_events(&|event| { -//! // Handle the event! -//! }); -//! chain_monitor.process_pending_events(&|event| { +//! let event_handler = |event: &Event| { //! // Handle the event! -//! }); +//! }; +//! channel_manager.await_persistable_update(); +//! channel_manager.process_pending_events(&event_handler); +//! chain_monitor.process_pending_events(&event_handler); //! } //! } //! ``` diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index 8969427a0f9..524035e96d7 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -144,7 +144,7 @@ where C::Target: chain::Filter, pub fn get_and_clear_pending_events(&self) -> Vec { use util::events::EventsProvider; let events = core::cell::RefCell::new(Vec::new()); - let event_handler = |event| events.borrow_mut().push(event); + let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone()); self.process_pending_events(&event_handler); events.into_inner() } @@ -332,7 +332,7 @@ impl even pending_events.append(&mut monitor.get_and_clear_pending_events()); } for event in pending_events.drain(..) { - handler.handle_event(event); + handler.handle_event(&event); } } } diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index ac2297f86ae..7ecdd8eaade 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4167,7 +4167,7 @@ impl ChannelMana #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] pub fn get_and_clear_pending_events(&self) -> Vec { let events = core::cell::RefCell::new(Vec::new()); - let event_handler = |event| events.borrow_mut().push(event); + let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone()); self.process_pending_events(&event_handler); events.into_inner() } @@ -4244,7 +4244,7 @@ where } for event in pending_events.drain(..) { - handler.handle_event(event); + handler.handle_event(&event); } result diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 1780483cb8b..d4288164cd9 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -561,11 +561,11 @@ pub trait EventHandler { /// Handles the given [`Event`]. /// /// See [`EventsProvider`] for details that must be considered when implementing this method. - fn handle_event(&self, event: Event); + fn handle_event(&self, event: &Event); } -impl EventHandler for F where F: Fn(Event) { - fn handle_event(&self, event: Event) { +impl EventHandler for F where F: Fn(&Event) { + fn handle_event(&self, event: &Event) { self(event) } } From 777661ae520c9ca969e6359bff05e561011eb336 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Mon, 9 Aug 2021 22:24:41 -0500 Subject: [PATCH 02/10] Individually lock NetworkGraph fields In preparation for giving NetworkGraph shared ownership, wrap individual fields in RwLock. This allows removing the outer RwLock used in NetGraphMsgHandler. --- lightning/src/routing/network_graph.rs | 99 ++++++++++++++++---------- lightning/src/routing/router.rs | 40 ++++++----- 2 files changed, 84 insertions(+), 55 deletions(-) diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 8accdab6088..3b593351fac 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -51,11 +51,11 @@ const MAX_EXCESS_BYTES_FOR_RELAY: usize = 1024; const MAX_SCIDS_PER_REPLY: usize = 8000; /// Represents the network as nodes and channels between them -#[derive(Clone, PartialEq)] pub struct NetworkGraph { genesis_hash: BlockHash, - channels: BTreeMap, - nodes: BTreeMap, + // Lock order: channels -> nodes + channels: RwLock>, + nodes: RwLock>, } /// A simple newtype for RwLockReadGuard<'a, NetworkGraph>. @@ -193,7 +193,8 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(ChannelAnnouncement, Option, Option)> { let network_graph = self.network_graph.read().unwrap(); let mut result = Vec::with_capacity(batch_amount as usize); - let mut iter = network_graph.get_channels().range(starting_point..); + let channels = network_graph.get_channels(); + let mut iter = channels.range(starting_point..); while result.len() < batch_amount as usize { if let Some((_, ref chan)) = iter.next() { if chan.announcement_message.is_some() { @@ -221,12 +222,13 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh fn get_next_node_announcements(&self, starting_point: Option<&PublicKey>, batch_amount: u8) -> Vec { let network_graph = self.network_graph.read().unwrap(); let mut result = Vec::with_capacity(batch_amount as usize); + let nodes = network_graph.get_nodes(); let mut iter = if let Some(pubkey) = starting_point { - let mut iter = network_graph.get_nodes().range((*pubkey)..); + let mut iter = nodes.range((*pubkey)..); iter.next(); iter } else { - network_graph.get_nodes().range(..) + nodes.range(..) }; while result.len() < batch_amount as usize { if let Some((_, ref node)) = iter.next() { @@ -616,13 +618,15 @@ impl Writeable for NetworkGraph { write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); self.genesis_hash.write(writer)?; - (self.channels.len() as u64).write(writer)?; - for (ref chan_id, ref chan_info) in self.channels.iter() { + let channels = self.channels.read().unwrap(); + (channels.len() as u64).write(writer)?; + for (ref chan_id, ref chan_info) in channels.iter() { (*chan_id).write(writer)?; chan_info.write(writer)?; } - (self.nodes.len() as u64).write(writer)?; - for (ref node_id, ref node_info) in self.nodes.iter() { + let nodes = self.nodes.read().unwrap(); + (nodes.len() as u64).write(writer)?; + for (ref node_id, ref node_info) in nodes.iter() { node_id.write(writer)?; node_info.write(writer)?; } @@ -655,8 +659,8 @@ impl Readable for NetworkGraph { Ok(NetworkGraph { genesis_hash, - channels, - nodes, + channels: RwLock::new(channels), + nodes: RwLock::new(nodes), }) } } @@ -664,36 +668,49 @@ impl Readable for NetworkGraph { impl fmt::Display for NetworkGraph { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { writeln!(f, "Network map\n[Channels]")?; - for (key, val) in self.channels.iter() { + for (key, val) in self.channels.read().unwrap().iter() { writeln!(f, " {}: {}", key, val)?; } writeln!(f, "[Nodes]")?; - for (key, val) in self.nodes.iter() { + for (key, val) in self.nodes.read().unwrap().iter() { writeln!(f, " {}: {}", log_pubkey!(key), val)?; } Ok(()) } } +impl PartialEq for NetworkGraph { + fn eq(&self, other: &Self) -> bool { + self.genesis_hash == other.genesis_hash && + *self.channels.read().unwrap() == *other.channels.read().unwrap() && + *self.nodes.read().unwrap() == *other.nodes.read().unwrap() + } +} + impl NetworkGraph { /// Returns all known valid channels' short ids along with announced channel info. /// /// (C-not exported) because we have no mapping for `BTreeMap`s - pub fn get_channels<'a>(&'a self) -> &'a BTreeMap { &self.channels } + pub fn get_channels(&self) -> RwLockReadGuard<'_, BTreeMap> { + self.channels.read().unwrap() + } + /// Returns all known nodes' public keys along with announced node info. /// /// (C-not exported) because we have no mapping for `BTreeMap`s - pub fn get_nodes<'a>(&'a self) -> &'a BTreeMap { &self.nodes } + pub fn get_nodes(&self) -> RwLockReadGuard<'_, BTreeMap> { + self.nodes.read().unwrap() + } /// Get network addresses by node id. /// Returns None if the requested node is completely unknown, /// or if node announcement for the node was never received. /// /// (C-not exported) as there is no practical way to track lifetimes of returned values. - pub fn get_addresses<'a>(&'a self, pubkey: &PublicKey) -> Option<&'a Vec> { - if let Some(node) = self.nodes.get(pubkey) { + pub fn get_addresses(&self, pubkey: &PublicKey) -> Option> { + if let Some(node) = self.nodes.read().unwrap().get(pubkey) { if let Some(node_info) = node.announcement_info.as_ref() { - return Some(&node_info.addresses) + return Some(node_info.addresses.clone()) } } None @@ -703,8 +720,8 @@ impl NetworkGraph { pub fn new(genesis_hash: BlockHash) -> NetworkGraph { Self { genesis_hash, - channels: BTreeMap::new(), - nodes: BTreeMap::new(), + channels: RwLock::new(BTreeMap::new()), + nodes: RwLock::new(BTreeMap::new()), } } @@ -729,7 +746,7 @@ impl NetworkGraph { } fn update_node_from_announcement_intern(&mut self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>) -> Result<(), LightningError> { - match self.nodes.get_mut(&msg.node_id) { + match self.nodes.write().unwrap().get_mut(&msg.node_id) { None => Err(LightningError{err: "No existing channels for node_announcement".to_owned(), action: ErrorAction::IgnoreError}), Some(node) => { if let Some(node_info) = node.announcement_info.as_ref() { @@ -838,7 +855,9 @@ impl NetworkGraph { { full_msg.cloned() } else { None }, }; - match self.channels.entry(msg.short_channel_id) { + let mut channels = self.channels.write().unwrap(); + let mut nodes = self.nodes.write().unwrap(); + match channels.entry(msg.short_channel_id) { BtreeEntry::Occupied(mut entry) => { //TODO: because asking the blockchain if short_channel_id is valid is only optional //in the blockchain API, we need to handle it smartly here, though it's unclear @@ -852,7 +871,7 @@ impl NetworkGraph { // b) we don't track UTXOs of channels we know about and remove them if they // get reorg'd out. // c) it's unclear how to do so without exposing ourselves to massive DoS risk. - Self::remove_channel_in_nodes(&mut self.nodes, &entry.get(), msg.short_channel_id); + Self::remove_channel_in_nodes(&mut nodes, &entry.get(), msg.short_channel_id); *entry.get_mut() = chan_info; } else { return Err(LightningError{err: "Already have knowledge of channel".to_owned(), action: ErrorAction::IgnoreAndLog(Level::Trace)}) @@ -865,7 +884,7 @@ impl NetworkGraph { macro_rules! add_channel_to_node { ( $node_id: expr ) => { - match self.nodes.entry($node_id) { + match nodes.entry($node_id) { BtreeEntry::Occupied(node_entry) => { node_entry.into_mut().channels.push(msg.short_channel_id); }, @@ -891,12 +910,14 @@ impl NetworkGraph { /// May cause the removal of nodes too, if this was their last channel. /// If not permanent, makes channels unavailable for routing. pub fn close_channel_from_update(&mut self, short_channel_id: u64, is_permanent: bool) { + let mut channels = self.channels.write().unwrap(); if is_permanent { - if let Some(chan) = self.channels.remove(&short_channel_id) { - Self::remove_channel_in_nodes(&mut self.nodes, &chan, short_channel_id); + if let Some(chan) = channels.remove(&short_channel_id) { + let mut nodes = self.nodes.write().unwrap(); + Self::remove_channel_in_nodes(&mut nodes, &chan, short_channel_id); } } else { - if let Some(chan) = self.channels.get_mut(&short_channel_id) { + if let Some(chan) = channels.get_mut(&short_channel_id) { if let Some(one_to_two) = chan.one_to_two.as_mut() { one_to_two.enabled = false; } @@ -937,7 +958,8 @@ impl NetworkGraph { let chan_enabled = msg.flags & (1 << 1) != (1 << 1); let chan_was_enabled; - match self.channels.get_mut(&msg.short_channel_id) { + let mut channels = self.channels.write().unwrap(); + match channels.get_mut(&msg.short_channel_id) { None => return Err(LightningError{err: "Couldn't find channel for update".to_owned(), action: ErrorAction::IgnoreError}), Some(channel) => { if let OptionalField::Present(htlc_maximum_msat) = msg.htlc_maximum_msat { @@ -1000,8 +1022,9 @@ impl NetworkGraph { } } + let mut nodes = self.nodes.write().unwrap(); if chan_enabled { - let node = self.nodes.get_mut(&dest_node_id).unwrap(); + let node = nodes.get_mut(&dest_node_id).unwrap(); let mut base_msat = msg.fee_base_msat; let mut proportional_millionths = msg.fee_proportional_millionths; if let Some(fees) = node.lowest_inbound_channel_fees { @@ -1013,11 +1036,11 @@ impl NetworkGraph { proportional_millionths }); } else if chan_was_enabled { - let node = self.nodes.get_mut(&dest_node_id).unwrap(); + let node = nodes.get_mut(&dest_node_id).unwrap(); let mut lowest_inbound_channel_fees = None; for chan_id in node.channels.iter() { - let chan = self.channels.get(chan_id).unwrap(); + let chan = channels.get(chan_id).unwrap(); let chan_info_opt; if chan.node_one == dest_node_id { chan_info_opt = chan.two_to_one.as_ref(); @@ -1268,7 +1291,7 @@ mod tests { match network.get_channels().get(&unsigned_announcement.short_channel_id) { None => panic!(), Some(_) => () - } + }; } // If we receive announcement for the same channel (with UTXO lookups disabled), @@ -1320,7 +1343,7 @@ mod tests { match network.get_channels().get(&unsigned_announcement.short_channel_id) { None => panic!(), Some(_) => () - } + }; } // If we receive announcement for the same channel (but TX is not confirmed), @@ -1353,7 +1376,7 @@ mod tests { assert_eq!(channel_entry.features, ChannelFeatures::empty()); }, _ => panic!() - } + }; } // Don't relay valid channels with excess data @@ -1484,7 +1507,7 @@ mod tests { assert_eq!(channel_info.one_to_two.as_ref().unwrap().cltv_expiry_delta, 144); assert!(channel_info.two_to_one.is_none()); } - } + }; } unsigned_channel_update.timestamp += 100; @@ -1645,7 +1668,7 @@ mod tests { Some(channel_info) => { assert!(channel_info.one_to_two.is_some()); } - } + }; } let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed { @@ -1663,7 +1686,7 @@ mod tests { Some(channel_info) => { assert!(!channel_info.one_to_two.as_ref().unwrap().enabled); } - } + }; } let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed { diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 5030f6aaacb..3df942d733a 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -443,6 +443,8 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // to use as the A* heuristic beyond just the cost to get one node further than the current // one. + let network_channels = network.get_channels(); + let network_nodes = network.get_nodes(); let dummy_directional_info = DummyDirectionalChannelInfo { // used for first_hops routes cltv_expiry_delta: 0, htlc_minimum_msat: 0, @@ -458,7 +460,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // work reliably. let allow_mpp = if let Some(features) = &payee_features { features.supports_basic_mpp() - } else if let Some(node) = network.get_nodes().get(&payee) { + } else if let Some(node) = network_nodes.get(&payee) { if let Some(node_info) = node.announcement_info.as_ref() { node_info.features.supports_basic_mpp() } else { false } @@ -492,7 +494,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // Map from node_id to information about the best current path to that node, including feerate // information. - let mut dist = HashMap::with_capacity(network.get_nodes().len()); + let mut dist = HashMap::with_capacity(network_nodes.len()); // During routing, if we ignore a path due to an htlc_minimum_msat limit, we set this, // indicating that we may wish to try again with a higher value, potentially paying to meet an @@ -511,7 +513,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // This map allows paths to be aware of the channel use by other paths in the same call. // This would help to make a better path finding decisions and not "overbook" channels. // It is unaware of the directions (except for `outbound_capacity_msat` in `first_hops`). - let mut bookkeeped_channels_liquidity_available_msat = HashMap::with_capacity(network.get_nodes().len()); + let mut bookkeeped_channels_liquidity_available_msat = 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); @@ -629,7 +631,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // as a way to reach the $dest_node_id. let mut fee_base_msat = u32::max_value(); let mut fee_proportional_millionths = u32::max_value(); - if let Some(Some(fees)) = network.get_nodes().get(&$src_node_id).map(|node| node.lowest_inbound_channel_fees) { + if let Some(Some(fees)) = network_nodes.get(&$src_node_id).map(|node| node.lowest_inbound_channel_fees) { fee_base_msat = fees.base_msat; fee_proportional_millionths = fees.proportional_millionths; } @@ -814,7 +816,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye if !features.requires_unknown_bits() { for chan_id in $node.channels.iter() { - let chan = network.get_channels().get(chan_id).unwrap(); + let chan = network_channels.get(chan_id).unwrap(); if !chan.features.requires_unknown_bits() { if chan.node_one == *$node_id { // ie $node is one, ie next hop in A* is two, via the two_to_one channel @@ -862,7 +864,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // Add the payee as a target, so that the payee-to-payer // search algorithm knows what to start with. - match network.get_nodes().get(payee) { + match network_nodes.get(payee) { // The payee is not in our network graph, so nothing to add here. // There is still a chance of reaching them via last_hops though, // so don't yet fail the payment here. @@ -884,7 +886,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // we have a direct channel to the first hop or the first hop is // in the regular network graph. first_hop_targets.get(&first_hop_in_route.src_node_id).is_some() || - network.get_nodes().get(&first_hop_in_route.src_node_id).is_some(); + network_nodes.get(&first_hop_in_route.src_node_id).is_some(); if have_hop_src_in_graph { // We start building the path from reverse, i.e., from payee // to the first RouteHintHop in the path. @@ -991,7 +993,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye 'path_walk: loop { if let Some(&(_, _, _, ref features)) = first_hop_targets.get(&ordered_hops.last().unwrap().0.pubkey) { ordered_hops.last_mut().unwrap().1 = features.clone(); - } else if let Some(node) = network.get_nodes().get(&ordered_hops.last().unwrap().0.pubkey) { + } else if let Some(node) = network_nodes.get(&ordered_hops.last().unwrap().0.pubkey) { if let Some(node_info) = node.announcement_info.as_ref() { ordered_hops.last_mut().unwrap().1 = node_info.features.clone(); } else { @@ -1093,7 +1095,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // Otherwise, since the current target node is not us, // keep "unrolling" the payment graph from payee to payer by // finding a way to reach the current target from the payer side. - match network.get_nodes().get(&pubkey) { + match network_nodes.get(&pubkey) { None => {}, Some(node) => { add_entries_to_cheapest_to_target_node!(node, &pubkey, lowest_fee_to_node, value_contribution_msat, path_htlc_minimum_msat); @@ -4211,12 +4213,13 @@ mod tests { // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut seed = random_init_seed() as usize; + let nodes = graph.get_nodes(); 'load_endpoints: for _ in 0..10 { loop { seed = seed.overflowing_mul(0xdeadbeef).0; - let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let src = nodes.keys().skip(seed % nodes.len()).next().unwrap(); seed = seed.overflowing_mul(0xdeadbeef).0; - let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap(); let amt = seed as u64 % 200_000_000; if get_route(src, &graph, dst, None, None, &[], amt, 42, &test_utils::TestLogger::new()).is_ok() { continue 'load_endpoints; @@ -4239,12 +4242,13 @@ mod tests { // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut seed = random_init_seed() as usize; + let nodes = graph.get_nodes(); 'load_endpoints: for _ in 0..10 { loop { seed = seed.overflowing_mul(0xdeadbeef).0; - let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let src = nodes.keys().skip(seed % nodes.len()).next().unwrap(); seed = seed.overflowing_mul(0xdeadbeef).0; - let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap(); let amt = seed as u64 % 200_000_000; if get_route(src, &graph, dst, Some(InvoiceFeatures::known()), None, &[], amt, 42, &test_utils::TestLogger::new()).is_ok() { continue 'load_endpoints; @@ -4297,6 +4301,7 @@ mod benches { fn generate_routes(bench: &mut Bencher) { let mut d = test_utils::get_route_file().unwrap(); let graph = NetworkGraph::read(&mut d).unwrap(); + let nodes = graph.get_nodes(); // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut path_endpoints = Vec::new(); @@ -4304,9 +4309,9 @@ mod benches { 'load_endpoints: for _ in 0..100 { loop { seed *= 0xdeadbeef; - let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let src = nodes.keys().skip(seed % nodes.len()).next().unwrap(); seed *= 0xdeadbeef; - let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap(); let amt = seed as u64 % 1_000_000; if get_route(src, &graph, dst, None, None, &[], amt, 42, &DummyLogger{}).is_ok() { path_endpoints.push((src, dst, amt)); @@ -4328,6 +4333,7 @@ mod benches { fn generate_mpp_routes(bench: &mut Bencher) { let mut d = test_utils::get_route_file().unwrap(); let graph = NetworkGraph::read(&mut d).unwrap(); + let nodes = graph.get_nodes(); // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut path_endpoints = Vec::new(); @@ -4335,9 +4341,9 @@ mod benches { 'load_endpoints: for _ in 0..100 { loop { seed *= 0xdeadbeef; - let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let src = nodes.keys().skip(seed % nodes.len()).next().unwrap(); seed *= 0xdeadbeef; - let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap(); + let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap(); let amt = seed as u64 % 1_000_000; if get_route(src, &graph, dst, Some(InvoiceFeatures::known()), None, &[], amt, 42, &DummyLogger{}).is_ok() { path_endpoints.push((src, dst, amt)); From 16ad7f17a1cf0d1d57ffd0e15532a670b749e075 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 10 Aug 2021 09:47:27 -0500 Subject: [PATCH 03/10] Remove RwLock from around NetworkGraph Now that NetworkGraph uses interior mutability, the RwLock used around it in NetGraphMsgHandler is no longer needed. This allows for shared ownership without a lock. --- fuzz/src/full_stack.rs | 4 +- fuzz/src/router.rs | 2 +- lightning-invoice/src/utils.rs | 4 +- lightning/src/ln/chanmon_update_fail_tests.rs | 48 +++---- lightning/src/ln/channelmanager.rs | 16 +-- lightning/src/ln/functional_test_utils.rs | 10 +- lightning/src/ln/functional_tests.rs | 126 +++++++++--------- lightning/src/ln/onion_route_tests.rs | 4 +- lightning/src/ln/shutdown_tests.rs | 6 +- lightning/src/routing/network_graph.rs | 118 +++++++--------- lightning/src/routing/router.rs | 102 +++++++------- 11 files changed, 210 insertions(+), 230 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 28592ffda51..ee7b2d18ae3 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -434,7 +434,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { }, 4 => { let value = slice_to_be24(get_slice!(3)) as u64; - let route = match get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) { + let route = match get_route(&our_id, &net_graph_msg_handler.network_graph, &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) { Ok(route) => route, Err(_) => return, }; @@ -451,7 +451,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { }, 15 => { let value = slice_to_be24(get_slice!(3)) as u64; - let mut route = match get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) { + let mut route = match get_route(&our_id, &net_graph_msg_handler.network_graph, &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) { Ok(route) => route, Err(_) => return, }; diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index baa32312ee9..6c792916f82 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -160,7 +160,7 @@ pub fn do_test(data: &[u8], out: Out) { let logger: Arc = Arc::new(test_logger::TestLogger::new("".to_owned(), out)); let our_pubkey = get_pubkey!(); - let mut net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash()); + let net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash()); let mut node_pks = HashSet::new(); let mut scid = 42; diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index df2bbfd8f12..409fa803cab 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -115,11 +115,11 @@ mod test { let amt_msat = invoice.amount_pico_btc().unwrap() / 10; let first_hops = nodes[0].node.list_usable_channels(); let last_hops = invoice.route_hints(); - let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap(); + let network_graph = &nodes[0].net_graph_msg_handler.network_graph; let logger = test_utils::TestLogger::new(); let route = router::get_route( &nodes[0].node.get_our_node_id(), - &network_graph, + network_graph, &invoice.recover_payee_pub_key(), Some(invoice.features().unwrap().clone()), Some(&first_hops.iter().collect::>()), diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 70bffeeb201..187cdeaf5ff 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -62,7 +62,7 @@ fn do_test_simple_monitor_permanent_update_fail(persister_fail: bool) { false => *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::PermanentFailure)) } let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable {..}, {}); check_added_monitors!(nodes[0], 2); @@ -186,7 +186,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -245,7 +245,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail false => *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure)) } let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -315,7 +315,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { { *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure)); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {}); check_added_monitors!(nodes[0], 1); } @@ -652,7 +652,7 @@ fn test_monitor_update_fail_cs() { let (payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -747,7 +747,7 @@ fn test_monitor_update_fail_no_rebroadcast() { let (payment_preimage_1, our_payment_hash, payment_secret_1) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(payment_secret_1)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -798,7 +798,7 @@ fn test_monitor_update_raa_while_paused() { let (payment_preimage_1, our_payment_hash_1, our_payment_secret_1) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash_1, &Some(our_payment_secret_1)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -807,7 +807,7 @@ fn test_monitor_update_raa_while_paused() { let (payment_preimage_2, our_payment_hash_2, our_payment_secret_2) = get_payment_preimage_hash!(nodes[0]); { let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, our_payment_hash_2, &Some(our_payment_secret_2)).unwrap(); check_added_monitors!(nodes[1], 1); } @@ -899,7 +899,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[2]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -926,7 +926,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { let (_, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[2]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -947,7 +947,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { // Try to route another payment backwards from 2 to make sure 1 holds off on responding let (payment_preimage_4, payment_hash_4, payment_secret_4) = get_payment_preimage_hash!(nodes[0]); let net_graph_msg_handler = &nodes[2].net_graph_msg_handler; - let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[2].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap(); check_added_monitors!(nodes[2], 1); @@ -1248,7 +1248,7 @@ fn raa_no_response_awaiting_raa_state() { // generation during RAA while in monitor-update-failed state. { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); check_added_monitors!(nodes[0], 1); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); @@ -1302,7 +1302,7 @@ fn raa_no_response_awaiting_raa_state() { // commitment transaction states) whereas here we can explicitly check for it. { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); check_added_monitors!(nodes[0], 0); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -1394,7 +1394,7 @@ fn claim_while_disconnected_monitor_update_fail() { let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1490,7 +1490,7 @@ fn monitor_failed_no_reestablish_response() { let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1566,7 +1566,7 @@ fn first_message_on_recv_ordering() { let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1591,7 +1591,7 @@ fn first_message_on_recv_ordering() { let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1678,7 +1678,7 @@ fn test_monitor_update_fail_claim() { let route; { let net_graph_msg_handler = &nodes[2].net_graph_msg_handler; - route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1_000_000, TEST_FINAL_CLTV, &logger).unwrap(); + route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1_000_000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[2], 1); } @@ -1788,7 +1788,7 @@ fn test_monitor_update_on_pending_forwards() { let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[0]); { let net_graph_msg_handler = &nodes[2].net_graph_msg_handler; - let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[2], 1); } @@ -1851,7 +1851,7 @@ fn monitor_update_claim_fail_no_response() { let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -2010,7 +2010,7 @@ fn test_path_paused_mpp() { let logger = test_utils::TestLogger::new(); let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[3]); - let mut route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let mut route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); // Set us up to take multiple routes, one 0 -> 1 -> 3 and one 0 -> 2 -> 3: let path = route.paths[0].clone(); @@ -2075,7 +2075,7 @@ fn test_pending_update_fee_ack_on_reconnect() { send_payment(&nodes[0], &[&nodes[1]], 100_000_00); let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[0]); - let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1_000_000, TEST_FINAL_CLTV, nodes[1].logger).unwrap(); nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); check_added_monitors!(nodes[1], 1); @@ -2283,7 +2283,7 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) { let route = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 100000, TEST_FINAL_CLTV, nodes[0].logger).unwrap() + get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 100000, TEST_FINAL_CLTV, nodes[0].logger).unwrap() }; nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); @@ -2470,7 +2470,7 @@ fn do_test_reconnect_dup_htlc_claims(htlc_status: HTLCStatusAtDupClaim, second_f // In order to get the HTLC claim into the holding cell at nodes[1], we need nodes[1] to be // awaiting a remote revoke_and_ack from nodes[0]. let (_, second_payment_hash, second_payment_secret) = get_payment_preimage_hash!(nodes[1]); - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, nodes[1].logger).unwrap(); nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 7ecdd8eaade..346dddf9261 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -5517,7 +5517,7 @@ mod tests { // First, send a partial MPP payment. let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap(); let (payment_preimage, our_payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[1]); // Use the utility function send_payment_along_path to send the payment with MPP data which // indicates there are more HTLCs coming. @@ -5624,7 +5624,7 @@ mod tests { let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &expected_route, 100_000); // Next, attempt a keysend payment and make sure it fails. - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -5652,7 +5652,7 @@ mod tests { // To start (2), send a keysend payment but don't claim it. let payment_preimage = PaymentPreimage([42; 32]); - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap(); let payment_hash = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -5704,9 +5704,9 @@ mod tests { nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() }); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); - let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap(); + let network_graph = &nodes[0].net_graph_msg_handler.network_graph; let first_hops = nodes[0].node.list_usable_channels(); - let route = get_keysend_route(&payer_pubkey, &network_graph, &payee_pubkey, + let route = get_keysend_route(&payer_pubkey, network_graph, &payee_pubkey, Some(&first_hops.iter().collect::>()), &vec![], 10000, 40, nodes[0].logger).unwrap(); @@ -5740,9 +5740,9 @@ mod tests { nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() }); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); - let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap(); + let network_graph = &nodes[0].net_graph_msg_handler.network_graph; let first_hops = nodes[0].node.list_usable_channels(); - let route = get_keysend_route(&payer_pubkey, &network_graph, &payee_pubkey, + let route = get_keysend_route(&payer_pubkey, network_graph, &payee_pubkey, Some(&first_hops.iter().collect::>()), &vec![], 10000, 40, nodes[0].logger).unwrap(); @@ -5779,7 +5779,7 @@ mod tests { // Marshall an MPP route. let (_, payment_hash, _) = get_payment_preimage_hash!(&nodes[3]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); let path = route.paths[0].clone(); route.paths.push(path); route.paths[0][0].pubkey = nodes[1].node.get_our_node_id(); diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 82c5d2901e2..4e7ca676d9f 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -239,10 +239,10 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { // Check that if we serialize the Router, we can deserialize it again. { let mut w = test_utils::TestVecWriter(Vec::new()); - let network_graph_ser = self.net_graph_msg_handler.network_graph.read().unwrap(); + let network_graph_ser = &self.net_graph_msg_handler.network_graph; network_graph_ser.write(&mut w).unwrap(); let network_graph_deser = ::read(&mut io::Cursor::new(&w.0)).unwrap(); - assert!(network_graph_deser == *self.net_graph_msg_handler.network_graph.read().unwrap()); + assert!(network_graph_deser == self.net_graph_msg_handler.network_graph); let net_graph_msg_handler = NetGraphMsgHandler::from_net_graph( Some(self.chain_source), self.logger, network_graph_deser ); @@ -962,7 +962,7 @@ macro_rules! get_route_and_payment_hash { let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!($recv_node); let net_graph_msg_handler = &$send_node.net_graph_msg_handler; let route = get_route(&$send_node.node.get_our_node_id(), - &net_graph_msg_handler.network_graph.read().unwrap(), + &net_graph_msg_handler.network_graph, &$recv_node.node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, $send_node.logger).unwrap(); (route, payment_hash, payment_preimage, payment_secret) }} @@ -1250,7 +1250,7 @@ pub const TEST_FINAL_CLTV: u32 = 70; pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) { let net_graph_msg_handler = &origin_node.net_graph_msg_handler; - let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), Some(&origin_node.node.list_usable_channels().iter().collect::>()), &[], recv_value, TEST_FINAL_CLTV, origin_node.logger).unwrap(); @@ -1265,7 +1265,7 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) { let net_graph_msg_handler = &origin_node.net_graph_msg_handler; - let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, origin_node.logger).unwrap(); + let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, origin_node.logger).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].len(), expected_route.len()); for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) { diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 06cc80cc18b..51b75684eaf 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -171,7 +171,7 @@ fn test_async_inbound_update_fee() { // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]... let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[0]); let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap(); + nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[1], 1); let payment_event = { @@ -272,7 +272,7 @@ fn test_update_fee_unordered_raa() { // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]... let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[0]); let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap(); + nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[1], 1); let payment_event = { @@ -675,7 +675,7 @@ fn test_update_fee_with_fundee_update_add_htlc() { let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[0]); let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800000, TEST_FINAL_CLTV, &logger).unwrap(); // nothing happens since node[1] is in AwaitingRemoteRevoke nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); @@ -1001,7 +1001,7 @@ fn holding_cell_htlc_counting() { for _ in 0..::ln::channel::OUR_MAX_HTLCS { let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); payments.push((payment_preimage, payment_hash)); } @@ -1018,7 +1018,7 @@ fn holding_cell_htlc_counting() { let (_, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[2]); { let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot push more than their max accepted HTLCs \(\d+\)").unwrap().is_match(err))); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); @@ -1029,7 +1029,7 @@ fn holding_cell_htlc_counting() { let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[2]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[0], 1); } @@ -1154,7 +1154,7 @@ fn test_duplicate_htlc_different_direction_onchain() { let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 900_000); let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800_000, TEST_FINAL_CLTV, &logger).unwrap(); let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap(); send_along_route_with_secret(&nodes[1], route, &[&[&nodes[0]]], 800_000, payment_hash, node_a_payment_secret); @@ -1240,7 +1240,7 @@ fn test_basic_channel_reserve() { let commit_tx_fee = 2 * commit_tx_fee_msat(get_feerate!(nodes[0], chan.2), 1 + 1); let max_can_send = 5000000 - channel_reserve - commit_tx_fee; let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), max_can_send + 1, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), max_can_send + 1, TEST_FINAL_CLTV, &logger).unwrap(); let err = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).err().unwrap(); match err { PaymentSendFailure::AllFailedRetrySafe(ref fails) => { @@ -1886,7 +1886,7 @@ fn channel_reserve_in_flight_removes() { let (payment_preimage_3, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[1]); let send_1 = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -1959,7 +1959,7 @@ fn channel_reserve_in_flight_removes() { let (payment_preimage_4, payment_hash_4, payment_secret_4) = get_payment_preimage_hash!(nodes[0]); let send_2 = { let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 10000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 10000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap(); check_added_monitors!(nodes[1], 1); let mut events = nodes[1].node.get_and_clear_pending_msg_events(); @@ -2937,7 +2937,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use let (_, fourth_payment_hash, fourth_payment_secret) = get_payment_preimage_hash!(nodes[2]); let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, fourth_payment_hash, &Some(fourth_payment_secret)).unwrap(); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); @@ -3089,7 +3089,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() { { let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -3106,7 +3106,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() { let (_, failed_payment_hash, failed_payment_secret) = get_payment_preimage_hash!(nodes[1]); { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, failed_payment_hash, &Some(failed_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 0); @@ -3121,7 +3121,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() { let session_priv = SecretKey::from_slice(&[42; 32]).unwrap(); let current_height = nodes[1].node.best_block.read().unwrap().height() + 1; let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap(); let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route.paths[0], 50_000, &Some(payment_secret), current_height, &None).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap(); let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash); @@ -3190,7 +3190,7 @@ fn test_force_close_fail_back() { let mut payment_event = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, 42, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, 42, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -3362,7 +3362,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken let logger = test_utils::TestLogger::new(); let payment_event = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), Some(&nodes[0].node.list_usable_channels().iter().collect::>()), &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap(); @@ -3557,7 +3557,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken // Channel should still work fine... let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), Some(&nodes[0].node.list_usable_channels().iter().collect::>()), &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); let payment_preimage_2 = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000).0; @@ -3664,7 +3664,7 @@ fn test_funding_peer_disconnect() { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); let (payment_preimage, _, _) = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000); claim_payment(&nodes[0], &[&nodes[1]], payment_preimage); @@ -3740,7 +3740,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() { // Now try to send a second payment which will fail to send let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -3887,7 +3887,7 @@ fn do_test_htlc_timeout(send_partial_mpp: bool) { let our_payment_hash = if send_partial_mpp { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); let (_, our_payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[1]); // Use the utility function send_payment_along_path to send the payment with MPP data which // indicates there are more HTLCs coming. @@ -3960,7 +3960,7 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { let (_, first_payment_hash, first_payment_secret) = get_payment_preimage_hash!(nodes[2]); { let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, first_payment_hash, &Some(first_payment_secret)).unwrap(); } assert_eq!(nodes[1].node.get_and_clear_pending_msg_events().len(), 1); @@ -3970,7 +3970,7 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { let (_, second_payment_hash, second_payment_secret) = get_payment_preimage_hash!(nodes[2]); if forwarded_htlc { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, second_payment_hash, &Some(first_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let payment_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); @@ -3980,7 +3980,7 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { check_added_monitors!(nodes[1], 0); } else { let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)).unwrap(); check_added_monitors!(nodes[1], 0); } @@ -5109,7 +5109,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() { // We reduce the final CLTV here by a somewhat arbitrary constant to keep it under the one-byte // script push size limit so that the below script length checks match // ACCEPTED_HTLC_SCRIPT_WEIGHT. - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 900000, TEST_FINAL_CLTV - 40, nodes[0].logger).unwrap(); send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 900000, duplicate_payment_hash, payment_secret); @@ -5307,7 +5307,7 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno let (_, payment_hash_2, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; let our_node_id = &nodes[1].node.get_our_node_id(); - let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap(); // 2nd HTLC: send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee // 3rd HTLC: @@ -5316,7 +5316,7 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno let (_, payment_hash_3, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000); // 5th HTLC: let (_, payment_hash_4, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000); - let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); // 6th HTLC: send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200, 0).unwrap()); // 7th HTLC: @@ -5325,13 +5325,13 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno // 8th HTLC: let (_, payment_hash_5, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000); // 9th HTLC: - let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap(); send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee // 10th HTLC: let (_, payment_hash_6, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee // 11th HTLC: - let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap(); send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200, 0).unwrap()); // Double-check that six of the new HTLC were added @@ -5736,7 +5736,7 @@ fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) { let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), if use_dust { 50000 } else { 3000000 }, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), if use_dust { 50000 } else { 3000000 }, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -5971,7 +5971,7 @@ fn test_fail_holding_cell_htlc_upon_free() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let max_can_send = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 1 + 1); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap(); // Send a payment which passes reserve checks but gets stuck in the holding cell. nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); @@ -6051,8 +6051,8 @@ fn test_free_and_fail_holding_cell_htlcs() { let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]); let amt_2 = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 2 + 1) - amt_1; let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_1, TEST_FINAL_CLTV, &logger).unwrap(); - let route_2 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_2, TEST_FINAL_CLTV, &logger).unwrap(); + let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_1, TEST_FINAL_CLTV, &logger).unwrap(); + let route_2 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_2, TEST_FINAL_CLTV, &logger).unwrap(); // Send 2 payments which pass reserve checks but get stuck in the holding cell. nodes[0].node.send_payment(&route_1, payment_hash_1, &Some(payment_secret_1)).unwrap(); @@ -6184,7 +6184,7 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() { let max_can_send = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 1 + 1) - total_routing_fee_msat; let payment_event = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -6288,7 +6288,7 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); route.paths[0][0].fee_msat = 100; unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, @@ -6309,7 +6309,7 @@ fn test_update_add_htlc_bolt2_sender_zero_value_msat() { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); route.paths[0][0].fee_msat = 0; unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, assert_eq!(err, "Cannot send 0-msat HTLC")); @@ -6330,7 +6330,7 @@ fn test_update_add_htlc_bolt2_receiver_zero_value_msat() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6356,7 +6356,7 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000000, 500000001, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000000, 500000001, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::RouteError { ref err }, assert_eq!(err, &"Channel CLTV overflowed?")); } @@ -6378,7 +6378,7 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let payment_event = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -6400,7 +6400,7 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() } let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err }, assert!(regex::Regex::new(r"Cannot push more than their max accepted HTLCs \(\d+\)").unwrap().is_match(err))); @@ -6457,7 +6457,7 @@ fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; let logger = test_utils::TestLogger::new(); - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], htlc_minimum_msat, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], htlc_minimum_msat, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6488,7 +6488,7 @@ fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { let max_can_send = 5000000 - channel_reserve - commit_tx_fee_outbound; let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6520,7 +6520,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { let session_priv = SecretKey::from_slice(&[42; 32]).unwrap(); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 3999999, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 3999999, TEST_FINAL_CLTV, &logger).unwrap(); let cur_height = nodes[0].node.best_block.read().unwrap().height() + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route.paths[0], &session_priv).unwrap(); @@ -6561,7 +6561,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6586,7 +6586,7 @@ fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known()); let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6613,7 +6613,7 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6660,7 +6660,7 @@ fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() { let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -6694,7 +6694,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6727,7 +6727,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -6842,7 +6842,7 @@ fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_messag let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -6895,7 +6895,7 @@ fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_upda //First hop let mut payment_event = { let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -7327,7 +7327,7 @@ fn test_check_htlc_underpaying() { // Create some initial channels create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 10_000, TEST_FINAL_CLTV, nodes[0].logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 10_000, TEST_FINAL_CLTV, nodes[0].logger).unwrap(); let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]); let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200, 0).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); @@ -7508,7 +7508,7 @@ fn test_priv_forwarding_rejection() { // to nodes[2], which should be rejected: let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[2]); let route = get_route(&nodes[0].node.get_our_node_id(), - &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), + &nodes[0].net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[&RouteHint(vec![RouteHintHop { src_node_id: nodes[1].node.get_our_node_id(), @@ -7628,7 +7628,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0; let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000, 30, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000, 30, &logger).unwrap(); send_along_route(&nodes[1], route, &vec!(&nodes[0])[..], 3000000); let revoked_txn = get_local_commitment_txn!(nodes[0], chan.2); @@ -7732,10 +7732,10 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, InitFeatures::known(), InitFeatures::known()); // Lock HTLC in both directions (using a slightly lower CLTV delay to provide timely RBF bumps) - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3_000_000, 50, nodes[0].logger).unwrap(); let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0; - let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph.read().unwrap(), + let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3_000_000, 50, nodes[0].logger).unwrap(); send_along_route(&nodes[1], route, &[&nodes[0]], 3_000_000); @@ -8125,7 +8125,7 @@ fn test_simple_mpp() { let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[3]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); let path = route.paths[0].clone(); route.paths.push(path); route.paths[0][0].pubkey = nodes[1].node.get_our_node_id(); @@ -8153,7 +8153,7 @@ fn test_preimage_storage() { let logger = test_utils::TestLogger::new(); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -8224,7 +8224,7 @@ fn test_secret_timeout() { { let logger = test_utils::TestLogger::new(); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); @@ -8264,7 +8264,7 @@ fn test_bad_secret_hash() { let logger = test_utils::TestLogger::new(); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap(); // All the below cases should end up being handled exactly identically, so we macro the // resulting events. @@ -8453,7 +8453,7 @@ fn test_concurrent_monitor_claim() { let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[0]); { let net_graph_msg_handler = &nodes[1].net_graph_msg_handler; - let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000 , TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000 , TEST_FINAL_CLTV, &logger).unwrap(); nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap(); } check_added_monitors!(nodes[1], 1); @@ -9109,10 +9109,10 @@ fn test_keysend_payments_to_public_node() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known()); - let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap(); + let network_graph = &nodes[0].net_graph_msg_handler.network_graph; let payer_pubkey = nodes[0].node.get_our_node_id(); let payee_pubkey = nodes[1].node.get_our_node_id(); - let route = get_route(&payer_pubkey, &network_graph, &payee_pubkey, None, + let route = get_route(&payer_pubkey, network_graph, &payee_pubkey, None, None, &vec![], 10000, 40, nodes[0].logger).unwrap(); @@ -9140,7 +9140,7 @@ fn test_keysend_payments_to_private_node() { nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() }); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); - let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap(); + let network_graph = &nodes[0].net_graph_msg_handler.network_graph; let first_hops = nodes[0].node.list_usable_channels(); let route = get_keysend_route(&payer_pubkey, &network_graph, &payee_pubkey, Some(&first_hops.iter().collect::>()), &vec![], 10000, 40, diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index 8530d3d6610..1006d9da133 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -263,7 +263,7 @@ fn test_fee_failures() { let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs); let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()), create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known())]; let logger = test_utils::TestLogger::new(); - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40_000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40_000, TEST_FINAL_CLTV, &logger).unwrap(); // positive case let (payment_preimage_success, payment_hash_success, payment_secret_success) = get_payment_preimage_hash!(nodes[2]); @@ -318,7 +318,7 @@ fn test_onion_failure() { let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()), create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known())]; let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); let logger = test_utils::TestLogger::new(); - let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(); // positve case send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000); diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index a40ad23761e..9f5db40c883 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -94,8 +94,8 @@ fn updates_shutdown_wait() { let net_graph_msg_handler0 = &nodes[0].net_graph_msg_handler; let net_graph_msg_handler1 = &nodes[1].net_graph_msg_handler; - let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler0.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); - let route_2 = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler1.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler0.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route_2 = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler1.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {}); unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {}); @@ -161,7 +161,7 @@ fn htlc_fail_async_shutdown() { let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[2]); let net_graph_msg_handler = &nodes[0].net_graph_msg_handler; - let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); + let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap(); nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap(); check_added_monitors!(nodes[0], 1); let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 3b593351fac..2d5051166be 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -58,11 +58,6 @@ pub struct NetworkGraph { nodes: RwLock>, } -/// A simple newtype for RwLockReadGuard<'a, NetworkGraph>. -/// This exists only to make accessing a RwLock possible from -/// the C bindings, as it can be done directly in Rust code. -pub struct LockedNetworkGraph<'a>(pub RwLockReadGuard<'a, NetworkGraph>); - /// Receives and validates network updates from peers, /// stores authentic and relevant data as a network graph. /// This network graph is then used for routing payments. @@ -71,7 +66,7 @@ pub struct LockedNetworkGraph<'a>(pub RwLockReadGuard<'a, NetworkGraph>); pub struct NetGraphMsgHandler where C::Target: chain::Access, L::Target: Logger { secp_ctx: Secp256k1, /// Representation of the payment channel network - pub network_graph: RwLock, + pub network_graph: NetworkGraph, chain_access: Option, full_syncs_requested: AtomicUsize, pending_events: Mutex>, @@ -87,7 +82,7 @@ impl NetGraphMsgHandler where C::Target: chain::Access pub fn new(genesis_hash: BlockHash, chain_access: Option, logger: L) -> Self { NetGraphMsgHandler { secp_ctx: Secp256k1::verification_only(), - network_graph: RwLock::new(NetworkGraph::new(genesis_hash)), + network_graph: NetworkGraph::new(genesis_hash), full_syncs_requested: AtomicUsize::new(0), chain_access, pending_events: Mutex::new(vec![]), @@ -100,7 +95,7 @@ impl NetGraphMsgHandler where C::Target: chain::Access pub fn from_net_graph(chain_access: Option, logger: L, network_graph: NetworkGraph) -> Self { NetGraphMsgHandler { secp_ctx: Secp256k1::verification_only(), - network_graph: RwLock::new(network_graph), + network_graph, full_syncs_requested: AtomicUsize::new(0), chain_access, pending_events: Mutex::new(vec![]), @@ -115,14 +110,6 @@ impl NetGraphMsgHandler where C::Target: chain::Access self.chain_access = chain_access; } - /// Take a read lock on the network_graph and return it in the C-bindings - /// newtype helper. This is likely only useful when called via the C - /// bindings as you can call `self.network_graph.read().unwrap()` in Rust - /// yourself. - pub fn read_locked_graph<'a>(&'a self) -> LockedNetworkGraph<'a> { - LockedNetworkGraph(self.network_graph.read().unwrap()) - } - /// Returns true when a full routing table sync should be performed with a peer. fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool { //TODO: Determine whether to request a full sync based on the network map. @@ -136,14 +123,6 @@ impl NetGraphMsgHandler where C::Target: chain::Access } } -impl<'a> LockedNetworkGraph<'a> { - /// Get a reference to the NetworkGraph which this read-lock contains. - pub fn graph(&self) -> &NetworkGraph { - &*self.0 - } -} - - macro_rules! secp_verify_sig { ( $secp_ctx: expr, $msg: expr, $sig: expr, $pubkey: expr ) => { match $secp_ctx.verify($msg, $sig, $pubkey) { @@ -155,14 +134,14 @@ macro_rules! secp_verify_sig { impl RoutingMessageHandler for NetGraphMsgHandler where C::Target: chain::Access, L::Target: Logger { fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result { - self.network_graph.write().unwrap().update_node_from_announcement(msg, &self.secp_ctx)?; + self.network_graph.update_node_from_announcement(msg, &self.secp_ctx)?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY && msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY && msg.contents.excess_data.len() + msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } fn handle_channel_announcement(&self, msg: &msgs::ChannelAnnouncement) -> Result { - self.network_graph.write().unwrap().update_channel_from_announcement(msg, &self.chain_access, &self.secp_ctx)?; + self.network_graph.update_channel_from_announcement(msg, &self.chain_access, &self.secp_ctx)?; log_trace!(self.logger, "Added channel_announcement for {}{}", msg.contents.short_channel_id, if !msg.contents.excess_data.is_empty() { " with excess uninterpreted data!" } else { "" }); Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } @@ -172,28 +151,27 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh &msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } => { let chan_enabled = msg.contents.flags & (1 << 1) != (1 << 1); log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}abled.", msg.contents.short_channel_id, if chan_enabled { "en" } else { "dis" }); - let _ = self.network_graph.write().unwrap().update_channel(msg, &self.secp_ctx); + let _ = self.network_graph.update_channel(msg, &self.secp_ctx); }, &msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } => { log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", if is_permanent { "Removing" } else { "Disabling" }, short_channel_id); - self.network_graph.write().unwrap().close_channel_from_update(short_channel_id, is_permanent); + self.network_graph.close_channel_from_update(short_channel_id, is_permanent); }, &msgs::HTLCFailChannelUpdate::NodeFailure { ref node_id, is_permanent } => { log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", if is_permanent { "Removing" } else { "Disabling" }, node_id); - self.network_graph.write().unwrap().fail_node(node_id, is_permanent); + self.network_graph.fail_node(node_id, is_permanent); }, } } fn handle_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result { - self.network_graph.write().unwrap().update_channel(msg, &self.secp_ctx)?; + self.network_graph.update_channel(msg, &self.secp_ctx)?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(ChannelAnnouncement, Option, Option)> { - let network_graph = self.network_graph.read().unwrap(); let mut result = Vec::with_capacity(batch_amount as usize); - let channels = network_graph.get_channels(); + let channels = self.network_graph.get_channels(); let mut iter = channels.range(starting_point..); while result.len() < batch_amount as usize { if let Some((_, ref chan)) = iter.next() { @@ -220,9 +198,8 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh } fn get_next_node_announcements(&self, starting_point: Option<&PublicKey>, batch_amount: u8) -> Vec { - let network_graph = self.network_graph.read().unwrap(); let mut result = Vec::with_capacity(batch_amount as usize); - let nodes = network_graph.get_nodes(); + let nodes = self.network_graph.get_nodes(); let mut iter = if let Some(pubkey) = starting_point { let mut iter = nodes.range((*pubkey)..); iter.next(); @@ -272,7 +249,7 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh pending_events.push(MessageSendEvent::SendChannelRangeQuery { node_id: their_node_id.clone(), msg: QueryChannelRange { - chain_hash: self.network_graph.read().unwrap().genesis_hash, + chain_hash: self.network_graph.genesis_hash, first_blocknum, number_of_blocks, }, @@ -334,8 +311,6 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh fn handle_query_channel_range(&self, their_node_id: &PublicKey, msg: QueryChannelRange) -> Result<(), LightningError> { log_debug!(self.logger, "Handling query_channel_range peer={}, first_blocknum={}, number_of_blocks={}", log_pubkey!(their_node_id), msg.first_blocknum, msg.number_of_blocks); - let network_graph = self.network_graph.read().unwrap(); - let inclusive_start_scid = scid_from_parts(msg.first_blocknum as u64, 0, 0); // We might receive valid queries with end_blocknum that would overflow SCID conversion. @@ -343,7 +318,7 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh let exclusive_end_scid = scid_from_parts(cmp::min(msg.end_blocknum() as u64, MAX_SCID_BLOCK), 0, 0); // Per spec, we must reply to a query. Send an empty message when things are invalid. - if msg.chain_hash != network_graph.genesis_hash || inclusive_start_scid.is_err() || exclusive_end_scid.is_err() || msg.number_of_blocks == 0 { + if msg.chain_hash != self.network_graph.genesis_hash || inclusive_start_scid.is_err() || exclusive_end_scid.is_err() || msg.number_of_blocks == 0 { let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(MessageSendEvent::SendReplyChannelRange { node_id: their_node_id.clone(), @@ -365,7 +340,7 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh // (has at least one update). A peer may still want to know the channel // exists even if its not yet routable. let mut batches: Vec> = vec![Vec::with_capacity(MAX_SCIDS_PER_REPLY)]; - for (_, ref chan) in network_graph.get_channels().range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) { + for (_, ref chan) in self.network_graph.get_channels().range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) { if let Some(chan_announcement) = &chan.announcement_message { // Construct a new batch if last one is full if batches.last().unwrap().len() == batches.last().unwrap().capacity() { @@ -376,7 +351,6 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh batch.push(chan_announcement.contents.short_channel_id); } } - drop(network_graph); let mut pending_events = self.pending_events.lock().unwrap(); let batch_count = batches.len(); @@ -731,7 +705,7 @@ impl NetworkGraph { /// You probably don't want to call this directly, instead relying on a NetGraphMsgHandler's /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept /// routing messages from a source using a protocol other than the lightning P2P protocol. - pub fn update_node_from_announcement(&mut self, msg: &msgs::NodeAnnouncement, secp_ctx: &Secp256k1) -> Result<(), LightningError> { + pub fn update_node_from_announcement(&self, msg: &msgs::NodeAnnouncement, secp_ctx: &Secp256k1) -> Result<(), LightningError> { let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]); secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id); self.update_node_from_announcement_intern(&msg.contents, Some(&msg)) @@ -741,11 +715,11 @@ impl NetworkGraph { /// given node announcement without verifying the associated signatures. Because we aren't /// given the associated signatures here we cannot relay the node announcement to any of our /// peers. - pub fn update_node_from_unsigned_announcement(&mut self, msg: &msgs::UnsignedNodeAnnouncement) -> Result<(), LightningError> { + pub fn update_node_from_unsigned_announcement(&self, msg: &msgs::UnsignedNodeAnnouncement) -> Result<(), LightningError> { self.update_node_from_announcement_intern(msg, None) } - fn update_node_from_announcement_intern(&mut self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>) -> Result<(), LightningError> { + fn update_node_from_announcement_intern(&self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>) -> Result<(), LightningError> { match self.nodes.write().unwrap().get_mut(&msg.node_id) { None => Err(LightningError{err: "No existing channels for node_announcement".to_owned(), action: ErrorAction::IgnoreError}), Some(node) => { @@ -781,10 +755,12 @@ impl NetworkGraph { /// /// If a `chain::Access` object is provided via `chain_access`, it will be called to verify /// the corresponding UTXO exists on chain and is correctly-formatted. - pub fn update_channel_from_announcement - (&mut self, msg: &msgs::ChannelAnnouncement, chain_access: &Option, secp_ctx: &Secp256k1) - -> Result<(), LightningError> - where C::Target: chain::Access { + pub fn update_channel_from_announcement( + &self, msg: &msgs::ChannelAnnouncement, chain_access: &Option, secp_ctx: &Secp256k1 + ) -> Result<(), LightningError> + where + C::Target: chain::Access, + { let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]); secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1); secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2); @@ -799,17 +775,21 @@ impl NetworkGraph { /// /// If a `chain::Access` object is provided via `chain_access`, it will be called to verify /// the corresponding UTXO exists on chain and is correctly-formatted. - pub fn update_channel_from_unsigned_announcement - (&mut self, msg: &msgs::UnsignedChannelAnnouncement, chain_access: &Option) - -> Result<(), LightningError> - where C::Target: chain::Access { + pub fn update_channel_from_unsigned_announcement( + &self, msg: &msgs::UnsignedChannelAnnouncement, chain_access: &Option + ) -> Result<(), LightningError> + where + C::Target: chain::Access, + { self.update_channel_from_unsigned_announcement_intern(msg, None, chain_access) } - fn update_channel_from_unsigned_announcement_intern - (&mut self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, chain_access: &Option) - -> Result<(), LightningError> - where C::Target: chain::Access { + fn update_channel_from_unsigned_announcement_intern( + &self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, chain_access: &Option + ) -> Result<(), LightningError> + where + C::Target: chain::Access, + { if msg.node_id_1 == msg.node_id_2 || msg.bitcoin_key_1 == msg.bitcoin_key_2 { return Err(LightningError{err: "Channel announcement node had a channel with itself".to_owned(), action: ErrorAction::IgnoreError}); } @@ -909,7 +889,7 @@ impl NetworkGraph { /// If permanent, removes a channel from the local storage. /// May cause the removal of nodes too, if this was their last channel. /// If not permanent, makes channels unavailable for routing. - pub fn close_channel_from_update(&mut self, short_channel_id: u64, is_permanent: bool) { + pub fn close_channel_from_update(&self, short_channel_id: u64, is_permanent: bool) { let mut channels = self.channels.write().unwrap(); if is_permanent { if let Some(chan) = channels.remove(&short_channel_id) { @@ -928,7 +908,7 @@ impl NetworkGraph { } } - fn fail_node(&mut self, _node_id: &PublicKey, is_permanent: bool) { + fn fail_node(&self, _node_id: &PublicKey, is_permanent: bool) { if is_permanent { // TODO: Wholly remove the node } else { @@ -942,18 +922,18 @@ impl NetworkGraph { /// You probably don't want to call this directly, instead relying on a NetGraphMsgHandler's /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept /// routing messages from a source using a protocol other than the lightning P2P protocol. - pub fn update_channel(&mut self, msg: &msgs::ChannelUpdate, secp_ctx: &Secp256k1) -> Result<(), LightningError> { + pub fn update_channel(&self, msg: &msgs::ChannelUpdate, secp_ctx: &Secp256k1) -> Result<(), LightningError> { self.update_channel_intern(&msg.contents, Some(&msg), Some((&msg.signature, secp_ctx))) } /// For an already known (from announcement) channel, update info about one of the directions /// of the channel without verifying the associated signatures. Because we aren't given the /// associated signatures here we cannot relay the channel update to any of our peers. - pub fn update_channel_unsigned(&mut self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> { + pub fn update_channel_unsigned(&self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> { self.update_channel_intern(msg, None, None::<(&secp256k1::Signature, &Secp256k1)>) } - fn update_channel_intern(&mut self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::Signature, &Secp256k1)>) -> Result<(), LightningError> { + fn update_channel_intern(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::Signature, &Secp256k1)>) -> Result<(), LightningError> { let dest_node_id; let chan_enabled = msg.flags & (1 << 1) != (1 << 1); let chan_was_enabled; @@ -1287,7 +1267,7 @@ mod tests { }; { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; match network.get_channels().get(&unsigned_announcement.short_channel_id) { None => panic!(), Some(_) => () @@ -1339,7 +1319,7 @@ mod tests { }; { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; match network.get_channels().get(&unsigned_announcement.short_channel_id) { None => panic!(), Some(_) => () @@ -1370,7 +1350,7 @@ mod tests { _ => panic!() }; { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; match network.get_channels().get(&unsigned_announcement.short_channel_id) { Some(channel_entry) => { assert_eq!(channel_entry.features, ChannelFeatures::empty()); @@ -1500,7 +1480,7 @@ mod tests { }; { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; match network.get_channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { @@ -1606,7 +1586,7 @@ mod tests { { // There is no nodes in the table at the beginning. - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; assert_eq!(network.get_nodes().len(), 0); } @@ -1662,7 +1642,7 @@ mod tests { // Non-permanent closing just disables a channel { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; match network.get_channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { @@ -1680,7 +1660,7 @@ mod tests { // Non-permanent closing just disables a channel { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; match network.get_channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { @@ -1698,7 +1678,7 @@ mod tests { // Permanent closing deletes a channel { - let network = net_graph_msg_handler.network_graph.read().unwrap(); + let network = &net_graph_msg_handler.network_graph; assert_eq!(network.get_channels().len(), 0); // Nodes are also deleted because there are no associated channels anymore assert_eq!(network.get_nodes().len(), 0); @@ -2016,7 +1996,7 @@ mod tests { Err(_) => panic!() }; - let network = net_graph_msg_handler.network_graph.write().unwrap(); + let network = &net_graph_msg_handler.network_graph; let mut w = test_utils::TestVecWriter(Vec::new()); assert!(!network.get_nodes().is_empty()); assert!(!network.get_channels().is_empty()); diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 3df942d733a..6d6d603c56a 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1703,11 +1703,11 @@ mod tests { // Simple route to 2 via 1 - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 0, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 0, 42, Arc::clone(&logger)) { assert_eq!(err, "Cannot send a payment of 0 msat"); } else { panic!(); } - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -1734,11 +1734,11 @@ mod tests { let our_chans = vec![get_channel_details(Some(2), our_id, InitFeatures::from_le_bytes(vec![0b11]), 100000)]; - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)) { assert_eq!(err, "First hop cannot have our_node_id as a destination."); } else { panic!(); } - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); } @@ -1842,7 +1842,7 @@ mod tests { }); // Not possible to send 199_999_999, because the minimum on channel=2 is 200_000_000. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } @@ -1861,7 +1861,7 @@ mod tests { }); // A payment above the minimum should pass - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); } @@ -1938,7 +1938,7 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 60_000, 42, Arc::clone(&logger)).unwrap(); // Overpay fees to hit htlc_minimum_msat. let overpaid_fees = route.paths[0][0].fee_msat + route.paths[1][0].fee_msat; @@ -1984,7 +1984,7 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 60_000, 42, Arc::clone(&logger)).unwrap(); // Fine to overpay for htlc_minimum_msat if it allows us to save fee. assert_eq!(route.paths.len(), 1); @@ -1992,7 +1992,7 @@ mod tests { let fees = route.paths[0][0].fee_msat; assert_eq!(fees, 5_000); - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap(); // Not fine to overpay for htlc_minimum_msat if it requires paying more than fee on // the other channel. @@ -2034,13 +2034,13 @@ mod tests { }); // If all the channels require some features we don't understand, route should fail - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } // If we specify a channel to node7, that overrides our local channel view and that gets used let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, nodes[7]); @@ -2070,13 +2070,13 @@ mod tests { add_or_update_node(&net_graph_msg_handler, &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, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } // If we specify a channel to node7, that overrides our local channel view and that gets used let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, nodes[7]); @@ -2104,7 +2104,7 @@ mod tests { let (_, our_id, _, nodes) = get_nodes(&secp_ctx); // Route to 1 via 2 and 3 because our channel to 1 is disabled - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[0], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 3); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2130,7 +2130,7 @@ mod tests { // If we specify a channel to node7, that overrides our local channel view and that gets used let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, nodes[7]); @@ -2249,12 +2249,12 @@ mod tests { let mut invalid_last_hops = last_hops_multi_private_channels(&nodes); invalid_last_hops.push(invalid_last_hop); { - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &invalid_last_hops.iter().collect::>(), 100, 42, Arc::clone(&logger)) { + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &invalid_last_hops.iter().collect::>(), 100, 42, Arc::clone(&logger)) { assert_eq!(err, "Last hop cannot have a payee as a source."); } else { panic!(); } } - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops_multi_private_channels(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops_multi_private_channels(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 5); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2326,7 +2326,7 @@ mod tests { // Test handling of an empty RouteHint passed in Invoice. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &empty_last_hop(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &empty_last_hop(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 5); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2432,7 +2432,7 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &multi_hint_last_hops(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &multi_hint_last_hops(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 4); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2510,7 +2510,7 @@ mod tests { // This test shows that public routes can be present in the invoice // which would be handled in the same manner. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops_with_public_channel(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops_with_public_channel(&nodes).iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 5); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2559,7 +2559,7 @@ mod tests { // Simple test with outbound channel to 4 to test that last_hops and first_hops connect let our_chans = vec![get_channel_details(Some(42), nodes[3].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; let mut last_hops = last_hops(&nodes); - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, Some(&our_chans.iter().collect::>()), &last_hops.iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, Some(&our_chans.iter().collect::>()), &last_hops.iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 2); assert_eq!(route.paths[0][0].pubkey, nodes[3]); @@ -2579,7 +2579,7 @@ mod tests { last_hops[0].0[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, None, &last_hops.iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops.iter().collect::>(), 100, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 4); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2613,7 +2613,7 @@ mod tests { assert_eq!(route.paths[0][3].channel_features.le_flags(), &Vec::::new()); // We can't learn any flags from invoices, sadly // ...but still use 8 for larger payments as 6 has a variable feerate - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops.iter().collect::>(), 2000, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops.iter().collect::>(), 2000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths[0].len(), 5); assert_eq!(route.paths[0][0].pubkey, nodes[1]); @@ -2787,7 +2787,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 250_000_001, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -2795,7 +2795,7 @@ mod tests { { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 250_000_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); @@ -2824,7 +2824,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), Some(&our_chans.iter().collect::>()), &Vec::new(), 200_000_001, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -2832,7 +2832,7 @@ mod tests { { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), Some(&our_chans.iter().collect::>()), &Vec::new(), 200_000_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); @@ -2872,7 +2872,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 15_001, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -2880,7 +2880,7 @@ mod tests { { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 15_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); @@ -2943,7 +2943,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 15_001, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -2951,7 +2951,7 @@ mod tests { { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 15_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); @@ -2976,7 +2976,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 10_001, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -2984,7 +2984,7 @@ mod tests { { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 10_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); @@ -3084,7 +3084,7 @@ mod tests { }); { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 60_000, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -3092,7 +3092,7 @@ mod tests { { // Now, attempt to route 49 sats (just a bit below the capacity). - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 49_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let mut total_amount_paid_msat = 0; @@ -3106,7 +3106,7 @@ mod tests { { // Attempt to route an exact amount is also fine - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let mut total_amount_paid_msat = 0; @@ -3151,7 +3151,7 @@ mod tests { }); { - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -3258,7 +3258,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 300_000, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -3267,7 +3267,7 @@ mod tests { { // Now, attempt to route 250 sats (just a bit below the capacity). // Our algorithm should provide us with these 3 paths. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 250_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; @@ -3281,7 +3281,7 @@ mod tests { { // Attempt to route an exact amount is also fine - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 290_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; @@ -3432,7 +3432,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 350_000, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -3441,7 +3441,7 @@ mod tests { { // Now, attempt to route 300 sats (exact amount we can route). // Our algorithm should provide us with these 3 paths, 100 sats each. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 300_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 3); @@ -3598,7 +3598,7 @@ mod tests { { // Now, attempt to route 180 sats. // Our algorithm should provide us with these 2 paths. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 180_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 2); @@ -3764,7 +3764,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 210_000, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -3772,7 +3772,7 @@ mod tests { { // Now, attempt to route 200 sats (exact amount we can route). - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3], Some(InvoiceFeatures::known()), None, &Vec::new(), 200_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 2); @@ -3882,7 +3882,7 @@ mod tests { { // Attempt to route more than available results in a failure. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 150_000, 42, Arc::clone(&logger)) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -3891,7 +3891,7 @@ mod tests { { // Now, attempt to route 125 sats (just a bit below the capacity of 3 channels). // Our algorithm should provide us with these 3 paths. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 125_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; @@ -3905,7 +3905,7 @@ mod tests { { // Attempt to route without the last small cheap channel - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 2); let mut total_amount_paid_msat = 0; @@ -4040,7 +4040,7 @@ mod tests { { // Now ensure the route flows simply over nodes 1 and 4 to 6. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &Vec::new(), 10_000, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &Vec::new(), 10_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].len(), 3); @@ -4107,7 +4107,7 @@ mod tests { { // Now, attempt to route 90 sats, which is exactly 90 sats at the last hop, plus the // 200% fee charged channel 13 in the 1-to-2 direction. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].len(), 2); @@ -4168,7 +4168,7 @@ mod tests { // Now, attempt to route 90 sats, hitting the htlc_minimum on channel 4, but // overshooting the htlc_maximum on channel 2. Thus, we should pick the (absurdly // expensive) channels 12-13 path. - let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap(); + let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].len(), 2); From 798cf6ea8387b2365e0d45681c8cf28ed11f13e1 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Mon, 16 Aug 2021 18:40:19 -0500 Subject: [PATCH 04/10] Add a read-only view of NetworkGraph Hide the internal locking of NetworkGraph by providing a read-only view. This way the locking order is handled internally. --- lightning/src/routing/network_graph.rs | 104 +++++++++++++++---------- lightning/src/routing/router.rs | 13 ++-- 2 files changed, 69 insertions(+), 48 deletions(-) diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 2d5051166be..61e94e0494c 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -58,6 +58,12 @@ pub struct NetworkGraph { nodes: RwLock>, } +/// A read-only view of [`NetworkGraph`]. +pub struct ReadOnlyNetworkGraph<'a> { + channels: RwLockReadGuard<'a, BTreeMap>, + nodes: RwLockReadGuard<'a, BTreeMap>, +} + /// Receives and validates network updates from peers, /// stores authentic and relevant data as a network graph. /// This network graph is then used for routing payments. @@ -171,7 +177,7 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(ChannelAnnouncement, Option, Option)> { let mut result = Vec::with_capacity(batch_amount as usize); - let channels = self.network_graph.get_channels(); + let channels = self.network_graph.channels.read().unwrap(); let mut iter = channels.range(starting_point..); while result.len() < batch_amount as usize { if let Some((_, ref chan)) = iter.next() { @@ -199,7 +205,7 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh fn get_next_node_announcements(&self, starting_point: Option<&PublicKey>, batch_amount: u8) -> Vec { let mut result = Vec::with_capacity(batch_amount as usize); - let nodes = self.network_graph.get_nodes(); + let nodes = self.network_graph.nodes.read().unwrap(); let mut iter = if let Some(pubkey) = starting_point { let mut iter = nodes.range((*pubkey)..); iter.next(); @@ -340,7 +346,8 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh // (has at least one update). A peer may still want to know the channel // exists even if its not yet routable. let mut batches: Vec> = vec![Vec::with_capacity(MAX_SCIDS_PER_REPLY)]; - for (_, ref chan) in self.network_graph.get_channels().range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) { + let channels = self.network_graph.channels.read().unwrap(); + for (_, ref chan) in channels.range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) { if let Some(chan_announcement) = &chan.announcement_message { // Construct a new batch if last one is full if batches.last().unwrap().len() == batches.last().unwrap().capacity() { @@ -351,6 +358,7 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh batch.push(chan_announcement.contents.short_channel_id); } } + drop(channels); let mut pending_events = self.pending_events.lock().unwrap(); let batch_count = batches.len(); @@ -662,34 +670,6 @@ impl PartialEq for NetworkGraph { } impl NetworkGraph { - /// Returns all known valid channels' short ids along with announced channel info. - /// - /// (C-not exported) because we have no mapping for `BTreeMap`s - pub fn get_channels(&self) -> RwLockReadGuard<'_, BTreeMap> { - self.channels.read().unwrap() - } - - /// Returns all known nodes' public keys along with announced node info. - /// - /// (C-not exported) because we have no mapping for `BTreeMap`s - pub fn get_nodes(&self) -> RwLockReadGuard<'_, BTreeMap> { - self.nodes.read().unwrap() - } - - /// Get network addresses by node id. - /// Returns None if the requested node is completely unknown, - /// or if node announcement for the node was never received. - /// - /// (C-not exported) as there is no practical way to track lifetimes of returned values. - pub fn get_addresses(&self, pubkey: &PublicKey) -> Option> { - if let Some(node) = self.nodes.read().unwrap().get(pubkey) { - if let Some(node_info) = node.announcement_info.as_ref() { - return Some(node_info.addresses.clone()) - } - } - None - } - /// Creates a new, empty, network graph. pub fn new(genesis_hash: BlockHash) -> NetworkGraph { Self { @@ -699,6 +679,16 @@ impl NetworkGraph { } } + /// Returns a read-only view of the network graph. + pub fn read_only(&'_ self) -> ReadOnlyNetworkGraph<'_> { + let channels = self.channels.read().unwrap(); + let nodes = self.nodes.read().unwrap(); + ReadOnlyNetworkGraph { + channels, + nodes, + } + } + /// For an already known node (from channel announcements), update its stored properties from a /// given node announcement. /// @@ -1064,6 +1054,36 @@ impl NetworkGraph { } } +impl ReadOnlyNetworkGraph<'_> { + /// Returns all known valid channels' short ids along with announced channel info. + /// + /// (C-not exported) because we have no mapping for `BTreeMap`s + pub fn channels(&self) -> &BTreeMap { + &*self.channels + } + + /// Returns all known nodes' public keys along with announced node info. + /// + /// (C-not exported) because we have no mapping for `BTreeMap`s + pub fn nodes(&self) -> &BTreeMap { + &*self.nodes + } + + /// Get network addresses by node id. + /// Returns None if the requested node is completely unknown, + /// or if node announcement for the node was never received. + /// + /// (C-not exported) as there is no practical way to track lifetimes of returned values. + pub fn get_addresses(&self, pubkey: &PublicKey) -> Option<&Vec> { + if let Some(node) = self.nodes.get(pubkey) { + if let Some(node_info) = node.announcement_info.as_ref() { + return Some(&node_info.addresses) + } + } + None + } +} + #[cfg(test)] mod tests { use chain; @@ -1268,7 +1288,7 @@ mod tests { { let network = &net_graph_msg_handler.network_graph; - match network.get_channels().get(&unsigned_announcement.short_channel_id) { + match network.read_only().channels().get(&unsigned_announcement.short_channel_id) { None => panic!(), Some(_) => () }; @@ -1320,7 +1340,7 @@ mod tests { { let network = &net_graph_msg_handler.network_graph; - match network.get_channels().get(&unsigned_announcement.short_channel_id) { + match network.read_only().channels().get(&unsigned_announcement.short_channel_id) { None => panic!(), Some(_) => () }; @@ -1351,7 +1371,7 @@ mod tests { }; { let network = &net_graph_msg_handler.network_graph; - match network.get_channels().get(&unsigned_announcement.short_channel_id) { + match network.read_only().channels().get(&unsigned_announcement.short_channel_id) { Some(channel_entry) => { assert_eq!(channel_entry.features, ChannelFeatures::empty()); }, @@ -1481,7 +1501,7 @@ mod tests { { let network = &net_graph_msg_handler.network_graph; - match network.get_channels().get(&short_channel_id) { + match network.read_only().channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { assert_eq!(channel_info.one_to_two.as_ref().unwrap().cltv_expiry_delta, 144); @@ -1587,7 +1607,7 @@ mod tests { { // There is no nodes in the table at the beginning. let network = &net_graph_msg_handler.network_graph; - assert_eq!(network.get_nodes().len(), 0); + assert_eq!(network.read_only().nodes().len(), 0); } { @@ -1643,7 +1663,7 @@ mod tests { // Non-permanent closing just disables a channel { let network = &net_graph_msg_handler.network_graph; - match network.get_channels().get(&short_channel_id) { + match network.read_only().channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { assert!(channel_info.one_to_two.is_some()); @@ -1661,7 +1681,7 @@ mod tests { // Non-permanent closing just disables a channel { let network = &net_graph_msg_handler.network_graph; - match network.get_channels().get(&short_channel_id) { + match network.read_only().channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { assert!(!channel_info.one_to_two.as_ref().unwrap().enabled); @@ -1679,9 +1699,9 @@ mod tests { // Permanent closing deletes a channel { let network = &net_graph_msg_handler.network_graph; - assert_eq!(network.get_channels().len(), 0); + assert_eq!(network.read_only().channels().len(), 0); // Nodes are also deleted because there are no associated channels anymore - assert_eq!(network.get_nodes().len(), 0); + assert_eq!(network.read_only().nodes().len(), 0); } // TODO: Test HTLCFailChannelUpdate::NodeFailure, which is not implemented yet. } @@ -1998,8 +2018,8 @@ mod tests { let network = &net_graph_msg_handler.network_graph; let mut w = test_utils::TestVecWriter(Vec::new()); - assert!(!network.get_nodes().is_empty()); - assert!(!network.get_channels().is_empty()); + assert!(!network.read_only().nodes().is_empty()); + assert!(!network.read_only().channels().is_empty()); network.write(&mut w).unwrap(); assert!(::read(&mut io::Cursor::new(&w.0)).unwrap() == *network); } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 6d6d603c56a..770b62d9cd2 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -443,8 +443,9 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye // to use as the A* heuristic beyond just the cost to get one node further than the current // one. - let network_channels = network.get_channels(); - let network_nodes = network.get_nodes(); + let network_graph = network.read_only(); + let network_channels = network_graph.channels(); + let network_nodes = network_graph.nodes(); let dummy_directional_info = DummyDirectionalChannelInfo { // used for first_hops routes cltv_expiry_delta: 0, htlc_minimum_msat: 0, @@ -4213,7 +4214,7 @@ mod tests { // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut seed = random_init_seed() as usize; - let nodes = graph.get_nodes(); + let nodes = graph.read_only().nodes().clone(); 'load_endpoints: for _ in 0..10 { loop { seed = seed.overflowing_mul(0xdeadbeef).0; @@ -4242,7 +4243,7 @@ mod tests { // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut seed = random_init_seed() as usize; - let nodes = graph.get_nodes(); + let nodes = graph.read_only().nodes().clone(); 'load_endpoints: for _ in 0..10 { loop { seed = seed.overflowing_mul(0xdeadbeef).0; @@ -4301,7 +4302,7 @@ mod benches { fn generate_routes(bench: &mut Bencher) { let mut d = test_utils::get_route_file().unwrap(); let graph = NetworkGraph::read(&mut d).unwrap(); - let nodes = graph.get_nodes(); + let nodes = graph.read_only().nodes().clone(); // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut path_endpoints = Vec::new(); @@ -4333,7 +4334,7 @@ mod benches { fn generate_mpp_routes(bench: &mut Bencher) { let mut d = test_utils::get_route_file().unwrap(); let graph = NetworkGraph::read(&mut d).unwrap(); - let nodes = graph.get_nodes(); + let nodes = graph.read_only().nodes().clone(); // First, get 100 (source, destination) pairs for which route-getting actually succeeds... let mut path_endpoints = Vec::new(); From a6749d582db677cc6dcf58863488d54ff0eeb419 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 24 Aug 2021 19:41:35 -0500 Subject: [PATCH 05/10] Remove test_invalid_channel_announcement It doesn't seem to be testing anything useful that isn't covered elsewhere. --- lightning/src/ln/functional_tests.rs | 82 +--------------------------- 1 file changed, 2 insertions(+), 80 deletions(-) diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 51b75684eaf..eb3d3cb3bf0 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -16,7 +16,7 @@ use chain::{Confirm, Listen, Watch}; use chain::channelmonitor; use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; use chain::transaction::OutPoint; -use chain::keysinterface::{KeysInterface, BaseSign}; +use chain::keysinterface::BaseSign; use ln::{PaymentPreimage, PaymentSecret, PaymentHash}; use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC}; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA}; @@ -35,7 +35,6 @@ use util::errors::APIError; use util::ser::{Writeable, ReadableArgs}; use util::config::UserConfig; -use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hash_types::{Txid, BlockHash}; use bitcoin::blockdata::block::{Block, BlockHeader}; use bitcoin::blockdata::script::Builder; @@ -46,7 +45,7 @@ use bitcoin::network::constants::Network; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; -use bitcoin::secp256k1::{Secp256k1, Message}; +use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::key::{PublicKey,SecretKey}; use regex; @@ -4015,83 +4014,6 @@ fn test_holding_cell_htlc_add_timeouts() { do_test_holding_cell_htlc_add_timeouts(true); } -#[test] -fn test_invalid_channel_announcement() { - //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs - let secp_ctx = Secp256k1::new(); - let chanmon_cfgs = create_chanmon_cfgs(2); - let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); - let nodes = create_network(2, &node_cfgs, &node_chanmgrs); - - let chan_announcement = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); - - let a_channel_lock = nodes[0].node.channel_state.lock().unwrap(); - let b_channel_lock = nodes[1].node.channel_state.lock().unwrap(); - let as_chan = a_channel_lock.by_id.get(&chan_announcement.3).unwrap(); - let bs_chan = b_channel_lock.by_id.get(&chan_announcement.3).unwrap(); - - nodes[0].net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap(), is_permanent: false } ); - - let as_bitcoin_key = as_chan.get_signer().inner.holder_channel_pubkeys.funding_pubkey; - let bs_bitcoin_key = bs_chan.get_signer().inner.holder_channel_pubkeys.funding_pubkey; - - let as_network_key = nodes[0].node.get_our_node_id(); - let bs_network_key = nodes[1].node.get_our_node_id(); - - let were_node_one = as_bitcoin_key.serialize()[..] < bs_bitcoin_key.serialize()[..]; - - let mut chan_announcement; - - macro_rules! dummy_unsigned_msg { - () => { - msgs::UnsignedChannelAnnouncement { - features: ChannelFeatures::known(), - chain_hash: genesis_block(Network::Testnet).header.block_hash(), - short_channel_id: as_chan.get_short_channel_id().unwrap(), - node_id_1: if were_node_one { as_network_key } else { bs_network_key }, - node_id_2: if were_node_one { bs_network_key } else { as_network_key }, - bitcoin_key_1: if were_node_one { as_bitcoin_key } else { bs_bitcoin_key }, - bitcoin_key_2: if were_node_one { bs_bitcoin_key } else { as_bitcoin_key }, - excess_data: Vec::new(), - } - } - } - - macro_rules! sign_msg { - ($unsigned_msg: expr) => { - let msghash = Message::from_slice(&Sha256dHash::hash(&$unsigned_msg.encode()[..])[..]).unwrap(); - let as_bitcoin_sig = secp_ctx.sign(&msghash, &as_chan.get_signer().inner.funding_key); - let bs_bitcoin_sig = secp_ctx.sign(&msghash, &bs_chan.get_signer().inner.funding_key); - let as_node_sig = secp_ctx.sign(&msghash, &nodes[0].keys_manager.get_node_secret()); - let bs_node_sig = secp_ctx.sign(&msghash, &nodes[1].keys_manager.get_node_secret()); - chan_announcement = msgs::ChannelAnnouncement { - node_signature_1 : if were_node_one { as_node_sig } else { bs_node_sig}, - node_signature_2 : if were_node_one { bs_node_sig } else { as_node_sig}, - bitcoin_signature_1: if were_node_one { as_bitcoin_sig } else { bs_bitcoin_sig }, - bitcoin_signature_2 : if were_node_one { bs_bitcoin_sig } else { as_bitcoin_sig }, - contents: $unsigned_msg - } - } - } - - let unsigned_msg = dummy_unsigned_msg!(); - sign_msg!(unsigned_msg); - assert_eq!(nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).unwrap(), true); - let _ = nodes[0].net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap(), is_permanent: false } ); - - // Configured with Network::Testnet - let mut unsigned_msg = dummy_unsigned_msg!(); - unsigned_msg.chain_hash = genesis_block(Network::Bitcoin).header.block_hash(); - sign_msg!(unsigned_msg); - assert!(nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).is_err()); - - let mut unsigned_msg = dummy_unsigned_msg!(); - unsigned_msg.chain_hash = BlockHash::hash(&[1,2,3,4,5,6,7,8,9]); - sign_msg!(unsigned_msg); - assert!(nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).is_err()); -} - #[test] fn test_no_txn_manager_serialize_deserialize() { let chanmon_cfgs = create_chanmon_cfgs(2); From bd3ee0ab3d7f07afd73270da7e93d591c68cdc9d Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 24 Aug 2021 20:24:23 -0500 Subject: [PATCH 06/10] Fail with PERM|8 (permanent_channel_failure) This affects the htlc_fail_async_shutdown test. --- lightning/src/ln/channel.rs | 2 +- lightning/src/ln/channelmanager.rs | 43 +++++++++++++++--------------- lightning/src/ln/shutdown_tests.rs | 5 ++-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index bd97326ac12..7f84ecf3e59 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -2178,7 +2178,7 @@ impl Channel { // We can't accept HTLCs sent after we've sent a shutdown. let local_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::LocalShutdownSent as u32)) != (ChannelState::ChannelFunded as u32); if local_sent_shutdown { - pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x1000|20); + pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x4000|8); } // If the remote has sent a shutdown prior to adding this HTLC, then they are in violation of the spec. let remote_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 346dddf9261..35535c05880 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -3519,33 +3519,34 @@ impl ChannelMana } let create_pending_htlc_status = |chan: &Channel, pending_forward_info: PendingHTLCStatus, error_code: u16| { - // Ensure error_code has the UPDATE flag set, since by default we send a - // channel update along as part of failing the HTLC. - assert!((error_code & 0x1000) != 0); // If the update_add is completely bogus, the call will Err and we will close, // but if we've sent a shutdown and they haven't acknowledged it yet, we just // want to reject the new HTLC and fail it backwards instead of forwarding. match pending_forward_info { PendingHTLCStatus::Forward(PendingHTLCInfo { ref incoming_shared_secret, .. }) => { - let reason = if let Ok(upd) = self.get_channel_update_for_unicast(chan) { - onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{ - let mut res = Vec::with_capacity(8 + 128); - // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791 - res.extend_from_slice(&byte_utils::be16_to_array(0)); - res.extend_from_slice(&upd.encode_with_len()[..]); - res - }[..]) + let reason = if (error_code & 0x1000) != 0 { + if let Ok(upd) = self.get_channel_update_for_unicast(chan) { + onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{ + let mut res = Vec::with_capacity(8 + 128); + // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791 + res.extend_from_slice(&byte_utils::be16_to_array(0)); + res.extend_from_slice(&upd.encode_with_len()[..]); + res + }[..]) + } else { + // The only case where we'd be unable to + // successfully get a channel update is if the + // channel isn't in the fully-funded state yet, + // implying our counterparty is trying to route + // payments over the channel back to themselves + // (because no one else should know the short_id + // is a lightning channel yet). We should have + // no problem just calling this + // unknown_next_peer (0x4000|10). + onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[]) + } } else { - // The only case where we'd be unable to - // successfully get a channel update is if the - // channel isn't in the fully-funded state yet, - // implying our counterparty is trying to route - // payments over the channel back to themselves - // (cause no one else should know the short_id - // is a lightning channel yet). We should have - // no problem just calling this - // unknown_next_peer (0x4000|10). - onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[]) + onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &[]) }; let msg = msgs::UpdateFailHTLC { channel_id: msg.channel_id, diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index 9f5db40c883..c1140ac43e9 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -197,8 +197,9 @@ fn htlc_fail_async_shutdown() { let msg_events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(msg_events.len(), 2); match msg_events[0] { - MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }} => { - assert_eq!(msg.contents.short_channel_id, chan_1.0.contents.short_channel_id); + MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent }} => { + assert_eq!(short_channel_id, chan_2.0.contents.short_channel_id); + assert!(is_permanent); }, _ => panic!("Unexpected event"), } From eff9a47075445a3d4f3bf15ef68723c2ea6348e8 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 12 Aug 2021 15:30:53 -0500 Subject: [PATCH 07/10] Refactor PaymentFailureNetworkUpdate event MessageSendEvent::PaymentFailureNetworkUpdate served as a hack to pass an HTLCFailChannelUpdate from ChannelManager to NetGraphMsgHandler via PeerManager. Instead, remove the event entirely and move the contained data (renamed NetworkUpdate) to Event::PaymentFailed to be processed by an event handler. --- fuzz/src/chanmon_consistency.rs | 7 -- lightning-net-tokio/src/lib.rs | 1 - lightning/src/ln/channelmanager.rs | 17 ++--- lightning/src/ln/functional_test_utils.rs | 23 +++--- lightning/src/ln/functional_tests.rs | 85 ++++++++++------------- lightning/src/ln/monitor_tests.rs | 6 +- lightning/src/ln/msgs.rs | 31 --------- lightning/src/ln/onion_route_tests.rs | 78 ++++++++++----------- lightning/src/ln/onion_utils.rs | 25 +++---- lightning/src/ln/peer_handler.rs | 4 -- lightning/src/ln/reorg_tests.rs | 10 +-- lightning/src/ln/shutdown_tests.rs | 14 ++-- lightning/src/routing/network_graph.rs | 85 ++++++++++++++--------- lightning/src/util/events.rs | 21 +++--- lightning/src/util/test_utils.rs | 1 - 15 files changed, 183 insertions(+), 225 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 88826d65570..6e726a94752 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -594,7 +594,6 @@ pub fn do_test(data: &[u8], out: Out) { }, events::MessageSendEvent::SendFundingLocked { .. } => continue, events::MessageSendEvent::SendAnnouncementSignatures { .. } => continue, - events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => continue, events::MessageSendEvent::SendChannelUpdate { ref node_id, ref msg } => { assert_eq!(msg.contents.flags & 2, 0); // The disable bit must never be set! if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); } @@ -727,10 +726,6 @@ pub fn do_test(data: &[u8], out: Out) { events::MessageSendEvent::SendAnnouncementSignatures { .. } => { // Can be generated as a reestablish response }, - events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => { - // Can be generated due to a payment forward being rejected due to a - // channel having previously failed a monitor update - }, events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => { // When we reconnect we will resend a channel_update to make sure our // counterparty has the latest parameters for receiving payments @@ -769,7 +764,6 @@ pub fn do_test(data: &[u8], out: Out) { events::MessageSendEvent::SendChannelReestablish { .. } => {}, events::MessageSendEvent::SendFundingLocked { .. } => {}, events::MessageSendEvent::SendAnnouncementSignatures { .. } => {}, - events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {}, events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => { assert_eq!(msg.contents.flags & 2, 0); // The disable bit must never be set! }, @@ -787,7 +781,6 @@ pub fn do_test(data: &[u8], out: Out) { events::MessageSendEvent::SendChannelReestablish { .. } => {}, events::MessageSendEvent::SendFundingLocked { .. } => {}, events::MessageSendEvent::SendAnnouncementSignatures { .. } => {}, - events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {}, events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => { assert_eq!(msg.contents.flags & 2, 0); // The disable bit must never be set! }, diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index bf411211fdb..13a4c0d934f 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -492,7 +492,6 @@ mod tests { fn handle_node_announcement(&self, _msg: &NodeAnnouncement) -> Result { Ok(false) } fn handle_channel_announcement(&self, _msg: &ChannelAnnouncement) -> Result { Ok(false) } fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result { Ok(false) } - fn handle_htlc_fail_channel_update(&self, _update: &HTLCFailChannelUpdate) { } fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(ChannelAnnouncement, Option, Option)> { Vec::new() } fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec { Vec::new() } fn sync_routing_table(&self, _their_node_id: &PublicKey, _init_msg: &Init) { } diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 35535c05880..b772c5e9ac7 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -2822,6 +2822,7 @@ impl ChannelMana events::Event::PaymentFailed { payment_hash, rejected_by_dest: false, + network_update: None, #[cfg(test)] error_code: None, #[cfg(test)] @@ -2866,23 +2867,17 @@ impl ChannelMana match &onion_error { &HTLCFailReason::LightningError { ref err } => { #[cfg(test)] - let (channel_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); + let (network_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); #[cfg(not(test))] - let (channel_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); + let (network_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); // TODO: If we decided to blame ourselves (or one of our channels) in // process_onion_failure we should close that channel as it implies our // next-hop is needlessly blaming us! - if let Some(update) = channel_update { - self.channel_state.lock().unwrap().pending_msg_events.push( - events::MessageSendEvent::PaymentFailureNetworkUpdate { - update, - } - ); - } self.pending_events.lock().unwrap().push( events::Event::PaymentFailed { payment_hash: payment_hash.clone(), rejected_by_dest: !payment_retryable, + network_update, #[cfg(test)] error_code: onion_error_code, #[cfg(test)] @@ -2897,7 +2892,7 @@ impl ChannelMana ref data, .. } => { // we get a fail_malformed_htlc from the first hop - // TODO: We'd like to generate a PaymentFailureNetworkUpdate for temporary + // TODO: We'd like to generate a NetworkUpdate for temporary // failures here, but that would be insufficient as get_route // generally ignores its view of our own channels as we provide them via // ChannelDetails. @@ -2907,6 +2902,7 @@ impl ChannelMana events::Event::PaymentFailed { payment_hash: payment_hash.clone(), rejected_by_dest: path.len() == 1, + network_update: None, #[cfg(test)] error_code: Some(*failure_code), #[cfg(test)] @@ -4670,7 +4666,6 @@ impl &events::MessageSendEvent::BroadcastChannelUpdate { .. } => true, &events::MessageSendEvent::SendChannelUpdate { ref node_id, .. } => node_id != counterparty_node_id, &events::MessageSendEvent::HandleError { ref node_id, .. } => node_id != counterparty_node_id, - &events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => true, &events::MessageSendEvent::SendChannelRangeQuery { .. } => false, &events::MessageSendEvent::SendShortIdsQuery { .. } => false, &events::MessageSendEvent::SendReplyChannelRange { .. } => false, diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 4e7ca676d9f..96a6ae86d6d 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -1036,22 +1036,27 @@ macro_rules! expect_payment_forwarded { } #[cfg(test)] -macro_rules! expect_payment_failure_chan_update { - ($node: expr, $scid: expr, $chan_closed: expr) => { - let events = $node.node.get_and_clear_pending_msg_events(); +macro_rules! expect_payment_failed_with_update { + ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr, $scid: expr, $chan_closed: expr) => { + let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => { - match update { - &HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } if !$chan_closed => { + Event::PaymentFailed { ref payment_hash, rejected_by_dest, ref network_update, ref error_code, ref error_data } => { + assert_eq!(*payment_hash, $expected_payment_hash, "unexpected payment_hash"); + assert_eq!(rejected_by_dest, $rejected_by_dest, "unexpected rejected_by_dest value"); + assert!(error_code.is_some(), "expected error_code.is_some() = true"); + assert!(error_data.is_some(), "expected error_data.is_some() = true"); + match network_update { + &Some(NetworkUpdate::ChannelUpdateMessage { ref msg }) if !$chan_closed => { assert_eq!(msg.contents.short_channel_id, $scid); assert_eq!(msg.contents.flags & 2, 0); }, - &HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } if $chan_closed => { + &Some(NetworkUpdate::ChannelClosed { short_channel_id, is_permanent }) if $chan_closed => { assert_eq!(short_channel_id, $scid); assert!(is_permanent); }, - _ => panic!("Unexpected update type"), + Some(_) => panic!("Unexpected update type"), + None => panic!("Expected update"), } }, _ => panic!("Unexpected event"), @@ -1065,7 +1070,7 @@ macro_rules! expect_payment_failed { let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - Event::PaymentFailed { ref payment_hash, rejected_by_dest, ref error_code, ref error_data } => { + Event::PaymentFailed { ref payment_hash, rejected_by_dest, network_update: _, ref error_code, ref error_data } => { assert_eq!(*payment_hash, $expected_payment_hash, "unexpected payment_hash"); assert_eq!(rejected_by_dest, $rejected_by_dest, "unexpected rejected_by_dest value"); assert!(error_code.is_some(), "expected error_code.is_some() = true"); diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index eb3d3cb3bf0..e1a57cd7cc1 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -24,10 +24,10 @@ use ln::channel::{Channel, ChannelError}; use ln::{chan_utils, onion_utils}; use ln::chan_utils::HTLC_SUCCESS_TX_WEIGHT; use routing::router::{Route, RouteHop, RouteHint, RouteHintHop, get_route, get_keysend_route}; -use routing::network_graph::RoutingFees; +use routing::network_graph::{NetworkUpdate, RoutingFees}; use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures}; use ln::msgs; -use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate, ErrorAction}; +use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction}; use util::enforcing_trait_impls::EnforcingSigner; use util::{byte_utils, test_utils}; use util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose}; @@ -1050,8 +1050,7 @@ fn holding_cell_htlc_counting() { nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_updates.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], bs_fail_updates.commitment_signed, false, true); - expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, false); - expect_payment_failed!(nodes[0], payment_hash_2, false); + expect_payment_failed_with_update!(nodes[0], payment_hash_2, false, chan_2.0.contents.short_channel_id, false); // Now forward all the pending HTLCs and claim them back nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &initial_payment_event.msgs[0]); @@ -2833,8 +2832,7 @@ fn test_simple_commitment_revoked_fail_backward() { nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true); - expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, true); - expect_payment_failed!(nodes[0], payment_hash, false); + expect_payment_failed_with_update!(nodes[0], payment_hash, false, chan_2.0.contents.short_channel_id, true); }, _ => panic!("Unexpected event"), } @@ -3020,33 +3018,30 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true); - let events = nodes[0].node.get_and_clear_pending_msg_events(); - // If we delivered B's RAA we got an unknown preimage error, not something - // that we should update our routing table for. - assert_eq!(events.len(), if deliver_bs_raa { 2 } else { 3 }); - for event in events { - match event { - MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {}, - _ => panic!("Unexpected event"), - } - } let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 3); match events[0] { - Event::PaymentFailed { ref payment_hash, .. } => { + Event::PaymentFailed { ref payment_hash, rejected_by_dest: _, ref network_update, .. } => { assert!(failed_htlcs.insert(payment_hash.0)); + // If we delivered B's RAA we got an unknown preimage error, not something + // that we should update our routing table for. + if !deliver_bs_raa { + assert!(network_update.is_some()); + } }, _ => panic!("Unexpected event"), } match events[1] { - Event::PaymentFailed { ref payment_hash, .. } => { + Event::PaymentFailed { ref payment_hash, rejected_by_dest: _, ref network_update, .. } => { assert!(failed_htlcs.insert(payment_hash.0)); + assert!(network_update.is_some()); }, _ => panic!("Unexpected event"), } match events[2] { - Event::PaymentFailed { ref payment_hash, .. } => { + Event::PaymentFailed { ref payment_hash, rejected_by_dest: _, ref network_update, .. } => { assert!(failed_htlcs.insert(payment_hash.0)); + assert!(network_update.is_some()); }, _ => panic!("Unexpected event"), } @@ -4001,8 +3996,7 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { }, _ => unreachable!(), } - expect_payment_failed!(nodes[0], second_payment_hash, false); - expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, false); + expect_payment_failed_with_update!(nodes[0], second_payment_hash, false, chan_2.0.contents.short_channel_id, false); } else { expect_payment_failed!(nodes[1], second_payment_hash, true); } @@ -5106,9 +5100,8 @@ fn test_duplicate_payment_hash_one_failure_one_success() { assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); { commitment_signed_dance!(nodes[0], nodes[1], &htlc_updates.commitment_signed, false, true); - expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, true); } - expect_payment_failed!(nodes[0], duplicate_payment_hash, false); + expect_payment_failed_with_update!(nodes[0], duplicate_payment_hash, false, chan_2.0.contents.short_channel_id, true); // Solve 2nd HTLC by broadcasting on B's chain HTLC-Success Tx from C // Note that the fee paid is effectively double as the HTLC value (including the nodes[1] fee @@ -5375,14 +5368,18 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno let as_events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(as_events.len(), if announce_latest { 5 } else { 3 }); let mut as_failds = HashSet::new(); + let mut as_updates = 0; for event in as_events.iter() { - if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, .. } = event { + if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, .. } = event { assert!(as_failds.insert(*payment_hash)); if *payment_hash != payment_hash_2 { assert_eq!(*rejected_by_dest, deliver_last_raa); } else { assert!(!rejected_by_dest); } + if network_update.is_some() { + as_updates += 1; + } } else { panic!("Unexpected event"); } } assert!(as_failds.contains(&payment_hash_1)); @@ -5396,14 +5393,18 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno let bs_events = nodes[1].node.get_and_clear_pending_events(); assert_eq!(bs_events.len(), if announce_latest { 4 } else { 3 }); let mut bs_failds = HashSet::new(); + let mut bs_updates = 0; for event in bs_events.iter() { - if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, .. } = event { + if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, .. } = event { assert!(bs_failds.insert(*payment_hash)); if *payment_hash != payment_hash_1 && *payment_hash != payment_hash_5 { assert_eq!(*rejected_by_dest, deliver_last_raa); } else { assert!(!rejected_by_dest); } + if network_update.is_some() { + bs_updates += 1; + } } else { panic!("Unexpected event"); } } assert!(bs_failds.contains(&payment_hash_1)); @@ -5414,20 +5415,11 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno assert!(bs_failds.contains(&payment_hash_5)); // For each HTLC which was not failed-back by normal process (ie deliver_last_raa), we should - // get a PaymentFailureNetworkUpdate. A should have gotten 4 HTLCs which were failed-back due - // to unknown-preimage-etc, B should have gotten 2. Thus, in the - // announce_latest && deliver_last_raa case, we should have 5-4=1 and 4-2=2 - // PaymentFailureNetworkUpdates. - let as_msg_events = nodes[0].node.get_and_clear_pending_msg_events(); - assert_eq!(as_msg_events.len(), if deliver_last_raa { 1 } else if !announce_latest { 3 } else { 5 }); - let bs_msg_events = nodes[1].node.get_and_clear_pending_msg_events(); - assert_eq!(bs_msg_events.len(), if deliver_last_raa { 2 } else if !announce_latest { 3 } else { 4 }); - for event in as_msg_events.iter().chain(bs_msg_events.iter()) { - match event { - &MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {}, - _ => panic!("Unexpected event"), - } - } + // get a NetworkUpdate. A should have gotten 4 HTLCs which were failed-back due to + // unknown-preimage-etc, B should have gotten 2. Thus, in the + // announce_latest && deliver_last_raa case, we should have 5-4=1 and 4-2=2 NetworkUpdates. + assert_eq!(as_updates, if deliver_last_raa { 1 } else if !announce_latest { 3 } else { 5 }); + assert_eq!(bs_updates, if deliver_last_raa { 2 } else if !announce_latest { 3 } else { 4 }); } #[test] @@ -5921,9 +5913,10 @@ fn test_fail_holding_cell_htlc_upon_free() { let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match &events[0] { - &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref error_code, ref error_data } => { + &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref error_code, ref error_data } => { assert_eq!(our_payment_hash.clone(), *payment_hash); assert_eq!(*rejected_by_dest, false); + assert_eq!(*network_update, None); assert_eq!(*error_code, None); assert_eq!(*error_data, None); }, @@ -6006,9 +5999,10 @@ fn test_free_and_fail_holding_cell_htlcs() { let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match &events[0] { - &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref error_code, ref error_data } => { + &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref error_code, ref error_data } => { assert_eq!(payment_hash_2.clone(), *payment_hash); assert_eq!(*rejected_by_dest, false); + assert_eq!(*network_update, None); assert_eq!(*error_code, None); assert_eq!(*error_data, None); }, @@ -6189,8 +6183,7 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() { _ => panic!("Unexpected event"), }; nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &raa); - expect_payment_failure_chan_update!(nodes[0], chan_1_2.0.contents.short_channel_id, false); - expect_payment_failed!(nodes[0], our_payment_hash, false); + expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_1_2.0.contents.short_channel_id, false); check_added_monitors!(nodes[0], 1); } @@ -7455,8 +7448,7 @@ fn test_priv_forwarding_rejection() { nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_fail_updates.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], htlc_fail_updates.commitment_signed, true, true); - expect_payment_failed!(nodes[0], our_payment_hash, false); - expect_payment_failure_chan_update!(nodes[0], nodes[2].node.list_channels()[0].short_channel_id.unwrap(), true); + expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, nodes[2].node.list_channels()[0].short_channel_id.unwrap(), true); // Now disconnect nodes[1] from its peers and restart with accept_forwards_to_priv_channels set // to true. Sadly there is currently no way to change it at runtime. @@ -9012,8 +9004,7 @@ fn do_test_tx_confirmed_skipping_blocks_immediate_broadcast(test_height_before_t assert!(updates.update_fee.is_none()); nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], updates.commitment_signed, true, true); - expect_payment_failed!(nodes[0], payment_hash, false); - expect_payment_failure_chan_update!(nodes[0], chan_announce.contents.short_channel_id, true); + expect_payment_failed_with_update!(nodes[0], payment_hash, false, chan_announce.contents.short_channel_id, true); } } diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 8fdf28e578b..2d3c8f59fb6 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -12,8 +12,9 @@ use chain::channelmonitor::ANTI_REORG_DELAY; use ln::{PaymentPreimage, PaymentHash}; use ln::features::InitFeatures; -use ln::msgs::{ChannelMessageHandler, HTLCFailChannelUpdate, ErrorAction}; +use ln::msgs::{ChannelMessageHandler, ErrorAction}; use util::events::{Event, MessageSendEvent, MessageSendEventsProvider}; +use routing::network_graph::NetworkUpdate; use routing::router::get_route; use bitcoin::hashes::sha256::Hash as Sha256; @@ -76,6 +77,5 @@ fn chanmon_fail_from_stale_commitment() { nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], fail_updates.commitment_signed, true, true); - expect_payment_failed!(nodes[0], payment_hash, false); - expect_payment_failure_chan_update!(nodes[0], update_a.contents.short_channel_id, true); + expect_payment_failed_with_update!(nodes[0], payment_hash, false, update_a.contents.short_channel_id, true); } diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 5b49f43b118..7c2647916e5 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -745,35 +745,6 @@ pub struct CommitmentUpdate { pub commitment_signed: CommitmentSigned, } -/// The information we received from a peer along the route of a payment we originated. This is -/// returned by ChannelMessageHandler::handle_update_fail_htlc to be passed into -/// RoutingMessageHandler::handle_htlc_fail_channel_update to update our network map. -#[derive(Clone, Debug, PartialEq)] -pub enum HTLCFailChannelUpdate { - /// We received an error which included a full ChannelUpdate message. - ChannelUpdateMessage { - /// The unwrapped message we received - msg: ChannelUpdate, - }, - /// We received an error which indicated only that a channel has been closed - ChannelClosed { - /// The short_channel_id which has now closed. - short_channel_id: u64, - /// when this true, this channel should be permanently removed from the - /// consideration. Otherwise, this channel can be restored as new channel_update is received - is_permanent: bool, - }, - /// We received an error which indicated only that a node has failed - NodeFailure { - /// The node_id that has failed. - node_id: PublicKey, - /// when this true, node should be permanently removed from the - /// consideration. Otherwise, the channels connected to this node can be - /// restored as new channel_update is received - is_permanent: bool, - } -} - /// Messages could have optional fields to use with extended features /// As we wish to serialize these differently from Options (Options get a tag byte, but /// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a @@ -868,8 +839,6 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider { /// Handle an incoming channel_update message, returning true if it should be forwarded on, /// false or returning an Err otherwise. fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result; - /// Handle some updates to the route graph that we learned due to an outbound failed payment. - fn handle_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate); /// Gets a subset of the channel announcements and updates required to dump our routing table /// to a remote node, starting at the short_channel_id indicated by starting_point and /// including the batch_amount entries immediately higher in numerical value than starting_point. diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index 1006d9da133..bcc05fdb030 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -16,9 +16,10 @@ use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; use ln::channelmanager::{HTLCForwardInfo, CLTV_FAR_FAR_AWAY}; use ln::onion_utils; use routing::router::{Route, get_route}; +use routing::network_graph::NetworkUpdate; use ln::features::{InitFeatures, InvoiceFeatures}; use ln::msgs; -use ln::msgs::{ChannelMessageHandler, ChannelUpdate, HTLCFailChannelUpdate, OptionalField}; +use ln::msgs::{ChannelMessageHandler, ChannelUpdate, OptionalField}; use util::test_utils; use util::events::{Event, MessageSendEvent, MessageSendEventsProvider}; use util::ser::{Writeable, Writer}; @@ -39,7 +40,7 @@ use core::default::Default; use ln::functional_test_utils::*; -fn run_onion_failure_test(_name: &str, test_case: u8, nodes: &Vec, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option, expected_channel_update: Option) +fn run_onion_failure_test(_name: &str, test_case: u8, nodes: &Vec, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option, expected_channel_update: Option) where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC), F2: FnMut(), { @@ -53,7 +54,7 @@ fn run_onion_failure_test(_name: &str, test_case: u8, nodes: &Vec, // 3: final node fails backward (but tamper onion payloads from node0) // 100: trigger error in the intermediate node and tamper returning fail_htlc // 200: trigger error in the final node and tamper returning fail_htlc -fn run_onion_failure_test_with_fail_intercept(_name: &str, test_case: u8, nodes: &Vec, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option, expected_channel_update: Option) +fn run_onion_failure_test_with_fail_intercept(_name: &str, test_case: u8, nodes: &Vec, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option, expected_channel_update: Option) where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC), F2: for <'a> FnMut(&'a mut msgs::UpdateFailHTLC), F3: FnMut(), @@ -162,34 +163,27 @@ fn run_onion_failure_test_with_fail_intercept(_name: &str, test_case: let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); - if let &Event::PaymentFailed { payment_hash:_, ref rejected_by_dest, ref error_code, error_data: _ } = &events[0] { + if let &Event::PaymentFailed { payment_hash:_, ref rejected_by_dest, ref network_update, ref error_code, error_data: _ } = &events[0] { assert_eq!(*rejected_by_dest, !expected_retryable); assert_eq!(*error_code, expected_error_code); - } else { - panic!("Uexpected event"); - } - - let events = nodes[0].node.get_and_clear_pending_msg_events(); - if expected_channel_update.is_some() { - assert_eq!(events.len(), 1); - match events[0] { - MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => { - match update { - &HTLCFailChannelUpdate::ChannelUpdateMessage { .. } => { - if let HTLCFailChannelUpdate::ChannelUpdateMessage { .. } = expected_channel_update.unwrap() {} else { + if expected_channel_update.is_some() { + match network_update { + Some(update) => match update { + &NetworkUpdate::ChannelUpdateMessage { .. } => { + if let NetworkUpdate::ChannelUpdateMessage { .. } = expected_channel_update.unwrap() {} else { panic!("channel_update not found!"); } }, - &HTLCFailChannelUpdate::ChannelClosed { ref short_channel_id, ref is_permanent } => { - if let HTLCFailChannelUpdate::ChannelClosed { short_channel_id: ref expected_short_channel_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() { + &NetworkUpdate::ChannelClosed { ref short_channel_id, ref is_permanent } => { + if let NetworkUpdate::ChannelClosed { short_channel_id: ref expected_short_channel_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() { assert!(*short_channel_id == *expected_short_channel_id); assert!(*is_permanent == *expected_is_permanent); } else { panic!("Unexpected message event"); } }, - &HTLCFailChannelUpdate::NodeFailure { ref node_id, ref is_permanent } => { - if let HTLCFailChannelUpdate::NodeFailure { node_id: ref expected_node_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() { + &NetworkUpdate::NodeFailure { ref node_id, ref is_permanent } => { + if let NetworkUpdate::NodeFailure { node_id: ref expected_node_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() { assert!(*node_id == *expected_node_id); assert!(*is_permanent == *expected_is_permanent); } else { @@ -197,11 +191,13 @@ fn run_onion_failure_test_with_fail_intercept(_name: &str, test_case: } }, } - }, - _ => panic!("Unexpected message event"), + None => panic!("Expected channel update"), + } + } else { + assert!(network_update.is_none()); } } else { - assert_eq!(events.len(), 0); + panic!("Unexpected event"); } } @@ -275,7 +271,7 @@ fn test_fee_failures() { let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.amount_msat -= 1; - }, || {}, true, Some(UPDATE|12), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true})); + }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true})); // In an earlier version, we spuriously failed to forward payments if the expected feerate // changed between the channel open and the payment. @@ -336,7 +332,7 @@ fn test_onion_failure() { // describing a length-1 TLV payload, which is obviously bogus. new_payloads[0].data[0] = 1; msg.onion_routing_packet = onion_utils::construct_onion_packet_bogus_hopdata(new_payloads, onion_keys, [0; 32], &payment_hash); - }, ||{}, true, Some(PERM|22), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));//XXX incremented channels idx here + }, ||{}, true, Some(PERM|22), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); // final node failure run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, &payment_secret, |msg| { @@ -352,7 +348,7 @@ fn test_onion_failure() { // length-1 TLV payload, which is obviously bogus. new_payloads[1].data[0] = 1; msg.onion_routing_packet = onion_utils::construct_onion_packet_bogus_hopdata(new_payloads, onion_keys, [0; 32], &payment_hash); - }, ||{}, false, Some(PERM|22), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); + }, ||{}, false, Some(PERM|22), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); // the following three with run_onion_failure_test_with_fail_intercept() test only the origin node // receiving simulated fail messages @@ -365,7 +361,7 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], NODE|2, &[0;0]); - }, ||{}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: false})); + }, ||{}, true, Some(NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: false})); // final node failure run_onion_failure_test_with_fail_intercept("temporary_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| { @@ -375,7 +371,7 @@ fn test_onion_failure() { msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]); }, ||{ nodes[2].node.fail_htlc_backwards(&payment_hash); - }, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: false})); + }, true, Some(NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: false})); let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); // intermediate node failure @@ -385,7 +381,7 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|2, &[0;0]); - }, ||{}, true, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true})); + }, ||{}, true, Some(PERM|NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true})); // final node failure run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| { @@ -394,7 +390,7 @@ fn test_onion_failure() { msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]); }, ||{ nodes[2].node.fail_htlc_backwards(&payment_hash); - }, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true})); + }, false, Some(PERM|NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true})); let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); // intermediate node failure @@ -406,7 +402,7 @@ fn test_onion_failure() { msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]); }, ||{ nodes[2].node.fail_htlc_backwards(&payment_hash); - }, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true})); + }, true, Some(PERM|NODE|3), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true})); // final node failure run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| { @@ -415,7 +411,7 @@ fn test_onion_failure() { msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]); }, ||{ nodes[2].node.fail_htlc_backwards(&payment_hash); - }, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true})); + }, false, Some(PERM|NODE|3), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true})); let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); run_onion_failure_test("invalid_onion_version", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.onion_routing_packet.version = 1; }, ||{}, true, @@ -433,7 +429,7 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy().encode_with_len()[..]); - }, ||{}, true, Some(UPDATE|7), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); + }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.amount_msat -= 1; @@ -442,7 +438,7 @@ fn test_onion_failure() { let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|8, &[0;0]); // short_channel_id from the processing node - }, ||{}, true, Some(PERM|8), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); + }, ||{}, true, Some(PERM|8), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); run_onion_failure_test_with_fail_intercept("required_channel_feature_missing", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.amount_msat -= 1; @@ -451,18 +447,18 @@ fn test_onion_failure() { let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|9, &[0;0]); // short_channel_id from the processing node - }, ||{}, true, Some(PERM|9), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); + }, ||{}, true, Some(PERM|9), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true})); let mut bogus_route = route.clone(); bogus_route.paths[0][1].short_channel_id -= 1; run_onion_failure_test("unknown_next_peer", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(PERM|10), - Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: bogus_route.paths[0][1].short_channel_id, is_permanent:true})); + Some(NetworkUpdate::ChannelClosed{short_channel_id: bogus_route.paths[0][1].short_channel_id, is_permanent:true})); let amt_to_forward = nodes[1].node.channel_state.lock().unwrap().by_id.get(&channels[1].2).unwrap().get_counterparty_htlc_minimum_msat() - 1; let mut bogus_route = route.clone(); let route_len = bogus_route.paths[0].len(); bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward; - run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); + run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); // Test a positive test-case with one extra msat, meeting the minimum. bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward + 1; @@ -473,19 +469,19 @@ fn test_onion_failure() { //invalid channel_update cases. run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.amount_msat -= 1; - }, || {}, true, Some(UPDATE|12), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true})); + }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true})); run_onion_failure_test("incorrect_cltv_expiry", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { // need to violate: cltv_expiry - cltv_expiry_delta >= outgoing_cltv_value msg.cltv_expiry -= 1; - }, || {}, true, Some(UPDATE|13), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true})); + }, || {}, true, Some(UPDATE|13), Some(NetworkUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true})); run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1; connect_blocks(&nodes[0], height - nodes[0].best_block_info().1); connect_blocks(&nodes[1], height - nodes[1].best_block_info().1); connect_blocks(&nodes[2], height - nodes[2].best_block_info().1); - }, ||{}, true, Some(UPDATE|14), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); + }, ||{}, true, Some(UPDATE|14), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || { nodes[2].node.fail_htlc_backwards(&payment_hash); @@ -528,7 +524,7 @@ fn test_onion_failure() { // disconnect event to the channel between nodes[1] ~ nodes[2] nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false); nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); - }, true, Some(UPDATE|20), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); + }, true, Some(UPDATE|20), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 4886168dd16..f6c62cb83ca 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -10,6 +10,7 @@ use ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use ln::channelmanager::HTLCSource; use ln::msgs; +use routing::network_graph::NetworkUpdate; use routing::router::RouteHop; use util::chacha20::ChaCha20; use util::errors::{self, APIError}; @@ -330,7 +331,7 @@ pub(super) fn build_first_hop_failure_packet(shared_secret: &[u8], failure_type: /// OutboundRoute). /// Returns update, a boolean indicating that the payment itself failed, and the error code. #[inline] -pub(super) fn process_onion_failure(secp_ctx: &Secp256k1, logger: &L, htlc_source: &HTLCSource, mut packet_decrypted: Vec) -> (Option, bool, Option, Option>) where L::Target: Logger { +pub(super) fn process_onion_failure(secp_ctx: &Secp256k1, logger: &L, htlc_source: &HTLCSource, mut packet_decrypted: Vec) -> (Option, bool, Option, Option>) where L::Target: Logger { if let &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat } = htlc_source { let mut res = None; let mut htlc_msat = *first_hop_htlc_msat; @@ -382,13 +383,13 @@ pub(super) fn process_onion_failure(secp_ctx: & } && is_from_final_node) // PERM bit observed below even this error is from the intermediate nodes || error_code == 21; // Special case error 21 as the Route object is bogus, TODO: Maybe fail the node if the CLTV was reasonable? - let mut fail_channel_update = None; + let mut network_update = None; if error_code & NODE == NODE { - fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: error_code & PERM == PERM }); + network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: error_code & PERM == PERM }); } else if error_code & PERM == PERM { - fail_channel_update = if payment_failed {None} else {Some(msgs::HTLCFailChannelUpdate::ChannelClosed { + network_update = if payment_failed { None } else { Some(NetworkUpdate::ChannelClosed { short_channel_id: path[next_route_hop_ix - if next_route_hop_ix == path.len() { 1 } else { 0 }].short_channel_id, is_permanent: true, })}; @@ -412,25 +413,25 @@ pub(super) fn process_onion_failure(secp_ctx: & 20 => chan_update.contents.flags & 2 == 0, _ => false, // unknown error code; take channel_update as valid }; - fail_channel_update = if is_chan_update_invalid { + network_update = if is_chan_update_invalid { // This probably indicates the node which forwarded // to the node in question corrupted something. - Some(msgs::HTLCFailChannelUpdate::ChannelClosed { + Some(NetworkUpdate::ChannelClosed { short_channel_id: route_hop.short_channel_id, is_permanent: true, }) } else { - Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { + Some(NetworkUpdate::ChannelUpdateMessage { msg: chan_update, }) }; } } } - if fail_channel_update.is_none() { + if network_update.is_none() { // They provided an UPDATE which was obviously bogus, not worth // trying to relay through them anymore. - fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { + network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true, }); @@ -439,7 +440,7 @@ pub(super) fn process_onion_failure(secp_ctx: & // We can't understand their error messages and they failed to // forward...they probably can't understand our forwards so its // really not worth trying any further. - fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { + network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true, }); @@ -448,7 +449,7 @@ pub(super) fn process_onion_failure(secp_ctx: & // TODO: Here (and a few other places) we assume that BADONION errors // are always "sourced" from the node previous to the one which failed // to decode the onion. - res = Some((fail_channel_update, !(error_code & PERM == PERM && is_from_final_node))); + res = Some((network_update, !(error_code & PERM == PERM && is_from_final_node))); let (description, title) = errors::get_onion_error_description(error_code); if debug_field_size > 0 && err_packet.failuremsg.len() >= 4 + debug_field_size { @@ -460,7 +461,7 @@ pub(super) fn process_onion_failure(secp_ctx: & } else { // Useless packet that we can't use but it passed HMAC, so it // definitely came from the peer in question - res = Some((Some(msgs::HTLCFailChannelUpdate::NodeFailure { + res = Some((Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true, }), !is_from_final_node)); diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 34bcda3a009..60d7a8750d8 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -66,7 +66,6 @@ impl RoutingMessageHandler for IgnoringMessageHandler { fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result { Ok(false) } fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result { Ok(false) } fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result { Ok(false) } - fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {} fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option, Option)> { Vec::new() } fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec { Vec::new() } @@ -1318,9 +1317,6 @@ impl P let peer = get_peer_for_forwarding!(node_id); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); }, - MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => { - self.message_handler.route_handler.handle_htlc_fail_channel_update(update); - }, MessageSendEvent::HandleError { ref node_id, ref action } => { match *action { msgs::ErrorAction::DisconnectPeer { ref msg } => { diff --git a/lightning/src/ln/reorg_tests.rs b/lightning/src/ln/reorg_tests.rs index bbdb5bfac6b..0db30b8178c 100644 --- a/lightning/src/ln/reorg_tests.rs +++ b/lightning/src/ln/reorg_tests.rs @@ -14,7 +14,8 @@ use chain::transaction::OutPoint; use chain::{Confirm, Watch}; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs}; use ln::features::InitFeatures; -use ln::msgs::{ChannelMessageHandler, ErrorAction, HTLCFailChannelUpdate}; +use ln::msgs::{ChannelMessageHandler, ErrorAction}; +use routing::network_graph::NetworkUpdate; use util::enforcing_trait_impls::EnforcingSigner; use util::events::{Event, MessageSendEvent, MessageSendEventsProvider}; use util::test_utils; @@ -163,12 +164,7 @@ fn do_test_onchain_htlc_reorg(local_commitment: bool, claim: bool) { if claim { expect_payment_sent!(nodes[0], our_payment_preimage); } else { - let events = nodes[0].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 1); - if let MessageSendEvent::PaymentFailureNetworkUpdate { update: HTLCFailChannelUpdate::ChannelClosed { ref is_permanent, .. } } = events[0] { - assert!(is_permanent); - } else { panic!("Unexpected event!"); } - expect_payment_failed!(nodes[0], our_payment_hash, false); + expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_2.0.contents.short_channel_id, true); } } diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index c1140ac43e9..26d39fbad9d 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -13,6 +13,7 @@ use chain::keysinterface::KeysInterface; use chain::transaction::OutPoint; use ln::{PaymentPreimage, PaymentHash}; use ln::channelmanager::PaymentSendFailure; +use routing::network_graph::NetworkUpdate; use routing::router::get_route; use ln::features::{InitFeatures, InvoiceFeatures}; use ln::msgs; @@ -192,18 +193,11 @@ fn htlc_fail_async_shutdown() { nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates_2.update_fail_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], updates_2.commitment_signed, false, true); - expect_payment_failed!(nodes[0], our_payment_hash, false); + expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_2.0.contents.short_channel_id, true); let msg_events = nodes[0].node.get_and_clear_pending_msg_events(); - assert_eq!(msg_events.len(), 2); - match msg_events[0] { - MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent }} => { - assert_eq!(short_channel_id, chan_2.0.contents.short_channel_id); - assert!(is_permanent); - }, - _ => panic!("Unexpected event"), - } - let node_0_closing_signed = match msg_events[1] { + assert_eq!(msg_events.len(), 1); + let node_0_closing_signed = match msg_events[0] { MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => { assert_eq!(*node_id, nodes[1].node.get_our_node_id()); (*msg).clone() diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 61e94e0494c..1a149b3bd76 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -64,6 +64,52 @@ pub struct ReadOnlyNetworkGraph<'a> { nodes: RwLockReadGuard<'a, BTreeMap>, } +/// Update to the [`NetworkGraph`] based on payment failure information conveyed via the Onion +/// return packet by a node along the route. See [BOLT #4] for details. +/// +/// [BOLT #4]: https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md +#[derive(Clone, Debug, PartialEq)] +pub enum NetworkUpdate { + /// An error indicating a `channel_update` messages should be applied via + /// [`NetworkGraph::update_channel`]. + ChannelUpdateMessage { + /// The update to apply via [`NetworkGraph::update_channel`]. + msg: ChannelUpdate, + }, + /// An error indicating only that a channel has been closed, which should be applied via + /// [`NetworkGraph::close_channel_from_update`]. + ChannelClosed { + /// The short channel id of the closed channel. + short_channel_id: u64, + /// Whether the channel should be permanently removed or temporarily disabled until a new + /// `channel_update` message is received. + is_permanent: bool, + }, + /// An error indicating only that a node has failed, which should be applied via + /// [`NetworkGraph::fail_node`]. + NodeFailure { + /// The node id of the failed node. + node_id: PublicKey, + /// Whether the node should be permanently removed from consideration or can be restored + /// when a new `channel_update` message is received. + is_permanent: bool, + } +} + +impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate, + (0, ChannelUpdateMessage) => { + (0, msg, required), + }, + (2, ChannelClosed) => { + (0, short_channel_id, required), + (2, is_permanent, required), + }, + (4, NodeFailure) => { + (0, node_id, required), + (2, is_permanent, required), + }, +); + /// Receives and validates network updates from peers, /// stores authentic and relevant data as a network graph. /// This network graph is then used for routing payments. @@ -152,24 +198,6 @@ impl RoutingMessageHandler for NetGraphMsgHandler wh Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } - fn handle_htlc_fail_channel_update(&self, update: &msgs::HTLCFailChannelUpdate) { - match update { - &msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } => { - let chan_enabled = msg.contents.flags & (1 << 1) != (1 << 1); - log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}abled.", msg.contents.short_channel_id, if chan_enabled { "en" } else { "dis" }); - let _ = self.network_graph.update_channel(msg, &self.secp_ctx); - }, - &msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } => { - log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", if is_permanent { "Removing" } else { "Disabling" }, short_channel_id); - self.network_graph.close_channel_from_update(short_channel_id, is_permanent); - }, - &msgs::HTLCFailChannelUpdate::NodeFailure { ref node_id, is_permanent } => { - log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", if is_permanent { "Removing" } else { "Disabling" }, node_id); - self.network_graph.fail_node(node_id, is_permanent); - }, - } - } - fn handle_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result { self.network_graph.update_channel(msg, &self.secp_ctx)?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) @@ -898,7 +926,8 @@ impl NetworkGraph { } } - fn fail_node(&self, _node_id: &PublicKey, is_permanent: bool) { + /// Marks a node in the graph as failed. + pub fn fail_node(&self, _node_id: &PublicKey, is_permanent: bool) { if is_permanent { // TODO: Wholly remove the node } else { @@ -1090,7 +1119,7 @@ mod tests { use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; use routing::network_graph::{NetGraphMsgHandler, NetworkGraph, MAX_EXCESS_BYTES_FOR_RELAY}; use ln::msgs::{Init, OptionalField, RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement, - UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, HTLCFailChannelUpdate, + UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, ReplyChannelRange, ReplyShortChannelIdsEnd, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT}; use util::test_utils; use util::logger::Logger; @@ -1671,12 +1700,7 @@ mod tests { }; } - let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed { - short_channel_id, - is_permanent: false - }; - - net_graph_msg_handler.handle_htlc_fail_channel_update(&channel_close_msg); + net_graph_msg_handler.network_graph.close_channel_from_update(short_channel_id, false); // Non-permanent closing just disables a channel { @@ -1689,12 +1713,7 @@ mod tests { }; } - let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed { - short_channel_id, - is_permanent: true - }; - - net_graph_msg_handler.handle_htlc_fail_channel_update(&channel_close_msg); + net_graph_msg_handler.network_graph.close_channel_from_update(short_channel_id, true); // Permanent closing deletes a channel { @@ -1703,7 +1722,7 @@ mod tests { // Nodes are also deleted because there are no associated channels anymore assert_eq!(network.read_only().nodes().len(), 0); } - // TODO: Test HTLCFailChannelUpdate::NodeFailure, which is not implemented yet. + // TODO: Test NetworkUpdate::NodeFailure, which is not implemented yet. } #[test] diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index d4288164cd9..bde7d8c4413 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -14,9 +14,10 @@ //! future, as well as generate and broadcast funding transactions handle payment preimages and a //! few other things. +use chain::keysinterface::SpendableOutputDescriptor; use ln::msgs; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; -use chain::keysinterface::SpendableOutputDescriptor; +use routing::network_graph::NetworkUpdate; use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper}; use bitcoin::blockdata::script::Script; @@ -128,6 +129,12 @@ pub enum Event { /// the payment has failed, not just the route in question. If this is not set, you may /// retry the payment via a different route. rejected_by_dest: bool, + /// Any failure information conveyed via the Onion return packet by a node along the failed + /// payment route. Should be applied to the [`NetworkGraph`] so that routing decisions can + /// take into account the update. + /// + /// [`NetworkGraph`]: crate::routing::network_graph::NetworkGraph + network_update: Option, #[cfg(test)] error_code: Option, #[cfg(test)] @@ -211,7 +218,7 @@ impl Writeable for Event { (0, payment_preimage, required), }); }, - &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, + &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, #[cfg(test)] ref error_code, #[cfg(test)] @@ -224,6 +231,7 @@ impl Writeable for Event { error_data.write(writer)?; write_tlv_fields!(writer, { (0, payment_hash, required), + (1, network_update, option), (2, rejected_by_dest, required), }); }, @@ -307,13 +315,16 @@ impl MaybeReadable for Event { let error_data = Readable::read(reader)?; let mut payment_hash = PaymentHash([0; 32]); let mut rejected_by_dest = false; + let mut network_update = None; read_tlv_fields!(reader, { (0, payment_hash, required), + (1, network_update, ignorable), (2, rejected_by_dest, required), }); Ok(Some(Event::PaymentFailed { payment_hash, rejected_by_dest, + network_update, #[cfg(test)] error_code, #[cfg(test)] @@ -485,12 +496,6 @@ pub enum MessageSendEvent { /// The action which should be taken. action: msgs::ErrorAction }, - /// When a payment fails we may receive updates back from the hop where it failed. In such - /// cases this event is generated so that we can inform the network graph of this information. - PaymentFailureNetworkUpdate { - /// The channel/node update which should be sent to NetGraphMsgHandler - update: msgs::HTLCFailChannelUpdate, - }, /// Query a peer for channels with funding transaction UTXOs in a block range. SendChannelRangeQuery { /// The node_id of this message recipient diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 64b88acb008..6dd5836c480 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -349,7 +349,6 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler { self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel); Err(msgs::LightningError { err: "".to_owned(), action: msgs::ErrorAction::IgnoreError }) } - fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {} fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option, Option)> { let mut chan_anns = Vec::new(); const TOTAL_UPDS: u64 = 100; From ba2c00b3f8e22ca2bf72af1c629ba811596aa7ba Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 12 Aug 2021 16:02:42 -0500 Subject: [PATCH 08/10] EventHandler for applying NetworkUpdate PaymentFailed events contain an optional NetworkUpdate describing changes to the NetworkGraph as conveyed by a node along a failed payment path according to BOLT 4. An EventHandler should apply the update to the graph so that future routing decisions can account for it. Implement EventHandler for NetGraphMsgHandler to update NetworkGraph. Previously, NetGraphMsgHandler::handle_htlc_fail_channel_update implemented this behavior. --- fuzz/src/full_stack.rs | 5 +- lightning/src/ln/functional_test_utils.rs | 7 +- lightning/src/routing/network_graph.rs | 163 +++++++++++++++------- lightning/src/routing/router.rs | 23 ++- lightning/src/util/events.rs | 7 +- 5 files changed, 140 insertions(+), 65 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index ee7b2d18ae3..d82ff88d9c7 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -38,7 +38,7 @@ use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor,Ig use lightning::ln::msgs::DecodeError; use lightning::ln::script::ShutdownScript; use lightning::routing::router::get_route; -use lightning::routing::network_graph::NetGraphMsgHandler; +use lightning::routing::network_graph::{NetGraphMsgHandler, NetworkGraph}; use lightning::util::config::UserConfig; use lightning::util::errors::APIError; use lightning::util::events::Event; @@ -378,7 +378,8 @@ pub fn do_test(data: &[u8], logger: &Arc) { }; let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params)); let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret()); - let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_block(network).block_hash(), None, Arc::clone(&logger))); + let network_graph = NetworkGraph::new(genesis_block(network).block_hash()); + let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger))); let peers = RefCell::new([false; 256]); let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler { diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 96a6ae86d6d..6824fb043a9 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -243,8 +243,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { network_graph_ser.write(&mut w).unwrap(); let network_graph_deser = ::read(&mut io::Cursor::new(&w.0)).unwrap(); assert!(network_graph_deser == self.net_graph_msg_handler.network_graph); - let net_graph_msg_handler = NetGraphMsgHandler::from_net_graph( - Some(self.chain_source), self.logger, network_graph_deser + let net_graph_msg_handler = NetGraphMsgHandler::new( + network_graph_deser, Some(self.chain_source), self.logger ); let mut chan_progress = 0; loop { @@ -1440,7 +1440,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec EventHandler for NetGraphMsgHandler +where C::Target: chain::Access, L::Target: Logger { + fn handle_event(&self, event: &Event) { + if let Event::PaymentFailed { payment_hash: _, rejected_by_dest: _, network_update, .. } = event { + if let Some(network_update) = network_update { + self.handle_network_update(network_update); + } + } + } +} + /// Receives and validates network updates from peers, /// stores authentic and relevant data as a network graph. /// This network graph is then used for routing payments. /// Provides interface to help with initial routing sync by /// serving historical announcements. -pub struct NetGraphMsgHandler where C::Target: chain::Access, L::Target: Logger { +/// +/// Serves as an [`EventHandler`] for applying updates from [`Event::PaymentFailed`] to the +/// [`NetworkGraph`]. +pub struct NetGraphMsgHandler +where C::Target: chain::Access, L::Target: Logger +{ secp_ctx: Secp256k1, /// Representation of the payment channel network pub network_graph: NetworkGraph, @@ -125,26 +141,15 @@ pub struct NetGraphMsgHandler where C::Target: chain::Access logger: L, } -impl NetGraphMsgHandler where C::Target: chain::Access, L::Target: Logger { +impl NetGraphMsgHandler +where C::Target: chain::Access, L::Target: Logger +{ /// Creates a new tracker of the actual state of the network of channels and nodes, - /// assuming a fresh network graph. + /// assuming an existing Network Graph. /// Chain monitor is used to make sure announced channels exist on-chain, /// channel data is correct, and that the announcement is signed with /// channel owners' keys. - pub fn new(genesis_hash: BlockHash, chain_access: Option, logger: L) -> Self { - NetGraphMsgHandler { - secp_ctx: Secp256k1::verification_only(), - network_graph: NetworkGraph::new(genesis_hash), - full_syncs_requested: AtomicUsize::new(0), - chain_access, - pending_events: Mutex::new(vec![]), - logger, - } - } - - /// Creates a new tracker of the actual state of the network of channels and nodes, - /// assuming an existing Network Graph. - pub fn from_net_graph(chain_access: Option, logger: L, network_graph: NetworkGraph) -> Self { + pub fn new(network_graph: NetworkGraph, chain_access: Option, logger: L) -> Self { NetGraphMsgHandler { secp_ctx: Secp256k1::verification_only(), network_graph, @@ -173,6 +178,29 @@ impl NetGraphMsgHandler where C::Target: chain::Access false } } + + /// Applies changes to the [`NetworkGraph`] from the given update. + fn handle_network_update(&self, update: &NetworkUpdate) { + match *update { + NetworkUpdate::ChannelUpdateMessage { ref msg } => { + let short_channel_id = msg.contents.short_channel_id; + let is_enabled = msg.contents.flags & (1 << 1) != (1 << 1); + let status = if is_enabled { "enabled" } else { "disabled" }; + log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}.", short_channel_id, status); + let _ = self.network_graph.update_channel(msg, &self.secp_ctx); + }, + NetworkUpdate::ChannelClosed { short_channel_id, is_permanent } => { + let action = if is_permanent { "Removing" } else { "Disabling" }; + log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", action, short_channel_id); + self.network_graph.close_channel_from_update(short_channel_id, is_permanent); + }, + NetworkUpdate::NodeFailure { ref node_id, is_permanent } => { + let action = if is_permanent { "Removing" } else { "Disabling" }; + log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", action, node_id); + self.network_graph.fail_node(node_id, is_permanent); + }, + } + } } macro_rules! secp_verify_sig { @@ -184,7 +212,9 @@ macro_rules! secp_verify_sig { }; } -impl RoutingMessageHandler for NetGraphMsgHandler where C::Target: chain::Access, L::Target: Logger { +impl RoutingMessageHandler for NetGraphMsgHandler +where C::Target: chain::Access, L::Target: Logger +{ fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result { self.network_graph.update_node_from_announcement(msg, &self.secp_ctx)?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY && @@ -1116,15 +1146,16 @@ impl ReadOnlyNetworkGraph<'_> { #[cfg(test)] mod tests { use chain; + use ln::PaymentHash; use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; - use routing::network_graph::{NetGraphMsgHandler, NetworkGraph, MAX_EXCESS_BYTES_FOR_RELAY}; + use routing::network_graph::{NetGraphMsgHandler, NetworkGraph, NetworkUpdate, MAX_EXCESS_BYTES_FOR_RELAY}; use ln::msgs::{Init, OptionalField, RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement, UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, ReplyChannelRange, ReplyShortChannelIdsEnd, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT}; use util::test_utils; use util::logger::Logger; use util::ser::{Readable, Writeable}; - use util::events::{MessageSendEvent, MessageSendEventsProvider}; + use util::events::{Event, EventHandler, MessageSendEvent, MessageSendEventsProvider}; use util::scid_utils::scid_from_parts; use bitcoin::hashes::sha256d::Hash as Sha256dHash; @@ -1148,7 +1179,8 @@ mod tests { let secp_ctx = Secp256k1::new(); let logger = Arc::new(test_utils::TestLogger::new()); let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); - let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_hash, None, Arc::clone(&logger)); + let network_graph = NetworkGraph::new(genesis_hash); + let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger)); (secp_ctx, net_graph_msg_handler) } @@ -1309,7 +1341,8 @@ mod tests { }; // Test if the UTXO lookups were not supported - let mut net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), None, Arc::clone(&logger)); + let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let mut net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger)); match net_graph_msg_handler.handle_channel_announcement(&valid_announcement) { Ok(res) => assert!(res), _ => panic!() @@ -1333,7 +1366,8 @@ mod tests { // Test if an associated transaction were not on-chain (or not confirmed). let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); *chain_source.utxo_ret.lock().unwrap() = Err(chain::AccessError::UnknownTx); - net_graph_msg_handler = NetGraphMsgHandler::new(chain_source.clone().genesis_hash, Some(chain_source.clone()), Arc::clone(&logger)); + let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), Arc::clone(&logger)); unsigned_announcement.short_channel_id += 1; msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]); @@ -1457,7 +1491,8 @@ mod tests { let secp_ctx = Secp256k1::new(); let logger: Arc = Arc::new(test_utils::TestLogger::new()); let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); - let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), Some(chain_source.clone()), Arc::clone(&logger)); + let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), Arc::clone(&logger)); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); @@ -1621,8 +1656,14 @@ mod tests { } #[test] - fn handling_htlc_fail_channel_update() { - let (secp_ctx, net_graph_msg_handler) = create_net_graph_msg_handler(); + fn handling_network_update() { + let logger = test_utils::TestLogger::new(); + let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); + let genesis_hash = genesis_block(Network::Testnet).header.block_hash(); + let network_graph = NetworkGraph::new(genesis_hash); + let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), &logger); + let secp_ctx = Secp256k1::new(); + let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); @@ -1632,11 +1673,11 @@ mod tests { let short_channel_id = 0; let chain_hash = genesis_block(Network::Testnet).header.block_hash(); + let network_graph = &net_graph_msg_handler.network_graph; { // There is no nodes in the table at the beginning. - let network = &net_graph_msg_handler.network_graph; - assert_eq!(network.read_only().nodes().len(), 0); + assert_eq!(network_graph.read_only().nodes().len(), 0); } { @@ -1660,10 +1701,9 @@ mod tests { bitcoin_signature_2: secp_ctx.sign(&msghash, node_2_btckey), contents: unsigned_announcement.clone(), }; - match net_graph_msg_handler.handle_channel_announcement(&valid_channel_announcement) { - Ok(_) => (), - Err(_) => panic!() - }; + let chain_source: Option<&test_utils::TestChainSource> = None; + assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source, &secp_ctx).is_ok()); + assert!(network_graph.read_only().channels().get(&short_channel_id).is_some()); let unsigned_channel_update = UnsignedChannelUpdate { chain_hash, @@ -1683,29 +1723,42 @@ mod tests { contents: unsigned_channel_update.clone() }; - match net_graph_msg_handler.handle_channel_update(&valid_channel_update) { - Ok(res) => assert!(res), - _ => panic!() - }; + assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none()); + + net_graph_msg_handler.handle_event(&Event::PaymentFailed { + payment_hash: PaymentHash([0; 32]), + rejected_by_dest: false, + network_update: Some(NetworkUpdate::ChannelUpdateMessage { + msg: valid_channel_update, + }), + error_code: None, + error_data: None, + }); + + assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); } // Non-permanent closing just disables a channel { - let network = &net_graph_msg_handler.network_graph; - match network.read_only().channels().get(&short_channel_id) { + match network_graph.read_only().channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { - assert!(channel_info.one_to_two.is_some()); + assert!(channel_info.one_to_two.as_ref().unwrap().enabled); } }; - } - net_graph_msg_handler.network_graph.close_channel_from_update(short_channel_id, false); + net_graph_msg_handler.handle_event(&Event::PaymentFailed { + payment_hash: PaymentHash([0; 32]), + rejected_by_dest: false, + network_update: Some(NetworkUpdate::ChannelClosed { + short_channel_id, + is_permanent: false, + }), + error_code: None, + error_data: None, + }); - // Non-permanent closing just disables a channel - { - let network = &net_graph_msg_handler.network_graph; - match network.read_only().channels().get(&short_channel_id) { + match network_graph.read_only().channels().get(&short_channel_id) { None => panic!(), Some(channel_info) => { assert!(!channel_info.one_to_two.as_ref().unwrap().enabled); @@ -1713,14 +1766,22 @@ mod tests { }; } - net_graph_msg_handler.network_graph.close_channel_from_update(short_channel_id, true); - // Permanent closing deletes a channel { - let network = &net_graph_msg_handler.network_graph; - assert_eq!(network.read_only().channels().len(), 0); + net_graph_msg_handler.handle_event(&Event::PaymentFailed { + payment_hash: PaymentHash([0; 32]), + rejected_by_dest: false, + network_update: Some(NetworkUpdate::ChannelClosed { + short_channel_id, + is_permanent: true, + }), + error_code: None, + error_data: None, + }); + + assert_eq!(network_graph.read_only().channels().len(), 0); // Nodes are also deleted because there are no associated channels anymore - assert_eq!(network.read_only().nodes().len(), 0); + assert_eq!(network_graph.read_only().nodes().len(), 0); } // TODO: Test NetworkUpdate::NodeFailure, which is not implemented yet. } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 770b62d9cd2..97c2c7623ea 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1296,8 +1296,10 @@ mod tests { } // Using the same keys for LN and BTC ids - fn add_channel(net_graph_msg_handler: &NetGraphMsgHandler, Arc>, secp_ctx: &Secp256k1, node_1_privkey: &SecretKey, - node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64) { + fn add_channel( + net_graph_msg_handler: &NetGraphMsgHandler, Arc>, + secp_ctx: &Secp256k1, node_1_privkey: &SecretKey, node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64 + ) { let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_id_2 = PublicKey::from_secret_key(&secp_ctx, node_2_privkey); @@ -1326,7 +1328,10 @@ mod tests { }; } - fn update_channel(net_graph_msg_handler: &NetGraphMsgHandler, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, update: UnsignedChannelUpdate) { + fn update_channel( + net_graph_msg_handler: &NetGraphMsgHandler, Arc>, + secp_ctx: &Secp256k1, node_privkey: &SecretKey, update: UnsignedChannelUpdate + ) { let msghash = hash_to_message!(&Sha256dHash::hash(&update.encode()[..])[..]); let valid_channel_update = ChannelUpdate { signature: secp_ctx.sign(&msghash, node_privkey), @@ -1339,8 +1344,10 @@ mod tests { }; } - fn add_or_update_node(net_graph_msg_handler: &NetGraphMsgHandler, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, - features: NodeFeatures, timestamp: u32) { + fn add_or_update_node( + net_graph_msg_handler: &NetGraphMsgHandler, Arc>, + secp_ctx: &Secp256k1, node_privkey: &SecretKey, features: NodeFeatures, timestamp: u32 + ) { let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey); let unsigned_announcement = UnsignedNodeAnnouncement { features, @@ -1396,7 +1403,8 @@ mod tests { 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 net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), None, Arc::clone(&logger)); + let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger)); // Build network from our_id to node6: // // -1(1)2- node0 -1(3)2- @@ -3947,7 +3955,8 @@ mod tests { // "previous hop" being set to node 3, creating a loop in the path. let secp_ctx = Secp256k1::new(); let logger = Arc::new(test_utils::TestLogger::new()); - let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), None, Arc::clone(&logger)); + let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()); + let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger)); let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx); add_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6); diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index bde7d8c4413..d63dd88b761 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -130,10 +130,13 @@ pub enum Event { /// retry the payment via a different route. rejected_by_dest: bool, /// Any failure information conveyed via the Onion return packet by a node along the failed - /// payment route. Should be applied to the [`NetworkGraph`] so that routing decisions can - /// take into account the update. + /// payment route. + /// + /// Should be applied to the [`NetworkGraph`] so that routing decisions can take into + /// account the update. [`NetGraphMsgHandler`] is capable of doing this. /// /// [`NetworkGraph`]: crate::routing::network_graph::NetworkGraph + /// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler network_update: Option, #[cfg(test)] error_code: Option, From e2f088c3718ddc4338b6871729c857c4b7422cf8 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 19 Aug 2021 11:21:42 -0500 Subject: [PATCH 09/10] Expand and format BackgroundProcessor docs --- lightning-background-processor/src/lib.rs | 43 ++++++++++++++++------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 45b33fd1fc5..7604ba1e5f6 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -26,20 +26,28 @@ use std::thread::JoinHandle; use std::time::{Duration, Instant}; use std::ops::Deref; -/// BackgroundProcessor takes care of tasks that (1) need to happen periodically to keep +/// `BackgroundProcessor` takes care of tasks that (1) need to happen periodically to keep /// Rust-Lightning running properly, and (2) either can or should be run in the background. Its /// responsibilities are: -/// * Monitoring whether the ChannelManager needs to be re-persisted to disk, and if so, +/// * Processing [`Event`]s with a user-provided [`EventHandler`]. +/// * Monitoring whether the [`ChannelManager`] needs to be re-persisted to disk, and if so, /// writing it to disk/backups by invoking the callback given to it at startup. -/// ChannelManager persistence should be done in the background. -/// * Calling `ChannelManager::timer_tick_occurred()` and -/// `PeerManager::timer_tick_occurred()` every minute (can be done in the -/// background). +/// [`ChannelManager`] persistence should be done in the background. +/// * Calling [`ChannelManager::timer_tick_occurred`] and [`PeerManager::timer_tick_occurred`] +/// at the appropriate intervals. /// -/// Note that if ChannelManager persistence fails and the persisted manager becomes out-of-date, -/// then there is a risk of channels force-closing on startup when the manager realizes it's -/// outdated. However, as long as `ChannelMonitor` backups are sound, no funds besides those used -/// for unilateral chain closure fees are at risk. +/// It will also call [`PeerManager::process_events`] periodically though this shouldn't be relied +/// upon as doing so may result in high latency. +/// +/// # Note +/// +/// If [`ChannelManager`] persistence fails and the persisted manager becomes out-of-date, then +/// there is a risk of channels force-closing on startup when the manager realizes it's outdated. +/// However, as long as [`ChannelMonitor`] backups are sound, no funds besides those used for +/// unilateral chain closure fees are at risk. +/// +/// [`ChannelMonitor`]: lightning::chain::channelmonitor::ChannelMonitor +/// [`Event`]: lightning::util::events::Event #[must_use = "BackgroundProcessor will immediately stop on drop. It should be stored until shutdown."] pub struct BackgroundProcessor { stop_thread: Arc, @@ -99,21 +107,30 @@ impl BackgroundProcessor { /// `persist_manager` returns an error. In case of an error, the error is retrieved by calling /// either [`join`] or [`stop`]. /// - /// Typically, users should either implement [`ChannelManagerPersister`] to never return an - /// error or call [`join`] and handle any error that may arise. For the latter case, the - /// `BackgroundProcessor` must be restarted by calling `start` again after handling the error. + /// # Data Persistence /// /// `persist_manager` is responsible for writing out the [`ChannelManager`] to disk, and/or /// uploading to one or more backup services. See [`ChannelManager::write`] for writing out a /// [`ChannelManager`]. See [`FilesystemPersister::persist_manager`] for Rust-Lightning's /// provided implementation. /// + /// Typically, users should either implement [`ChannelManagerPersister`] to never return an + /// error or call [`join`] and handle any error that may arise. For the latter case, + /// `BackgroundProcessor` must be restarted by calling `start` again after handling the error. + /// + /// # Event Handling + /// + /// `event_handler` is responsible for handling events that users should be notified of (e.g., + /// payment failed). A user's [`EventHandler`] may be decorated with other handlers to implement + /// common functionality. See individual [`Event`]s for further details. + /// /// [top-level documentation]: Self /// [`join`]: Self::join /// [`stop`]: Self::stop /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager /// [`ChannelManager::write`]: lightning::ln::channelmanager::ChannelManager#impl-Writeable /// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister::persist_manager + /// [`Event`]: lightning::util::events::Event pub fn start< Signer: 'static + Sign, CF: 'static + Deref + Send + Sync, From 992df51001af62a8fb9d39d3c2fb70f26918d740 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 14 Sep 2021 21:38:00 -0500 Subject: [PATCH 10/10] Update NetworkGraph in BackgroundProcessor Decorate the user-supplied EventHandler with NetGraphMsgHandler in the BackgroundProcessor. The resulting handler will intercept PaymentFailed events in order to update the NetworkGraph in the background before delegating to the user's event handler. --- lightning-background-processor/src/lib.rs | 67 ++++++++++++++++++----- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 7604ba1e5f6..4e6fb6f02df 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -17,7 +17,8 @@ use lightning::ln::channelmanager::ChannelManager; use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler}; use lightning::ln::peer_handler::{PeerManager, SocketDescriptor}; use lightning::ln::peer_handler::CustomMessageHandler; -use lightning::util::events::{EventHandler, EventsProvider}; +use lightning::routing::network_graph::NetGraphMsgHandler; +use lightning::util::events::{Event, EventHandler, EventsProvider}; use lightning::util::logger::Logger; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; @@ -99,6 +100,33 @@ ChannelManagerPersister for Fun where } } +/// Decorates an [`EventHandler`] with common functionality provided by standard [`EventHandler`]s. +struct DecoratingEventHandler< + E: EventHandler, + N: Deref>, + A: Deref, + L: Deref, +> +where A::Target: chain::Access, L::Target: Logger { + event_handler: E, + net_graph_msg_handler: Option, +} + +impl< + E: EventHandler, + N: Deref>, + A: Deref, + L: Deref, +> EventHandler for DecoratingEventHandler +where A::Target: chain::Access, L::Target: Logger { + fn handle_event(&self, event: &Event) { + if let Some(event_handler) = &self.net_graph_msg_handler { + event_handler.handle_event(event); + } + self.event_handler.handle_event(event); + } +} + impl BackgroundProcessor { /// Start a background thread that takes care of responsibilities enumerated in the [top-level /// documentation]. @@ -121,8 +149,9 @@ impl BackgroundProcessor { /// # Event Handling /// /// `event_handler` is responsible for handling events that users should be notified of (e.g., - /// payment failed). A user's [`EventHandler`] may be decorated with other handlers to implement - /// common functionality. See individual [`Event`]s for further details. + /// payment failed). [`BackgroundProcessor`] may decorate the given [`EventHandler`] with common + /// functionality implemented by other handlers. + /// * [`NetGraphMsgHandler`] if given will update the [`NetworkGraph`] based on payment failures. /// /// [top-level documentation]: Self /// [`join`]: Self::join @@ -130,9 +159,10 @@ impl BackgroundProcessor { /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager /// [`ChannelManager::write`]: lightning::ln::channelmanager::ChannelManager#impl-Writeable /// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister::persist_manager - /// [`Event`]: lightning::util::events::Event + /// [`NetworkGraph`]: lightning::routing::network_graph::NetworkGraph pub fn start< Signer: 'static + Sign, + CA: 'static + Deref + Send + Sync, CF: 'static + Deref + Send + Sync, CW: 'static + Deref + Send + Sync, T: 'static + Deref + Send + Sync, @@ -147,11 +177,15 @@ impl BackgroundProcessor { CMP: 'static + Send + ChannelManagerPersister, M: 'static + Deref> + Send + Sync, CM: 'static + Deref> + Send + Sync, + NG: 'static + Deref> + Send + Sync, UMH: 'static + Deref + Send + Sync, PM: 'static + Deref> + Send + Sync, - > - (persister: CMP, event_handler: EH, chain_monitor: M, channel_manager: CM, peer_manager: PM, logger: L) -> Self + >( + persister: CMP, event_handler: EH, chain_monitor: M, channel_manager: CM, + net_graph_msg_handler: Option, peer_manager: PM, logger: L + ) -> Self where + CA::Target: 'static + chain::Access, CF::Target: 'static + chain::Filter, CW::Target: 'static + chain::Watch, T::Target: 'static + BroadcasterInterface, @@ -166,6 +200,8 @@ impl BackgroundProcessor { let stop_thread = Arc::new(AtomicBool::new(false)); let stop_thread_clone = stop_thread.clone(); let handle = thread::spawn(move || -> Result<(), std::io::Error> { + let event_handler = DecoratingEventHandler { event_handler, net_graph_msg_handler }; + log_trace!(logger, "Calling ChannelManager's timer_tick_occurred on startup"); channel_manager.timer_tick_occurred(); @@ -274,6 +310,7 @@ mod tests { use lightning::ln::features::InitFeatures; use lightning::ln::msgs::{ChannelMessageHandler, Init}; use lightning::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler}; + use lightning::routing::network_graph::{NetworkGraph, NetGraphMsgHandler}; use lightning::util::config::UserConfig; use lightning::util::events::{Event, MessageSendEventsProvider, MessageSendEvent}; use lightning::util::ser::Writeable; @@ -301,6 +338,7 @@ mod tests { struct Node { node: Arc>, + net_graph_msg_handler: Option, Arc>>>, peer_manager: Arc, Arc, Arc, IgnoringMessageHandler>>, chain_monitor: Arc, persister: Arc, @@ -335,15 +373,18 @@ mod tests { let persister = Arc::new(FilesystemPersister::new(format!("{}_persister_{}", persist_dir, i))); let seed = [i as u8; 32]; let network = Network::Testnet; - let now = Duration::from_secs(genesis_block(network).header.time as u64); + let genesis_block = genesis_block(network); + let now = Duration::from_secs(genesis_block.header.time as u64); let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos())); let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), persister.clone())); let best_block = BestBlock::from_genesis(network); let params = ChainParameters { network, best_block }; let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster.clone(), logger.clone(), keys_manager.clone(), UserConfig::default(), params)); + let network_graph = NetworkGraph::new(genesis_block.header.block_hash()); + let net_graph_msg_handler = Some(Arc::new(NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), logger.clone()))); let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )}; let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(), &seed, logger.clone(), IgnoringMessageHandler{})); - let node = Node { node: manager, peer_manager, chain_monitor, persister, tx_broadcaster, logger, best_block }; + let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, logger, best_block }; nodes.push(node); } @@ -441,7 +482,7 @@ mod tests { let data_dir = nodes[0].persister.get_data_dir(); let persister = move |node: &ChannelManager, Arc, Arc, Arc, Arc>| FilesystemPersister::persist_manager(data_dir.clone(), node); let event_handler = |_: &_| {}; - let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); + let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); macro_rules! check_persisted_data { ($node: expr, $filepath: expr, $expected_bytes: expr) => { @@ -494,7 +535,7 @@ mod tests { let data_dir = nodes[0].persister.get_data_dir(); let persister = move |node: &ChannelManager, Arc, Arc, Arc, Arc>| FilesystemPersister::persist_manager(data_dir.clone(), node); let event_handler = |_: &_| {}; - let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); + let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); loop { let log_entries = nodes[0].logger.lines.lock().unwrap(); let desired_log = "Calling ChannelManager's timer_tick_occurred".to_string(); @@ -516,7 +557,7 @@ mod tests { let persister = |_: &_| Err(std::io::Error::new(std::io::ErrorKind::Other, "test")); let event_handler = |_: &_| {}; - let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); + let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); match bg_processor.join() { Ok(_) => panic!("Expected error persisting manager"), Err(e) => { @@ -538,7 +579,7 @@ mod tests { let event_handler = move |event: &Event| { sender.send(handle_funding_generation_ready!(event, channel_value)).unwrap(); }; - let bg_processor = BackgroundProcessor::start(persister.clone(), event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); + let bg_processor = BackgroundProcessor::start(persister.clone(), event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); // Open a channel and check that the FundingGenerationReady event was handled. begin_open_channel!(nodes[0], nodes[1], channel_value); @@ -562,7 +603,7 @@ mod tests { // Set up a background event handler for SpendableOutputs events. let (sender, receiver) = std::sync::mpsc::sync_channel(1); let event_handler = move |event: &Event| sender.send(event.clone()).unwrap(); - let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); + let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone()); // Force close the channel and check that the SpendableOutputs event was handled. nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();