diff --git a/lightning/src/ln/onion_message.rs b/lightning/src/ln/onion_message.rs index a98e86e87c5..41575536bea 100644 --- a/lightning/src/ln/onion_message.rs +++ b/lightning/src/ln/onion_message.rs @@ -9,6 +9,9 @@ //! Onion Messages: sending, receiving, forwarding, and ancillary utilities live here +pub(crate) const SMALL_PACKET_HOP_DATA_LEN: usize = 1300; +pub(crate) const BIG_PACKET_HOP_DATA_LEN: usize = 32768; + #[derive(Clone, Debug, PartialEq)] pub(crate) struct Packet { pub(crate) version: u8, @@ -20,6 +23,13 @@ pub(crate) struct Packet { pub(crate) hmac: [u8; 32], } +impl Packet { + fn len(&self) -> u16 { + // 32 (hmac) + 33 (public_key) + 1 (version) = 66 + self.hop_data.len() as u16 + 66 + } +} + impl Writeable for Packet { fn write(&self, w: &mut W) -> Result<(), io::Error> {} } @@ -28,6 +38,46 @@ impl ReadableArgs for Packet { fn read(r: &mut R, len: u16) -> Result {} } +/// The payload of an onion message. +pub(crate) struct Payload { + /// Onion message payloads contain an encrypted TLV stream, containing both "control" TLVs and + /// sometimes user-provided custom "data" TLVs. See [`EncryptedTlvs`] for more information. + encrypted_tlvs: EncryptedTlvs, + // Coming soon: + // * custom TLVs + // * `message: Message` field + // * `reply_path: Option` field +} + +// Coming soon: +// enum Message { +// InvoiceRequest(InvoiceRequest), +// Invoice(Invoice), +// InvoiceError(InvoiceError), +// CustomMessage, +// } + +/// We want to avoid encoding and encrypting separately in order to avoid an intermediate Vec, thus +/// we encode and encrypt at the same time using the `SharedSecret` here. +impl Writeable for (Payload, SharedSecret) { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + } +} + +/// Onion messages contain an encrypted TLV stream. This can be supplied by someone else, in the +/// case that we're sending to a blinded route, or created by us if we're constructing payloads for +/// unblinded hops in the onion message's path. +pub(crate) enum EncryptedTlvs { + /// If we're sending to a blinded route, the node that constructed the blinded route has provided + /// our onion message's `EncryptedTlvs`, already encrypted and encoded into bytes. + Blinded(Vec), + /// If we're receiving an onion message or constructing an onion message to send through any + /// unblinded nodes, we'll need to construct the onion message's `EncryptedTlvs` in their + /// unblinded state to avoid encoding them into an intermediate `Vec`. + // Below will later have an additional Vec + Unblinded(ControlTlvs), +} + /// Onion messages have "control" TLVs and "data" TLVs. Control TLVs are used to control the /// direction and routing of an onion message from hop to hop, whereas data TLVs contain the onion /// message content itself. @@ -105,6 +155,18 @@ impl BlindedRoute { fn encrypt_payload(payload: ControlTlvs, encrypted_tlvs_ss: SharedSecret) -> Vec {} } +/// The destination of an onion message. +pub enum Destination { + /// We're sending this onion message to a node. + Node(PublicKey), + /// We're sending this onion message to a blinded route. + BlindedRoute(BlindedRoute), +} + +impl Destination { + fn num_hops(&self) -> usize { +} + /// 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. pub struct OnionMessenger @@ -136,6 +198,10 @@ impl OnionMessenger logger, } } + + /// Send an empty onion message to `destination`, routing it through `intermediate_nodes`. + pub fn send_onion_message(&self, intermediate_nodes: Vec, destination: Destination) -> Result<(), secp256k1::Error> { + } } impl OnionMessageHandler for OnionMessenger @@ -153,9 +219,13 @@ impl MessageSendEventsProvider for OnionMessen } } +/// Build an onion message's payloads for encoding in the onion packet. +fn build_payloads(intermediate_nodes: Vec, destination: Destination, mut encrypted_tlvs_keys: Vec) -> Vec<(Payload, SharedSecret)> { +} + #[allow(unused_assignments)] #[inline] -fn construct_keys_callback (secp_ctx: &Secp256k1, unblinded_path: &Vec, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {} +fn construct_keys_callback (secp_ctx: &Secp256k1, unblinded_path: &Vec, destination: Option<&Destination>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {} /// Construct keys for constructing a blinded route along the given `unblinded_path`. /// @@ -168,6 +238,17 @@ fn construct_blinded_route_keys // calls construct_keys_callback } +/// Construct keys for sending an onion message along the given `path`. +/// +/// Returns: `(encrypted_tlvs_keys, onion_packet_keys)` +/// where the encrypted tlvs keys are used to encrypt the [`EncryptedTlvs`] of the onion message and the +/// onion packet keys are used to encrypt the onion packet. +fn construct_sending_keys( + secp_ctx: &Secp256k1, unblinded_path: &Vec, destination: &Destination, session_priv: &SecretKey +) -> Result<(Vec, Vec), secp256k1::Error> { + // calls construct_keys_callback +} + /// Useful for simplifying the parameters of [`SimpleArcChannelManager`] and /// [`SimpleArcPeerManager`]. See their docs for more details. pub type SimpleArcOnionMessenger = OnionMessenger, Arc>; diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 357e0d012c3..acc28a8863b 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -229,6 +229,9 @@ pub(super) fn construct_onion_packet(payloads: Vec, onion_ke payloads, onion_keys, PacketData::Payment(packet_data), Some(associated_data)).try_into().unwrap() } +pub(super) fn construct_onion_message_packet(payloads: Vec<(onion_message::Payload, SharedSecret)>, onion_keys: Vec, prng_seed: [u8; 32]) -> onion_message::Packet { +} + #[cfg(test)] // Used in testing to write bogus OnionHopDatas, which is otherwise not representable in // msgs::OnionHopData.