Skip to content

Commit 07205a2

Browse files
committed
Make create_onion_message a freestanding function
The new `create_onion_message` function in `OnionMessenger` is hard to handle - it has various generic requirements indirectly via the struct, but they're not bounded by any of the method parameters. Thus, you can't simply call `OnionMessenger::create_onion_message`, as various bounds are not specified. Instead, we move it to a freestanding function so that it can be called directly without explicitly setting bounds.
1 parent 6ce4c6c commit 07205a2

File tree

1 file changed

+61
-64
lines changed

1 file changed

+61
-64
lines changed

lightning/src/onion_message/messenger.rs

Lines changed: 61 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,64 @@ pub trait CustomOnionMessageHandler {
246246
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
247247
}
248248

249+
250+
/// Create an onion message with contents `message` to the destination of `path`.
251+
/// Returns (introduction_node_id, onion_msg)
252+
pub fn create_onion_message<ES: Deref, NS: Deref, T: CustomOnionMessageContents>(
253+
entropy_source: &ES, node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>,
254+
path: OnionMessagePath, message: OnionMessageContents<T>, reply_path: Option<BlindedPath>,
255+
) -> Result<(PublicKey, msgs::OnionMessage), SendError>
256+
where
257+
ES::Target: EntropySource,
258+
NS::Target: NodeSigner,
259+
{
260+
let OnionMessagePath { intermediate_nodes, mut destination } = path;
261+
if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination {
262+
if blinded_hops.len() < 2 {
263+
return Err(SendError::TooFewBlindedHops);
264+
}
265+
}
266+
267+
if message.tlv_type() < 64 { return Err(SendError::InvalidMessage) }
268+
269+
// If we are sending straight to a blinded path and we are the introduction node, we need to
270+
// advance the blinded path by 1 hop so the second hop is the new introduction node.
271+
if intermediate_nodes.len() == 0 {
272+
if let Destination::BlindedPath(ref mut blinded_path) = destination {
273+
let our_node_id = node_signer.get_node_id(Recipient::Node)
274+
.map_err(|()| SendError::GetNodeIdFailed)?;
275+
if blinded_path.introduction_node_id == our_node_id {
276+
advance_path_by_one(blinded_path, node_signer, &secp_ctx)
277+
.map_err(|()| SendError::BlindedPathAdvanceFailed)?;
278+
}
279+
}
280+
}
281+
282+
let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
283+
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
284+
let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
285+
(intermediate_nodes[0], PublicKey::from_secret_key(&secp_ctx, &blinding_secret))
286+
} else {
287+
match destination {
288+
Destination::Node(pk) => (pk, PublicKey::from_secret_key(&secp_ctx, &blinding_secret)),
289+
Destination::BlindedPath(BlindedPath { introduction_node_id, blinding_point, .. }) =>
290+
(introduction_node_id, blinding_point),
291+
}
292+
};
293+
let (packet_payloads, packet_keys) = packet_payloads_and_keys(
294+
&secp_ctx, &intermediate_nodes, destination, message, reply_path, &blinding_secret)
295+
.map_err(|e| SendError::Secp256k1(e))?;
296+
297+
let prng_seed = entropy_source.get_secure_random_bytes();
298+
let onion_routing_packet = construct_onion_message_packet(
299+
packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
300+
301+
Ok((introduction_node_id, msgs::OnionMessage {
302+
blinding_point,
303+
onion_routing_packet
304+
}))
305+
}
306+
249307
impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
250308
OnionMessenger<ES, NS, L, MR, OMH, CMH>
251309
where
@@ -283,13 +341,9 @@ where
283341
&self, path: OnionMessagePath, message: OnionMessageContents<T>,
284342
reply_path: Option<BlindedPath>
285343
) -> Result<(), SendError> {
286-
let (introduction_node_id, onion_msg) = Self::create_onion_message(
287-
&self.entropy_source,
288-
&self.node_signer,
289-
&self.secp_ctx,
290-
path,
291-
message,
292-
reply_path
344+
let (introduction_node_id, onion_msg) = create_onion_message(
345+
&self.entropy_source, &self.node_signer, &self.secp_ctx,
346+
path, message, reply_path
293347
)?;
294348

295349
let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
@@ -303,63 +357,6 @@ where
303357
}
304358
}
305359

306-
/// Create an onion message with contents `message` to the destination of `path`.
307-
/// Returns (introduction_node_id, onion_msg)
308-
pub fn create_onion_message<T: CustomOnionMessageContents>(
309-
entropy_source: &ES,
310-
node_signer: &NS,
311-
secp_ctx: &Secp256k1<secp256k1::All>,
312-
path: OnionMessagePath,
313-
message: OnionMessageContents<T>,
314-
reply_path: Option<BlindedPath>,
315-
) -> Result<(PublicKey, msgs::OnionMessage), SendError> {
316-
let OnionMessagePath { intermediate_nodes, mut destination } = path;
317-
if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination {
318-
if blinded_hops.len() < 2 {
319-
return Err(SendError::TooFewBlindedHops);
320-
}
321-
}
322-
323-
if message.tlv_type() < 64 { return Err(SendError::InvalidMessage) }
324-
325-
// If we are sending straight to a blinded path and we are the introduction node, we need to
326-
// advance the blinded path by 1 hop so the second hop is the new introduction node.
327-
if intermediate_nodes.len() == 0 {
328-
if let Destination::BlindedPath(ref mut blinded_path) = destination {
329-
let our_node_id = node_signer.get_node_id(Recipient::Node)
330-
.map_err(|()| SendError::GetNodeIdFailed)?;
331-
if blinded_path.introduction_node_id == our_node_id {
332-
advance_path_by_one(blinded_path, node_signer, &secp_ctx)
333-
.map_err(|()| SendError::BlindedPathAdvanceFailed)?;
334-
}
335-
}
336-
}
337-
338-
let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
339-
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
340-
let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
341-
(intermediate_nodes[0], PublicKey::from_secret_key(&secp_ctx, &blinding_secret))
342-
} else {
343-
match destination {
344-
Destination::Node(pk) => (pk, PublicKey::from_secret_key(&secp_ctx, &blinding_secret)),
345-
Destination::BlindedPath(BlindedPath { introduction_node_id, blinding_point, .. }) =>
346-
(introduction_node_id, blinding_point),
347-
}
348-
};
349-
let (packet_payloads, packet_keys) = packet_payloads_and_keys(
350-
&secp_ctx, &intermediate_nodes, destination, message, reply_path, &blinding_secret)
351-
.map_err(|e| SendError::Secp256k1(e))?;
352-
353-
let prng_seed = entropy_source.get_secure_random_bytes();
354-
let onion_routing_packet = construct_onion_message_packet(
355-
packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
356-
357-
Ok((introduction_node_id, msgs::OnionMessage {
358-
blinding_point,
359-
onion_routing_packet
360-
}))
361-
}
362-
363360
fn respond_with_onion_message<T: CustomOnionMessageContents>(
364361
&self, response: OnionMessageContents<T>, path_id: Option<[u8; 32]>,
365362
reply_path: Option<BlindedPath>

0 commit comments

Comments
 (0)