Skip to content

Commit f6cbff3

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 8138657 commit f6cbff3

File tree

1 file changed

+60
-64
lines changed

1 file changed

+60
-64
lines changed

lightning/src/onion_message/messenger.rs

Lines changed: 60 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,63 @@ 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> where
256+
ES::Target: EntropySource,
257+
NS::Target: NodeSigner,
258+
{
259+
let OnionMessagePath { intermediate_nodes, mut destination } = path;
260+
if let Destination::BlindedPath(BlindedPath { ref blinded_hops, .. }) = destination {
261+
if blinded_hops.len() < 2 {
262+
return Err(SendError::TooFewBlindedHops);
263+
}
264+
}
265+
266+
if message.tlv_type() < 64 { return Err(SendError::InvalidMessage) }
267+
268+
// If we are sending straight to a blinded path and we are the introduction node, we need to
269+
// advance the blinded path by 1 hop so the second hop is the new introduction node.
270+
if intermediate_nodes.len() == 0 {
271+
if let Destination::BlindedPath(ref mut blinded_path) = destination {
272+
let our_node_id = node_signer.get_node_id(Recipient::Node)
273+
.map_err(|()| SendError::GetNodeIdFailed)?;
274+
if blinded_path.introduction_node_id == our_node_id {
275+
advance_path_by_one(blinded_path, node_signer, &secp_ctx)
276+
.map_err(|()| SendError::BlindedPathAdvanceFailed)?;
277+
}
278+
}
279+
}
280+
281+
let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
282+
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
283+
let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
284+
(intermediate_nodes[0], PublicKey::from_secret_key(&secp_ctx, &blinding_secret))
285+
} else {
286+
match destination {
287+
Destination::Node(pk) => (pk, PublicKey::from_secret_key(&secp_ctx, &blinding_secret)),
288+
Destination::BlindedPath(BlindedPath { introduction_node_id, blinding_point, .. }) =>
289+
(introduction_node_id, blinding_point),
290+
}
291+
};
292+
let (packet_payloads, packet_keys) = packet_payloads_and_keys(
293+
&secp_ctx, &intermediate_nodes, destination, message, reply_path, &blinding_secret)
294+
.map_err(|e| SendError::Secp256k1(e))?;
295+
296+
let prng_seed = entropy_source.get_secure_random_bytes();
297+
let onion_routing_packet = construct_onion_message_packet(
298+
packet_payloads, packet_keys, prng_seed).map_err(|()| SendError::TooBigPacket)?;
299+
300+
Ok((introduction_node_id, msgs::OnionMessage {
301+
blinding_point,
302+
onion_routing_packet
303+
}))
304+
}
305+
249306
impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
250307
OnionMessenger<ES, NS, L, MR, OMH, CMH>
251308
where
@@ -283,13 +340,9 @@ where
283340
&self, path: OnionMessagePath, message: OnionMessageContents<T>,
284341
reply_path: Option<BlindedPath>
285342
) -> 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
343+
let (introduction_node_id, onion_msg) = create_onion_message(
344+
&self.entropy_source, &self.node_signer, &self.secp_ctx,
345+
path, message, reply_path
293346
)?;
294347

295348
let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
@@ -303,63 +356,6 @@ where
303356
}
304357
}
305358

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-
363359
fn respond_with_onion_message<T: CustomOnionMessageContents>(
364360
&self, response: OnionMessageContents<T>, path_id: Option<[u8; 32]>,
365361
reply_path: Option<BlindedPath>

0 commit comments

Comments
 (0)