BlindedPath with unannounced introduction node
[rust-lightning] / lightning / src / onion_message / messenger.rs
index 5ceb0683c57203396da6612a6e2e7835c4c2f8bc..d333eb2103c5ca516217518ab144dab2f84b9807 100644 (file)
@@ -325,12 +325,18 @@ impl OnionMessageRecipient {
 
 /// The `Responder` struct creates an appropriate [`ResponseInstruction`]
 /// for responding to a message.
+#[derive(Clone, Debug, Eq, PartialEq)]
 pub struct Responder {
        /// The path along which a response can be sent.
        reply_path: BlindedPath,
        path_id: Option<[u8; 32]>
 }
 
+impl_writeable_tlv_based!(Responder, {
+       (0, reply_path, required),
+       (2, path_id, option),
+});
+
 impl Responder {
        /// Creates a new [`Responder`] instance with the provided reply path.
        pub(super) fn new(reply_path: BlindedPath, path_id: Option<[u8; 32]>) -> Self {
@@ -456,6 +462,13 @@ pub trait MessageRouter {
 }
 
 /// A [`MessageRouter`] that can only route to a directly connected [`Destination`].
+///
+/// # Privacy
+///
+/// Creating [`BlindedPath`]s may affect privacy since, if a suitable path cannot be found, it will
+/// create a one-hop path using the recipient as the introduction node if it is a announced node.
+/// Otherwise, there is no way to find a path to the introduction node in order to send a message,
+/// and thus an `Err` is returned.
 pub struct DefaultMessageRouter<G: Deref<Target=NetworkGraph<L>>, L: Deref, ES: Deref>
 where
        L::Target: Logger,
@@ -476,7 +489,7 @@ where
        }
 
        fn create_blinded_paths_from_iter<
-               I: Iterator<Item = ForwardNode>,
+               I: ExactSizeIterator<Item = ForwardNode>,
                T: secp256k1::Signing + secp256k1::Verification
        >(
                &self, recipient: PublicKey, peers: I, secp_ctx: &Secp256k1<T>, compact_paths: bool
@@ -492,13 +505,18 @@ where
                let is_recipient_announced =
                        network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient));
 
+               let has_one_peer = peers.len() == 1;
                let mut peer_info = peers
-                       // Limit to peers with announced channels
+                       // Limit to peers with announced channels unless the recipient is unannounced.
                        .filter_map(|peer|
                                network_graph
                                        .node(&NodeId::from_pubkey(&peer.node_id))
                                        .filter(|info| info.channels.len() >= MIN_PEER_CHANNELS)
                                        .map(|info| (peer, info.is_tor_only(), info.channels.len()))
+                                       // Allow messages directly with the only peer when unannounced.
+                                       .or_else(|| (!is_recipient_announced && has_one_peer)
+                                               .then(|| (peer, false, 0))
+                                       )
                        )
                        // Exclude Tor-only nodes when the recipient is announced.
                        .filter(|(_, is_tor_only, _)| !(*is_tor_only && is_recipient_announced))