@@ -104,12 +104,22 @@ pub(crate) fn next_hop_packet_pubkey<T: secp256k1::Signing + secp256k1::Verifica
104104
105105// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
106106#[ inline]
107- pub ( super ) fn construct_onion_keys_callback < T : secp256k1:: Signing , FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , & RouteHop , usize ) > ( secp_ctx : & Secp256k1 < T > , path : & Vec < RouteHop > , session_priv : & SecretKey , mut callback : FType ) -> Result < ( ) , secp256k1:: Error > {
107+ pub ( super ) fn construct_onion_keys_callback < T , FType > (
108+ secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey , mut callback : FType
109+ ) -> Result < ( ) , secp256k1:: Error >
110+ where
111+ T : secp256k1:: Signing ,
112+ FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , Option < & RouteHop > , usize )
113+ {
108114 let mut blinded_priv = session_priv. clone ( ) ;
109115 let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
110116
111- for ( idx, hop) in path. iter ( ) . enumerate ( ) {
112- let shared_secret = SharedSecret :: new ( & hop. pubkey , & blinded_priv) ;
117+ for ( idx, ( pubkey, route_hop_opt) ) in path. hops . iter ( ) . map ( |h| ( h. pubkey , Some ( h) ) )
118+ . chain ( path. blinded_tail . as_ref ( ) . map ( |t| t. hops . iter ( ) ) . unwrap_or ( [ ] . iter ( ) ) . skip ( 1 )
119+ . map ( |h| ( h. blinded_node_id , None ) ) )
120+ . enumerate ( )
121+ {
122+ let shared_secret = SharedSecret :: new ( & pubkey, & blinded_priv) ;
113123
114124 let mut sha = Sha256 :: engine ( ) ;
115125 sha. input ( & blinded_pub. serialize ( ) [ ..] ) ;
@@ -121,7 +131,7 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
121131 blinded_priv = blinded_priv. mul_tweak ( & Scalar :: from_be_bytes ( blinding_factor) . unwrap ( ) ) ?;
122132 blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
123133
124- callback ( shared_secret, blinding_factor, ephemeral_pubkey, hop , idx) ;
134+ callback ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt , idx) ;
125135 }
126136
127137 Ok ( ( ) )
@@ -131,7 +141,9 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
131141pub ( super ) fn construct_onion_keys < T : secp256k1:: Signing > ( secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey ) -> Result < Vec < OnionKeys > , secp256k1:: Error > {
132142 let mut res = Vec :: with_capacity ( path. hops . len ( ) ) ;
133143
134- construct_onion_keys_callback ( secp_ctx, & path. hops , session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
144+ construct_onion_keys_callback ( secp_ctx, & path, session_priv,
145+ |shared_secret, _blinding_factor, ephemeral_pubkey, _, _|
146+ {
135147 let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
136148
137149 res. push ( OnionKeys {
@@ -401,9 +413,16 @@ where L::Target: Logger {
401413 let mut is_from_final_node = false ;
402414
403415 // Handle packed channel/node updates for passing back for the route handler
404- construct_onion_keys_callback ( secp_ctx, & path. hops , session_priv, |shared_secret, _, _, route_hop, route_hop_idx| {
416+ construct_onion_keys_callback ( secp_ctx, & path, session_priv,
417+ |shared_secret, _, _, route_hop_opt, route_hop_idx|
418+ {
405419 if res. is_some ( ) { return ; }
406420
421+ let route_hop = match route_hop_opt {
422+ Some ( hop) => hop,
423+ None => return ,
424+ } ;
425+
407426 let amt_to_forward = htlc_msat - route_hop. fee_msat ;
408427 htlc_msat = amt_to_forward;
409428
0 commit comments