X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fonion_message%2Fmessenger.rs;h=9f6c5cb435276ffbc4a76793f1f9fea624986de4;hb=f5ee8c23a1a52bc51c00eb8a62b0b5226acee80b;hp=2dc5a89a37b5fae41071d8c4589d813b39916a3e;hpb=36e434d8cefe6b533a2ab378d2d65923433df373;p=rust-lightning diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 2dc5a89a..9f6c5cb4 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -28,7 +28,7 @@ use super::packet::OnionMessageContents; use super::packet::ParsedOnionMessageContents; use super::offers::OffersMessageHandler; use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN}; -use crate::util::logger::Logger; +use crate::util::logger::{Logger, WithContext}; use crate::util::ser::Writeable; use core::fmt; @@ -358,16 +358,28 @@ where const MIN_PEER_CHANNELS: usize = 3; let network_graph = self.network_graph.deref().read_only(); - let paths = peers.iter() + let is_recipient_announced = + network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)); + + let mut peer_info = peers.iter() // Limit to peers with announced channels - .filter(|pubkey| + .filter_map(|pubkey| network_graph .node(&NodeId::from_pubkey(pubkey)) - .map(|info| &info.channels[..]) - .map(|channels| channels.len() >= MIN_PEER_CHANNELS) - .unwrap_or(false) + .filter(|info| info.channels.len() >= MIN_PEER_CHANNELS) + .map(|info| (*pubkey, info.is_tor_only(), info.channels.len())) ) - .map(|pubkey| vec![*pubkey, recipient]) + // Exclude Tor-only nodes when the recipient is announced. + .filter(|(_, is_tor_only, _)| !(*is_tor_only && is_recipient_announced)) + .collect::>(); + + // Prefer using non-Tor nodes with the most channels as the introduction node. + peer_info.sort_unstable_by(|(_, a_tor_only, a_channels), (_, b_tor_only, b_channels)| { + a_tor_only.cmp(b_tor_only).then(a_channels.cmp(b_channels).reverse()) + }); + + let paths = peer_info.into_iter() + .map(|(pubkey, _, _)| vec![pubkey, recipient]) .map(|node_pks| BlindedPath::new_for_message(&node_pks, &*self.entropy_source, secp_ctx)) .take(MAX_PATHS) .collect::, _>>(); @@ -375,7 +387,7 @@ where match paths { Ok(paths) if !paths.is_empty() => Ok(paths), _ => { - if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) { + if is_recipient_announced { BlindedPath::one_hop_for_message(recipient, &*self.entropy_source, secp_ctx) .map(|path| vec![path]) } else { @@ -736,25 +748,31 @@ where &self, contents: T, destination: Destination, reply_path: Option, log_suffix: fmt::Arguments ) -> Result { + let mut logger = WithContext::from(&self.logger, None, None); let result = self.find_path(destination) - .and_then(|path| self.enqueue_onion_message(path, contents, reply_path, log_suffix)); + .and_then(|path| { + let first_hop = path.intermediate_nodes.get(0).map(|p| *p); + logger = WithContext::from(&self.logger, first_hop, None); + self.enqueue_onion_message(path, contents, reply_path, log_suffix) + }); match result.as_ref() { Err(SendError::GetNodeIdFailed) => { - log_warn!(self.logger, "Unable to retrieve node id {}", log_suffix); + log_warn!(logger, "Unable to retrieve node id {}", log_suffix); }, Err(SendError::PathNotFound) => { - log_trace!(self.logger, "Failed to find path {}", log_suffix); + log_trace!(logger, "Failed to find path {}", log_suffix); }, Err(e) => { - log_trace!(self.logger, "Failed sending onion message {}: {:?}", log_suffix, e); + log_trace!(logger, "Failed sending onion message {}: {:?}", log_suffix, e); }, Ok(SendSuccess::Buffered) => { - log_trace!(self.logger, "Buffered onion message {}", log_suffix); + log_trace!(logger, "Buffered onion message {}", log_suffix); }, Ok(SendSuccess::BufferedAwaitingConnection(node_id)) => { log_trace!( - self.logger, "Buffered onion message waiting on peer connection {}: {:?}", + logger, + "Buffered onion message waiting on peer connection {}: {}", log_suffix, node_id ); }, @@ -913,12 +931,13 @@ where OMH::Target: OffersMessageHandler, CMH::Target: CustomOnionMessageHandler, { - fn handle_onion_message(&self, _peer_node_id: &PublicKey, msg: &OnionMessage) { + fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage) { + let logger = WithContext::from(&self.logger, Some(*peer_node_id), None); match self.peel_onion_message(msg) { Ok(PeeledOnion::Receive(message, path_id, reply_path)) => { log_trace!( - self.logger, - "Received an onion message with path_id {:02x?} and {} reply_path: {:?}", + logger, + "Received an onion message with path_id {:02x?} and {} reply_path: {:?}", path_id, if reply_path.is_some() { "a" } else { "no" }, message); match message { @@ -945,7 +964,10 @@ where Ok(PeeledOnion::Forward(next_node_id, onion_message)) => { let mut message_recipients = self.message_recipients.lock().unwrap(); if outbound_buffer_full(&next_node_id, &message_recipients) { - log_trace!(self.logger, "Dropping forwarded onion message to peer {:?}: outbound buffer full", next_node_id); + log_trace!( + logger, + "Dropping forwarded onion message to peer {}: outbound buffer full", + next_node_id); return } @@ -959,16 +981,19 @@ where e.get(), OnionMessageRecipient::ConnectedPeer(..) ) => { e.get_mut().enqueue_message(onion_message); - log_trace!(self.logger, "Forwarding an onion message to peer {}", next_node_id); + log_trace!(logger, "Forwarding an onion message to peer {}", next_node_id); }, _ => { - log_trace!(self.logger, "Dropping forwarded onion message to disconnected peer {:?}", next_node_id); + log_trace!( + logger, + "Dropping forwarded onion message to disconnected peer {}", + next_node_id); return }, } }, Err(e) => { - log_error!(self.logger, "Failed to process onion message {:?}", e); + log_error!(logger, "Failed to process onion message {:?}", e); } } }