Skip to content

Commit e3ececc

Browse files
Support sending onion messages
This adds several utilities in service of then adding OnionMessenger::send_onion_message, which can send to either an unblinded pubkey or a blinded route. Sending custom TLVs and sending an onion message containing a reply path are not yet supported.
1 parent 6daa533 commit e3ececc

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

lightning/src/ln/onion_message.rs

+82-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
//! Onion Messages: sending, receiving, forwarding, and ancillary utilities live here
1111
12+
pub(crate) const SMALL_PACKET_HOP_DATA_LEN: usize = 1300;
13+
pub(crate) const BIG_PACKET_HOP_DATA_LEN: usize = 32768;
14+
1215
#[derive(Clone, Debug, PartialEq)]
1316
pub(crate) struct Packet {
1417
pub(crate) version: u8,
@@ -20,6 +23,13 @@ pub(crate) struct Packet {
2023
pub(crate) hmac: [u8; 32],
2124
}
2225

26+
impl Packet {
27+
fn len(&self) -> u16 {
28+
// 32 (hmac) + 33 (public_key) + 1 (version) = 66
29+
self.hop_data.len() as u16 + 66
30+
}
31+
}
32+
2333
impl Writeable for Packet {
2434
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {}
2535
}
@@ -28,6 +38,46 @@ impl ReadableArgs<u16> for Packet {
2838
fn read<R: Read>(r: &mut R, len: u16) -> Result<Self, DecodeError> {}
2939
}
3040

41+
/// The payload of an onion message.
42+
pub(crate) struct Payload {
43+
/// Onion message payloads contain an encrypted TLV stream, containing both "control" TLVs and
44+
/// sometimes user-provided custom "data" TLVs. See [`EncryptedTlvs`] for more information.
45+
encrypted_tlvs: EncryptedTlvs,
46+
// Coming soon:
47+
// * custom TLVs
48+
// * `message: Message` field
49+
// * `reply_path: Option<BlindedRoute>` field
50+
}
51+
52+
// Coming soon:
53+
// enum Message {
54+
// InvoiceRequest(InvoiceRequest),
55+
// Invoice(Invoice),
56+
// InvoiceError(InvoiceError),
57+
// CustomMessage<T>,
58+
// }
59+
60+
/// We want to avoid encoding and encrypting separately in order to avoid an intermediate Vec, thus
61+
/// we encode and encrypt at the same time using the `SharedSecret` here.
62+
impl Writeable for (Payload, SharedSecret) {
63+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
64+
}
65+
}
66+
67+
/// Onion messages contain an encrypted TLV stream. This can be supplied by someone else, in the
68+
/// case that we're sending to a blinded route, or created by us if we're constructing payloads for
69+
/// unblinded hops in the onion message's path.
70+
pub(crate) enum EncryptedTlvs {
71+
/// If we're sending to a blinded route, the node that constructed the blinded route has provided
72+
/// our onion message's `EncryptedTlvs`, already encrypted and encoded into bytes.
73+
Blinded(Vec<u8>),
74+
/// If we're receiving an onion message or constructing an onion message to send through any
75+
/// unblinded nodes, we'll need to construct the onion message's `EncryptedTlvs` in their
76+
/// unblinded state to avoid encoding them into an intermediate `Vec`.
77+
// Below will later have an additional Vec<CustomTlv>
78+
Unblinded(ControlTlvs),
79+
}
80+
3181
/// Onion messages have "control" TLVs and "data" TLVs. Control TLVs are used to control the
3282
/// direction and routing of an onion message from hop to hop, whereas data TLVs contain the onion
3383
/// message content itself.
@@ -105,6 +155,18 @@ impl BlindedRoute {
105155
fn encrypt_payload(payload: ControlTlvs, encrypted_tlvs_ss: SharedSecret) -> Vec<u8> {}
106156
}
107157

