Merge pull request #2881 from TheBlueMatt/2024-02-offers-tweak
[rust-lightning] / lightning / src / onion_message / messenger.rs
index c221e7820256ba3c290994440a561f65899f6bdd..9f6c5cb435276ffbc4a76793f1f9fea624986de4 100644 (file)
@@ -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,19 +358,28 @@ where
                const MIN_PEER_CHANNELS: usize = 3;
 
                let network_graph = self.network_graph.deref().read_only();
+               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_map(|pubkey|
                                network_graph
                                        .node(&NodeId::from_pubkey(pubkey))
                                        .filter(|info| info.channels.len() >= MIN_PEER_CHANNELS)
-                                       .map(|info| (*pubkey, info.is_tor_only()))
+                                       .map(|info| (*pubkey, info.is_tor_only(), info.channels.len()))
                        )
+                       // Exclude Tor-only nodes when the recipient is announced.
+                       .filter(|(_, is_tor_only, _)| !(*is_tor_only && is_recipient_announced))
                        .collect::<Vec<_>>();
-               peer_info.sort_unstable_by(|(_, a_tor_only), (_, b_tor_only)| a_tor_only.cmp(b_tor_only));
+
+               // 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(|(pubkey, _, _)| vec![pubkey, recipient])
                        .map(|node_pks| BlindedPath::new_for_message(&node_pks, &*self.entropy_source, secp_ctx))
                        .take(MAX_PATHS)
                        .collect::<Result<Vec<_>, _>>();
@@ -378,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 {
@@ -739,25 +748,31 @@ where
                &self, contents: T, destination: Destination, reply_path: Option<BlindedPath>,
                log_suffix: fmt::Arguments
        ) -> Result<SendSuccess, SendError> {
+               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
                                );
                        },
@@ -916,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 {
@@ -948,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
                                }
 
@@ -962,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);
                        }
                }
        }