@@ -104,12 +104,22 @@ pub(crate) fn next_hop_packet_pubkey<T: secp256k1::Signing + secp256k1::Verifica
104
104
105
105
// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
106
106
#[ 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
+ {
108
114
let mut blinded_priv = session_priv. clone ( ) ;
109
115
let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
110
116
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) ;
113
123
114
124
let mut sha = Sha256 :: engine ( ) ;
115
125
sha. input ( & blinded_pub. serialize ( ) [ ..] ) ;
@@ -121,7 +131,7 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
121
131
blinded_priv = blinded_priv. mul_tweak ( & Scalar :: from_be_bytes ( blinding_factor) . unwrap ( ) ) ?;
122
132
blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
123
133
124
- callback ( shared_secret, blinding_factor, ephemeral_pubkey, hop , idx) ;
134
+ callback ( shared_secret, blinding_factor, ephemeral_pubkey, route_hop_opt , idx) ;
125
135
}
126
136
127
137
Ok ( ( ) )
@@ -131,7 +141,9 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
131
141
pub ( super ) fn construct_onion_keys < T : secp256k1:: Signing > ( secp_ctx : & Secp256k1 < T > , path : & Path , session_priv : & SecretKey ) -> Result < Vec < OnionKeys > , secp256k1:: Error > {
132
142
let mut res = Vec :: with_capacity ( path. hops . len ( ) ) ;
133
143
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
+ {
135
147
let ( rho, mu) = gen_rho_mu_from_shared_secret ( shared_secret. as_ref ( ) ) ;
136
148
137
149
res. push ( OnionKeys {
@@ -396,9 +408,16 @@ where L::Target: Logger {
396
408
let mut is_from_final_node = false ;
397
409
398
410
// Handle packed channel/node updates for passing back for the route handler
399
- construct_onion_keys_callback ( secp_ctx, & path. hops , session_priv, |shared_secret, _, _, route_hop, route_hop_idx| {
411
+ construct_onion_keys_callback ( secp_ctx, & path, session_priv,
412
+ |shared_secret, _, _, route_hop_opt, route_hop_idx|
413
+ {
400
414
if res. is_some ( ) { return ; }
401
415
416
+ let route_hop = match route_hop_opt {
417
+ Some ( hop) => hop,
418
+ None => return ,
419
+ } ;
420
+
402
421
let amt_to_forward = htlc_msat - route_hop. fee_msat ;
403
422
htlc_msat = amt_to_forward;
404
423
0 commit comments