158+
/// The destination of an onion message.
159+
pub enum Destination {
160+
/// We're sending this onion message to a node.
161+
Node(PublicKey),
162+
/// We're sending this onion message to a blinded route.
163+
BlindedRoute(BlindedRoute),
164+
}
165+
166+
impl Destination {
167+
fn num_hops(&self) -> usize {
168+
}
169+
108170
/// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
109171
/// used to retrieve invoices and fulfill invoice requests from offers.
110172
pub struct OnionMessenger<Signer: Sign, K: Deref, L: Deref>
@@ -136,6 +198,10 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
136198
logger,
137199
}
138200
}
201+
202+
/// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
203+
pub fn send_onion_message(&self, intermediate_nodes: Vec<PublicKey>, destination: Destination) -> Result<(), secp256k1::Error> {
204+
}
139205
}
140206

141207
impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L>
@@ -153,9 +219,13 @@ impl<Signer: Sign, K: Deref, L: Deref> MessageSendEventsProvider for OnionMessen
153219
}
154220
}
155221

222+
/// Build an onion message's payloads for encoding in the onion packet.
223+
fn build_payloads(intermediate_nodes: Vec<PublicKey>, destination: Destination, mut encrypted_tlvs_keys: Vec<SharedSecret>) -> Vec<(Payload, SharedSecret)> {
224+
}
225+
156226
#[allow(unused_assignments)]
157227
#[inline]
158-
fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verification, FType: FnMut(PublicKey, SharedSecret, [u8; 32], PublicKey, SharedSecret)> (secp_ctx: &Secp256k1<T>, unblinded_path: &Vec<PublicKey>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {}
228+
fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verification, FType: FnMut(PublicKey, SharedSecret, [u8; 32], PublicKey, SharedSecret)> (secp_ctx: &Secp256k1<T>, unblinded_path: &Vec<PublicKey>, destination: Option<&Destination>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {}
159229

160230
/// Construct keys for constructing a blinded route along the given `unblinded_path`.
161231
///
@@ -168,6 +238,17 @@ fn construct_blinded_route_keys<T: secp256k1::Signing + secp256k1::Verification>
168238
// calls construct_keys_callback
169239
}
170240

241+
/// Construct keys for sending an onion message along the given `path`.
242+
///
243+
/// Returns: `(encrypted_tlvs_keys, onion_packet_keys)`
244+
/// where the encrypted tlvs keys are used to encrypt the [`EncryptedTlvs`] of the onion message and the
245+
/// onion packet keys are used to encrypt the onion packet.
246+
fn construct_sending_keys<T: secp256k1::Signing + secp256k1::Verification>(
247+
secp_ctx: &Secp256k1<T>, unblinded_path: &Vec<PublicKey>, destination: &Destination, session_priv: &SecretKey
248+
) -> Result<(Vec<SharedSecret>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
249+
// calls construct_keys_callback
250+
}
251+
171252
/// Useful for simplifying the parameters of [`SimpleArcChannelManager`] and
172253
/// [`SimpleArcPeerManager`]. See their docs for more details.
173254
pub type SimpleArcOnionMessenger<L> = OnionMessenger<InMemorySigner, Arc<KeysManager>, Arc<L>>;

lightning/src/ln/onion_utils.rs

+3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ pub(super) fn construct_onion_packet(payloads: Vec<msgs::OnionHopData>, onion_ke
214214
payloads, onion_keys, PacketData::Payment(packet_data), Some(associated_data)).try_into().unwrap()
215215
}
216216

217+
pub(super) fn construct_onion_message_packet(payloads: Vec<(onion_message::Payload, SharedSecret)>, onion_keys: Vec<OnionKeys>, prng_seed: [u8; 32]) -> onion_message::Packet {
218+
}
219+
217220
#[cfg(test)]
218221
// Used in testing to write bogus OnionHopDatas, which is otherwise not representable in
219222
// msgs::OnionHopData.

0 commit comments

Comments
 (0)