@@ -308,26 +308,25 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundTrampolinePayload<'a> {
308308 }
309309}
310310
311- # [ inline ]
312- fn construct_onion_keys_generic_callback < ' a , T , H , FType > (
313- secp_ctx : & Secp256k1 < T > , hops : & ' a [ H ] , blinded_tail : Option < & BlindedTail > ,
314- session_priv : & SecretKey , mut callback : FType ,
315- ) where
311+ fn construct_onion_keys_generic < ' a , T , H > (
312+ secp_ctx : & ' a Secp256k1 < T > , hops : & ' a [ H ] , blinded_tail : Option < & ' a BlindedTail > ,
313+ session_priv : & SecretKey ,
314+ ) -> impl Iterator < Item = ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & ' a H > , usize ) > + ' a
315+ where
316316 T : secp256k1:: Signing ,
317317 H : HopInfo ,
318- FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & ' a H > , usize ) ,
319318{
320319 let mut blinded_priv = session_priv. clone ( ) ;
321320 let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
322321
323- let unblinded_hops_iter = hops. iter ( ) . map ( |h| ( h. node_pubkey ( ) , Some ( h) ) ) ;
324- let blinded_pks_iter = blinded_tail
322+ let unblinded_hops = hops. iter ( ) . map ( |h| ( h. node_pubkey ( ) , Some ( h) ) ) ;
323+ let blinded_pubkeys = blinded_tail
325324 . map ( |t| t. hops . iter ( ) )
326325 . unwrap_or ( [ ] . iter ( ) )
327326 . skip ( 1 ) // Skip the intro node because it's included in the unblinded hops
328327 . map ( |h| ( & h. blinded_node_id , None ) ) ;
329328
330- for ( idx, ( pubkey, route_hop_opt) ) in unblinded_hops_iter . chain ( blinded_pks_iter ) . enumerate ( ) {
329+ unblinded_hops . chain ( blinded_pubkeys ) . enumerate ( ) . map ( move | ( idx, ( pubkey, route_hop_opt) ) | {
331330 let shared_secret = SharedSecret :: new ( pubkey, & blinded_priv) ;
332331
333332 let mut sha = Sha256 :: engine ( ) ;
@@ -342,8 +341,8 @@ fn construct_onion_keys_generic_callback<'a, T, H, FType>(
342341 . expect ( "Blinding are never invalid as we picked the starting private key randomly" ) ;
343342 blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
344343
345- callback ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt, idx) ;
346- }
344+ ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt, idx)
345+ } )
347346}
348347
349348// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
@@ -358,25 +357,20 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(
358357 }
359358 Some ( t)
360359 } ) ;
361- construct_onion_keys_generic_callback (
362- secp_ctx,
363- & path. hops ,
364- blinded_tail,
365- session_priv,
366- |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
367- let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
368-
369- res. push ( OnionKeys {
370- #[ cfg( test) ]
371- shared_secret,
372- #[ cfg( test) ]
373- blinding_factor : _blinding_factor,
374- ephemeral_pubkey,
375- rho,
376- mu,
377- } ) ;
378- } ,
379- ) ;
360+ let iter = construct_onion_keys_generic ( secp_ctx, & path. hops , blinded_tail, session_priv) ;
361+ for ( shared_secret, _blinding_factor, ephemeral_pubkey, _, _) in iter {
362+ let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
363+
364+ res. push ( OnionKeys {
365+ #[ cfg( test) ]
366+ shared_secret,
367+ #[ cfg( test) ]
368+ blinding_factor : _blinding_factor,
369+ ephemeral_pubkey,
370+ rho,
371+ mu,
372+ } ) ;
373+ }
380374
381375 res
382376}
@@ -387,25 +381,21 @@ pub(super) fn construct_trampoline_onion_keys<T: secp256k1::Signing>(
387381) -> Vec < OnionKeys > {
388382 let mut res = Vec :: with_capacity ( blinded_tail. trampoline_hops . len ( ) ) ;
389383
390- construct_onion_keys_generic_callback (
391- secp_ctx,
392- & blinded_tail. trampoline_hops ,
393- Some ( blinded_tail) ,
394- session_priv,
395- |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
396- let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
397-
398- res. push ( OnionKeys {
399- #[ cfg( test) ]
400- shared_secret,
401- #[ cfg( test) ]
402- blinding_factor : _blinding_factor,
403- ephemeral_pubkey,
404- rho,
405- mu,
406- } ) ;
407- } ,
408- ) ;
384+ let hops = & blinded_tail. trampoline_hops ;
385+ let iter = construct_onion_keys_generic ( secp_ctx, & hops, Some ( blinded_tail) , session_priv) ;
386+ for ( shared_secret, _blinding_factor, ephemeral_pubkey, _, _) in iter {
387+ let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
388+
389+ res. push ( OnionKeys {
390+ #[ cfg( test) ]
391+ shared_secret,
392+ #[ cfg( test) ]
393+ blinding_factor : _blinding_factor,
394+ ephemeral_pubkey,
395+ rho,
396+ mu,
397+ } ) ;
398+ }
409399
410400 res
411401}
@@ -1113,31 +1103,27 @@ where
11131103 let mut onion_keys =
11141104 Vec :: with_capacity ( path. hops . len ( ) + num_trampoline_hops + num_blinded_hops) ;
11151105
1116- construct_onion_keys_generic_callback (
1117- secp_ctx,
1118- & path. hops ,
1119- // if we have Trampoline hops, the blinded hops are part of the inner Trampoline onion
1120- if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ,
1121- outer_session_priv,
1122- |shared_secret, _, _, route_hop_option : Option < & RouteHop > , _| {
1123- onion_keys. push ( ( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret) )
1124- } ,
1125- ) ;
1106+ // if we have Trampoline hops, the blinded hops are part of the inner Trampoline onion
1107+ let nontrampoline_bp =
1108+ if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ;
1109+ let nontrampoline_hops =
1110+ construct_onion_keys_generic ( secp_ctx, & path. hops , nontrampoline_bp, outer_session_priv) ;
1111+ for ( shared_secret, _, _, route_hop_option, _) in nontrampoline_hops {
1112+ onion_keys. push ( ( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret) ) ;
1113+ }
11261114
11271115 if path. has_trampoline_hops ( ) {
1128- construct_onion_keys_generic_callback (
1129- secp_ctx,
1130- // Trampoline hops are part of the blinded tail, so this can never panic
1131- & path. blinded_tail . as_ref ( ) . unwrap ( ) . trampoline_hops ,
1132- path. blinded_tail . as_ref ( ) ,
1133- inner_session_priv. expect ( "Trampoline hops always have an inner session priv" ) ,
1134- |shared_secret, _, _, trampoline_hop_option : Option < & TrampolineHop > , _| {
1135- onion_keys. push ( (
1136- trampoline_hop_option. map ( |th| ErrorHop :: TrampolineHop ( th) ) ,
1137- shared_secret,
1138- ) )
1139- } ,
1140- ) ;
1116+ // Trampoline hops are part of the blinded tail, so this can never panic
1117+ let blinded_tail = path. blinded_tail . as_ref ( ) ;
1118+ let hops = & blinded_tail. unwrap ( ) . trampoline_hops ;
1119+ let inner_session_priv =
1120+ inner_session_priv. expect ( "Trampoline hops always have an inner session priv" ) ;
1121+ let trampoline_hops =
1122+ construct_onion_keys_generic ( secp_ctx, hops, blinded_tail, inner_session_priv) ;
1123+ for ( shared_secret, _, _, trampoline_hop_option, _) in trampoline_hops {
1124+ onion_keys
1125+ . push ( ( trampoline_hop_option. map ( |th| ErrorHop :: TrampolineHop ( th) ) , shared_secret) ) ;
1126+ }
11411127 }
11421128
11431129 // In the best case, paths can be up to 27 hops. But attribution data can only be conveyed back to the sender from
@@ -3191,15 +3177,11 @@ mod tests {
31913177 let path = Path { hops, blinded_tail : None } ;
31923178
31933179 // Calculate shared secrets.
3194- let mut onion_keys = Vec :: new ( ) ;
31953180 let session_key = get_test_session_key ( ) ;
3196- construct_onion_keys_generic_callback (
3197- & secp_ctx,
3198- & path. hops ,
3199- None ,
3200- & session_key,
3201- |shared_secret, _, _, _, _| onion_keys. push ( shared_secret) ,
3202- ) ;
3181+ let onion_keys: Vec < _ > =
3182+ construct_onion_keys_generic ( & secp_ctx, & path. hops , None , & session_key)
3183+ . map ( |( key, ..) | key)
3184+ . collect ( ) ;
32033185
32043186 // Construct the htlc source.
32053187 let logger = TestLogger :: new ( ) ;
0 commit comments