@@ -75,11 +75,11 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
75
75
76
76
// can only fail if an intermediary hop has an invalid public key or session_priv is invalid
77
77
#[ inline]
78
- pub ( super ) fn construct_onion_keys_callback < T : secp256k1:: Signing , FType : FnMut ( SharedSecret , [ u8 ; 32 ] , PublicKey , & RouteHop ) > ( secp_ctx : & Secp256k1 < T > , path : & Vec < RouteHop > , session_priv : & SecretKey , mut callback : FType ) -> Result < ( ) , secp256k1:: Error > {
78
+ 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 > {
79
79
let mut blinded_priv = session_priv. clone ( ) ;
80
80
let mut blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
81
81
82
- for hop in path. iter ( ) {
82
+ for ( idx , hop) in path. iter ( ) . enumerate ( ) {
83
83
let shared_secret = SharedSecret :: new ( & hop. pubkey , & blinded_priv) ;
84
84
85
85
let mut sha = Sha256 :: engine ( ) ;
@@ -92,7 +92,7 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
92
92
blinded_priv. mul_assign ( & blinding_factor) ?;
93
93
blinded_pub = PublicKey :: from_secret_key ( secp_ctx, & blinded_priv) ;
94
94
95
- callback ( shared_secret, blinding_factor, ephemeral_pubkey, hop) ;
95
+ callback ( shared_secret, blinding_factor, ephemeral_pubkey, hop, idx ) ;
96
96
}
97
97
98
98
Ok ( ( ) )
@@ -102,7 +102,7 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
102
102
pub ( super ) fn construct_onion_keys < T : secp256k1:: Signing > ( secp_ctx : & Secp256k1 < T > , path : & Vec < RouteHop > , session_priv : & SecretKey ) -> Result < Vec < OnionKeys > , secp256k1:: Error > {
103
103
let mut res = Vec :: with_capacity ( path. len ( ) ) ;
104
104
105
- construct_onion_keys_callback ( secp_ctx, path, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _| {
105
+ construct_onion_keys_callback ( secp_ctx, path, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _, _ | {
106
106
let ( rho, mu) = gen_rho_mu_from_shared_secret ( & shared_secret[ ..] ) ;
107
107
108
108
res. push ( OnionKeys {
@@ -337,12 +337,10 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
337
337
let mut htlc_msat = * first_hop_htlc_msat;
338
338
let mut error_code_ret = None ;
339
339
let mut error_packet_ret = None ;
340
- let mut next_route_hop_ix = 0 ;
341
340
let mut is_from_final_node = false ;
342
341
343
342
// Handle packed channel/node updates for passing back for the route handler
344
- construct_onion_keys_callback ( secp_ctx, path, session_priv, |shared_secret, _, _, route_hop| {
345
- next_route_hop_ix += 1 ;
343
+ construct_onion_keys_callback ( secp_ctx, path, session_priv, |shared_secret, _, _, route_hop, route_hop_idx| {
346
344
if res. is_some ( ) { return ; }
347
345
348
346
let amt_to_forward = htlc_msat - route_hop. fee_msat ;
@@ -356,7 +354,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
356
354
chacha. process ( & packet_decrypted, & mut decryption_tmp[ ..] ) ;
357
355
packet_decrypted = decryption_tmp;
358
356
359
- is_from_final_node = path . last ( ) . unwrap ( ) . pubkey == route_hop . pubkey ;
357
+ is_from_final_node = route_hop_idx + 1 == path . len ( ) ;
360
358
361
359
if let Ok ( err_packet) = msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & packet_decrypted) ) {
362
360
let um = gen_um_from_shared_secret ( & shared_secret[ ..] ) ;
@@ -388,10 +386,13 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
388
386
network_update = Some ( NetworkUpdate :: NodeFailure { node_id : route_hop. pubkey , is_permanent : error_code & PERM == PERM } ) ;
389
387
}
390
388
else if error_code & PERM == PERM {
391
- network_update = if payment_failed { None } else { Some ( NetworkUpdate :: ChannelClosed {
392
- short_channel_id : path[ next_route_hop_ix - if next_route_hop_ix == path. len ( ) { 1 } else { 0 } ] . short_channel_id ,
393
- is_permanent : true ,
394
- } ) } ;
389
+ network_update = if payment_failed { None } else {
390
+ let failing_route_hop = if is_from_final_node { route_hop } else { & path[ route_hop_idx + 1 ] } ;
391
+ Some ( NetworkUpdate :: ChannelClosed {
392
+ short_channel_id : failing_route_hop. short_channel_id ,
393
+ is_permanent : true ,
394
+ } )
395
+ } ;
395
396
}
396
397
else if error_code & UPDATE == UPDATE {
397
398
if let Some ( update_len_slice) = err_packet. failuremsg . get ( debug_field_size+2 ..debug_field_size+4 ) {
0 commit comments