Fix CI to error on doc links to private items
[rust-lightning] / lightning / src / onion_message / messenger.rs
index 3b18b1186febe9cffe38c13c1ff4ab4032c01c34..7eba3cdd254af6418132fc29bfac3cde59bd2292 100644 (file)
@@ -28,9 +28,56 @@ use sync::{Arc, Mutex};
 use prelude::*;
 
 /// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
-/// used to retrieve invoices and fulfill invoice requests from [offers].
+/// used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending
+/// and receiving empty onion messages is supported.
+///
+/// # Example
+///
+//  Needs to be `ignore` until the `onion_message` module is made public, otherwise this is a test
+//  failure.
+/// ```ignore
+/// # extern crate bitcoin;
+/// # use bitcoin::hashes::_export::_core::time::Duration;
+/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
+/// # use lightning::chain::keysinterface::{InMemorySigner, KeysManager, KeysInterface};
+/// # use lightning::onion_message::{BlindedRoute, Destination, OnionMessenger};
+/// # use lightning::util::logger::{Logger, Record};
+/// # use std::sync::Arc;
+/// # struct FakeLogger {};
+/// # impl Logger for FakeLogger {
+/// #     fn log(&self, record: &Record) { unimplemented!() }
+/// # }
+/// # let seed = [42u8; 32];
+/// # let time = Duration::from_secs(123456);
+/// # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos());
+/// # let logger = Arc::new(FakeLogger {});
+/// # let node_secret = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
+/// # let secp_ctx = Secp256k1::new();
+/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
+/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1,
+/// hop_node_id1);
+/// # let destination_node_id = hop_node_id1;
+/// #
+/// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
+/// // ChannelManager.
+/// let onion_messenger = OnionMessenger::new(&keys_manager, logger);
+///
+/// // Send an empty onion message to a node id.
+/// let intermediate_hops = [hop_node_id1, hop_node_id2];
+/// onion_messenger.send_onion_message(&intermediate_hops, Destination::Node(destination_node_id));
+///
+/// // Create a blinded route to yourself, for someone to send an onion message to.
+/// # let your_node_id = hop_node_id1;
+/// let hops = [hop_node_id3, hop_node_id4, your_node_id];
+/// let blinded_route = BlindedRoute::new::<InMemorySigner, _, _>(&hops, &keys_manager, &secp_ctx).unwrap();
+///
+/// // Send an empty onion message to a blinded route.
+/// # let intermediate_hops = [hop_node_id1, hop_node_id2];
+/// onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route));
+/// ```
 ///
 /// [offers]: <https://github.com/lightning/bolts/pull/798>
+/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
 pub struct OnionMessenger<Signer: Sign, K: Deref, L: Deref>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
@@ -61,6 +108,21 @@ impl Destination {
        }
 }
 
+/// Errors that may occur when [sending an onion message].
+///
+/// [sending an onion message]: OnionMessenger::send_onion_message
+#[derive(Debug, PartialEq)]
+pub enum SendError {
+       /// Errored computing onion message packet keys.
+       Secp256k1(secp256k1::Error),
+       /// Because implementations such as Eclair will drop onion messages where the message packet
+       /// exceeds 32834 bytes, we refuse to send messages where the packet exceeds this size.
+       TooBigPacket,
+       /// The provided [`Destination`] was an invalid [`BlindedRoute`], due to having fewer than two
+       /// blinded hops.
+       TooFewBlindedHops,
+}
+
 impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
@@ -79,7 +141,13 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
        }
 
        /// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
-       pub fn send_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination) -> Result<(), secp256k1::Error> {
+       /// See [`OnionMessenger`] for example usage.
+       pub fn send_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination) -> Result<(), SendError> {
+               if let Destination::BlindedRoute(BlindedRoute { ref blinded_hops, .. }) = destination {
+                       if blinded_hops.len() < 2 {
+                               return Err(SendError::TooFewBlindedHops);
+                       }
+               }
                let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes();
                let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
                let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
@@ -92,10 +160,12 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
                        }
                };
                let (packet_payloads, packet_keys) = packet_payloads_and_keys(
-                       &self.secp_ctx, intermediate_nodes, destination, &blinding_secret)?;
+                       &self.secp_ctx, intermediate_nodes, destination, &blinding_secret)
+                       .map_err(|e| SendError::Secp256k1(e))?;
 
                let prng_seed = self.keys_manager.get_secure_random_bytes();
-               let onion_packet = construct_onion_message_packet(packet_payloads, packet_keys, prng_seed);
+               let onion_packet = construct_onion_message_packet(
+                       packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
 
                let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
                let pending_msgs = pending_per_peer_msgs.entry(introduction_node_id).or_insert(Vec::new());
@@ -198,6 +268,14 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
                        },
                };
        }
+
+       #[cfg(test)]
+       pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, Vec<msgs::OnionMessage>> {
+               let mut pending_msgs = self.pending_messages.lock().unwrap();
+               let mut msgs = HashMap::new();
+               core::mem::swap(&mut *pending_msgs, &mut msgs);
+               msgs
+       }
 }
 
 // TODO: parameterize the below Simple* types with OnionMessenger and handle the messages it
@@ -287,7 +365,8 @@ fn packet_payloads_and_keys<T: secp256k1::Signing + secp256k1::Verification>(
        Ok((payloads, onion_packet_keys))
 }
 
-fn construct_onion_message_packet(payloads: Vec<(Payload, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Packet {
+/// Errors if the serialized payload size exceeds onion_message::BIG_PACKET_HOP_DATA_LEN
+fn construct_onion_message_packet(payloads: Vec<(Payload, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
        // Spec rationale:
        // "`len` allows larger messages to be sent than the standard 1300 bytes allowed for an HTLC
        // onion, but this should be used sparingly as it is reduces anonymity set, hence the
@@ -297,7 +376,8 @@ fn construct_onion_message_packet(payloads: Vec<(Payload, [u8; 32])>, onion_keys
                SMALL_PACKET_HOP_DATA_LEN
        } else if payloads_ser_len <= BIG_PACKET_HOP_DATA_LEN {
                BIG_PACKET_HOP_DATA_LEN
-       } else { payloads_ser_len };
+       } else { return Err(()) };
 
-       onion_utils::construct_onion_message_packet::<_, _>(payloads, onion_keys, prng_seed, hop_data_len)
+       Ok(onion_utils::construct_onion_message_packet::<_, _>(
+               payloads, onion_keys, prng_seed, hop_data_len))
 }