@@ -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+
249306impl < ES : Deref , NS : Deref , L : Deref , MR : Deref , OMH : Deref , CMH : Deref >
250307OnionMessenger < ES , NS , L , MR , OMH , CMH >
251308where
@@ -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