@@ -296,26 +296,25 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundTrampolinePayload<'a> {
296296 }
297297}
298298
299- # [ inline ]
300- fn construct_onion_keys_generic_callback < ' a , T , H , FType > (
301- secp_ctx : & Secp256k1 < T > , hops : & ' a [ H ] , blinded_tail : Option < & BlindedTail > ,
302- session_priv : & SecretKey , mut callback : FType ,
303- ) where
299+ fn construct_onion_keys_generic < ' a , T , H > (
300+ secp_ctx : & ' a Secp256k1 < T > , hops : & ' a [ H ] , blinded_tail : Option < & ' a BlindedTail > ,
301+ session_priv : & SecretKey ,
302+ ) -> impl Iterator < Item = ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & ' a H > , usize ) > + ' a
303+ where
304304 T : secp256k1:: Signing ,
305305 H : HopInfo ,
306- FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & ' a H > , usize ) ,
307306{
308307 let mut blinded_priv = session_priv. clone ( ) ;
309308 let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
310309
311- let unblinded_hops_iter = hops. iter ( ) . map ( |h| ( h. node_pubkey ( ) , Some ( h) ) ) ;
312- let blinded_pks_iter = blinded_tail
310+ let unblinded_hops = hops. iter ( ) . map ( |h| ( h. node_pubkey ( ) , Some ( h) ) ) ;
311+ let blinded_pks = blinded_tail
313312 . map ( |t| t. hops . iter ( ) )
314313 . unwrap_or ( [ ] . iter ( ) )
315314 . skip ( 1 ) // Skip the intro node because it's included in the unblinded hops
316315 . map ( |h| ( & h. blinded_node_id , None ) ) ;
317316
318- for ( idx, ( pubkey, route_hop_opt) ) in unblinded_hops_iter . chain ( blinded_pks_iter ) . enumerate ( ) {
317+ unblinded_hops . chain ( blinded_pks ) . enumerate ( ) . map ( move | ( idx, ( pubkey, route_hop_opt) ) | {
319318 let shared_secret = SharedSecret :: new ( pubkey, & blinded_priv) ;
320319
321320 let mut sha = Sha256 :: engine ( ) ;
@@ -330,8 +329,8 @@ fn construct_onion_keys_generic_callback<'a, T, H, FType>(
330329 . expect ( "Blinding are never invalid as we picked the starting private key randomly" ) ;
331330 blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
332331
333- callback ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt, idx) ;
334- }
332+ ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt, idx)
333+ } )
335334}
336335
337336// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
@@ -346,25 +345,20 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(
346345 }
347346 Some ( t)
348347 } ) ;
349- construct_onion_keys_generic_callback (
350- secp_ctx,
351- & path. hops ,
352- blinded_tail,
353- session_priv,
354- |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
355- let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
356-
357- res. push ( OnionKeys {
358- #[ cfg( test) ]
359- shared_secret,
360- #[ cfg( test) ]
361- blinding_factor : _blinding_factor,
362- ephemeral_pubkey,
363- rho,
364- mu,
365- } ) ;
366- } ,
367- ) ;
348+ let iter = construct_onion_keys_generic ( secp_ctx, & path. hops , blinded_tail, session_priv) ;
349+ for ( shared_secret, _blinding_factor, ephemeral_pubkey, _, _) in iter {
350+ let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
351+
352+ res. push ( OnionKeys {
353+ #[ cfg( test) ]
354+ shared_secret,
355+ #[ cfg( test) ]
356+ blinding_factor : _blinding_factor,
357+ ephemeral_pubkey,
358+ rho,
359+ mu,
360+ } ) ;
361+ }
368362
369363 res
370364}
@@ -375,25 +369,21 @@ pub(super) fn construct_trampoline_onion_keys<T: secp256k1::Signing>(
375369) -> Vec < OnionKeys > {
376370 let mut res = Vec :: with_capacity ( blinded_tail. trampoline_hops . len ( ) ) ;
377371
378- construct_onion_keys_generic_callback (
379- secp_ctx,
380- & blinded_tail. trampoline_hops ,
381- Some ( blinded_tail) ,
382- session_priv,
383- |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
384- let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
385-
386- res. push ( OnionKeys {
387- #[ cfg( test) ]
388- shared_secret,
389- #[ cfg( test) ]
390- blinding_factor : _blinding_factor,
391- ephemeral_pubkey,
392- rho,
393- mu,
394- } ) ;
395- } ,
396- ) ;
372+ let hops = & blinded_tail. trampoline_hops ;
373+ let iter = construct_onion_keys_generic ( secp_ctx, & hops, Some ( blinded_tail) , session_priv) ;
374+ for ( shared_secret, _blinding_factor, ephemeral_pubkey, _, _) in iter {
375+ let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
376+
377+ res. push ( OnionKeys {
378+ #[ cfg( test) ]
379+ shared_secret,
380+ #[ cfg( test) ]
381+ blinding_factor : _blinding_factor,
382+ ephemeral_pubkey,
383+ rho,
384+ mu,
385+ } ) ;
386+ }
397387
398388 res
399389}
@@ -1043,31 +1033,27 @@ where
10431033 let mut onion_keys =
10441034 Vec :: with_capacity ( path. hops . len ( ) + num_trampoline_hops + num_blinded_hops) ;
10451035
1046- construct_onion_keys_generic_callback (
1047- secp_ctx,
1048- & path. hops ,
1049- // if we have Trampoline hops, the blinded hops are part of the inner Trampoline onion
1050- if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ,
1051- outer_session_priv,
1052- |shared_secret, _, _, route_hop_option : Option < & RouteHop > , _| {
1053- onion_keys. push ( ( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret) )
1054- } ,
1055- ) ;
1036+ // if we have Trampoline hops, the blinded hops are part of the inner Trampoline onion
1037+ let nontrampoline_bp =
1038+ if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ;
1039+ let nontrampoline_hops =
1040+ construct_onion_keys_generic ( secp_ctx, & path. hops , nontrampoline_bp, outer_session_priv) ;
1041+ for ( shared_secret, _, _, route_hop_option, _) in nontrampoline_hops {
1042+ onion_keys. push ( ( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret) ) ;
1043+ }
10561044
10571045 if path. has_trampoline_hops ( ) {
1058- construct_onion_keys_generic_callback (
1059- secp_ctx,
1060- // Trampoline hops are part of the blinded tail, so this can never panic
1061- & path. blinded_tail . as_ref ( ) . unwrap ( ) . trampoline_hops ,
1062- path. blinded_tail . as_ref ( ) ,
1063- inner_session_priv. expect ( "Trampoline hops always have an inner session priv" ) ,
1064- |shared_secret, _, _, trampoline_hop_option : Option < & TrampolineHop > , _| {
1065- onion_keys. push ( (
1066- trampoline_hop_option. map ( |th| ErrorHop :: TrampolineHop ( th) ) ,
1067- shared_secret,
1068- ) )
1069- } ,
1070- ) ;
1046+ // Trampoline hops are part of the blinded tail, so this can never panic
1047+ let blinded_tail = path. blinded_tail . as_ref ( ) ;
1048+ let hops = & blinded_tail. unwrap ( ) . trampoline_hops ;
1049+ let inner_session_priv =
1050+ inner_session_priv. expect ( "Trampoline hops always have an inner session priv" ) ;
1051+ let trampoline_hops =
1052+ construct_onion_keys_generic ( secp_ctx, hops, blinded_tail, inner_session_priv) ;
1053+ for ( shared_secret, _, _, trampoline_hop_option, _) in trampoline_hops {
1054+ onion_keys
1055+ . push ( ( trampoline_hop_option. map ( |th| ErrorHop :: TrampolineHop ( th) ) , shared_secret) ) ;
1056+ }
10711057 }
10721058
10731059 // Handle packed channel/node updates for passing back for the route handler
@@ -2163,8 +2149,7 @@ mod tests {
21632149 let route = Route { paths : vec ! [ path] , route_params : None } ;
21642150
21652151 let onion_keys =
2166- super :: construct_onion_keys ( & secp_ctx, & route. paths [ 0 ] , & get_test_session_key ( ) )
2167- . unwrap ( ) ;
2152+ super :: construct_onion_keys ( & secp_ctx, & route. paths [ 0 ] , & get_test_session_key ( ) ) ;
21682153 assert_eq ! ( onion_keys. len( ) , route. paths[ 0 ] . hops. len( ) ) ;
21692154 onion_keys
21702155 }
@@ -2536,13 +2521,12 @@ mod tests {
25362521 & secp_ctx,
25372522 & path. blinded_tail . as_ref ( ) . unwrap ( ) ,
25382523 & session_priv,
2539- )
2540- . unwrap ( ) ;
2524+ ) ;
25412525
25422526 let outer_onion_keys = {
25432527 let session_priv_hash = Sha256 :: hash ( & session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
25442528 let outer_session_priv = SecretKey :: from_slice ( & session_priv_hash[ ..] ) . unwrap ( ) ;
2545- construct_onion_keys ( & Secp256k1 :: new ( ) , & path, & outer_session_priv) . unwrap ( )
2529+ construct_onion_keys ( & Secp256k1 :: new ( ) , & path, & outer_session_priv)
25462530 } ;
25472531
25482532 let htlc_source = HTLCSource :: OutboundRoute {
0 commit comments