@@ -308,26 +308,25 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundTrampolinePayload<'a> {
308
308
}
309
309
}
310
310
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
316
316
T : secp256k1:: Signing ,
317
317
H : HopInfo ,
318
- FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & ' a H > , usize ) ,
319
318
{
320
319
let mut blinded_priv = session_priv. clone ( ) ;
321
320
let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
322
321
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
325
324
. map ( |t| t. hops . iter ( ) )
326
325
. unwrap_or ( [ ] . iter ( ) )
327
326
. skip ( 1 ) // Skip the intro node because it's included in the unblinded hops
328
327
. map ( |h| ( & h. blinded_node_id , None ) ) ;
329
328
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) ) | {
331
330
let shared_secret = SharedSecret :: new ( pubkey, & blinded_priv) ;
332
331
333
332
let mut sha = Sha256 :: engine ( ) ;
@@ -342,8 +341,8 @@ fn construct_onion_keys_generic_callback<'a, T, H, FType>(
342
341
. expect ( "Blinding are never invalid as we picked the starting private key randomly" ) ;
343
342
blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
344
343
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
+ } )
347
346
}
348
347
349
348
// 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>(
358
357
}
359
358
Some ( t)
360
359
} ) ;
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
+ }
380
374
381
375
res
382
376
}
@@ -387,25 +381,21 @@ pub(super) fn construct_trampoline_onion_keys<T: secp256k1::Signing>(
387
381
) -> Vec < OnionKeys > {
388
382
let mut res = Vec :: with_capacity ( blinded_tail. trampoline_hops . len ( ) ) ;
389
383
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
+ }
409
399
410
400
res
411
401
}
@@ -1113,31 +1103,27 @@ where
1113
1103
let mut onion_keys =
1114
1104
Vec :: with_capacity ( path. hops . len ( ) + num_trampoline_hops + num_blinded_hops) ;
1115
1105
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
+ }
1126
1114
1127
1115
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
+ }
1141
1127
}
1142
1128
1143
1129
// 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 {
3191
3177
let path = Path { hops, blinded_tail : None } ;
3192
3178
3193
3179
// Calculate shared secrets.
3194
- let mut onion_keys = Vec :: new ( ) ;
3195
3180
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 ( ) ;
3203
3185
3204
3186
// Construct the htlc source.
3205
3187
let logger = TestLogger :: new ( ) ;
0 commit comments