@@ -419,14 +419,6 @@ where L::Target: Logger {
419
419
{
420
420
if res. is_some ( ) { return ; }
421
421
422
- let route_hop = match route_hop_opt {
423
- Some ( hop) => hop,
424
- None => return ,
425
- } ;
426
-
427
- let amt_to_forward = htlc_msat - route_hop. fee_msat ;
428
- htlc_msat = amt_to_forward;
429
-
430
422
let ammag = gen_ammag_from_shared_secret ( shared_secret. as_ref ( ) ) ;
431
423
432
424
let mut decryption_tmp = Vec :: with_capacity ( packet_decrypted. len ( ) ) ;
@@ -435,11 +427,6 @@ where L::Target: Logger {
435
427
chacha. process ( & packet_decrypted, & mut decryption_tmp[ ..] ) ;
436
428
packet_decrypted = decryption_tmp;
437
429
438
- // The failing hop includes either the inbound channel to the recipient or the outbound channel
439
- // from the current hop (i.e., the next hop's inbound channel).
440
- is_from_final_node = route_hop_idx + 1 == path. hops . len ( ) ;
441
- let failing_route_hop = if is_from_final_node { route_hop } else { & path. hops [ route_hop_idx + 1 ] } ;
442
-
443
430
let err_packet = match msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & packet_decrypted) ) {
444
431
Ok ( p) => p,
445
432
Err ( _) => return
@@ -448,30 +435,58 @@ where L::Target: Logger {
448
435
let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
449
436
hmac. input ( & err_packet. encode ( ) [ 32 ..] ) ;
450
437
438
+ // The failing hop includes either the inbound channel to the recipient or the outbound channel
439
+ // from the current hop (i.e., the next hop's inbound channel).
440
+ let num_blinded_hops = path. blinded_tail . as_ref ( ) . map_or ( 0 , |t| t. hops . len ( ) ) ;
441
+ is_from_final_node = route_hop_idx + 1 == path. hops . len ( ) &&
442
+ ( path. blinded_tail . is_none ( ) || num_blinded_hops == 1 ) ;
443
+
451
444
if !fixed_time_eq ( & Hmac :: from_engine ( hmac) . into_inner ( ) , & err_packet. hmac ) { return }
452
445
let error_code_slice = match err_packet. failuremsg . get ( 0 ..2 ) {
453
446
Some ( s) => s,
454
- None => {
447
+ None if route_hop_opt . is_some ( ) => {
455
448
// Useless packet that we can't use but it passed HMAC, so it definitely came from the peer
456
449
// in question
457
450
let network_update = Some ( NetworkUpdate :: NodeFailure {
458
- node_id : route_hop . pubkey ,
451
+ node_id : route_hop_opt . as_ref ( ) . unwrap ( ) . pubkey ,
459
452
is_permanent : true ,
460
453
} ) ;
461
- let short_channel_id = Some ( route_hop . short_channel_id ) ;
454
+ let short_channel_id = Some ( route_hop_opt . as_ref ( ) . unwrap ( ) . short_channel_id ) ;
462
455
res = Some ( ( network_update, short_channel_id, !is_from_final_node) ) ;
463
456
return
457
+ } ,
458
+ None => return , // Useless packet from a blinded path hop
459
+ } ;
460
+
461
+ let error_code = u16:: from_be_bytes ( error_code_slice. try_into ( ) . expect ( "len is 2" ) ) ;
462
+ error_code_ret = Some ( error_code) ;
463
+ error_packet_ret = Some ( err_packet. failuremsg [ 2 ..] . to_vec ( ) ) ;
464
+
465
+ let route_hop = match route_hop_opt {
466
+ Some ( hop) => hop,
467
+ None => {
468
+ res = Some ( ( None , None , true ) ) ;
469
+ return
470
+ }
471
+ } ;
472
+ let failing_route_hop = if is_from_final_node { route_hop } else {
473
+ match path. hops . get ( route_hop_idx + 1 ) {
474
+ Some ( hop) => hop,
475
+ None => {
476
+ res = Some ( ( None , None , true ) ) ;
477
+ return
478
+ }
464
479
}
465
480
} ;
481
+
482
+ let amt_to_forward = htlc_msat - route_hop. fee_msat ;
483
+ htlc_msat = amt_to_forward;
484
+
466
485
const BADONION : u16 = 0x8000 ;
467
486
const PERM : u16 = 0x4000 ;
468
487
const NODE : u16 = 0x2000 ;
469
488
const UPDATE : u16 = 0x1000 ;
470
489
471
- let error_code = u16:: from_be_bytes ( error_code_slice. try_into ( ) . expect ( "len is 2" ) ) ;
472
- error_code_ret = Some ( error_code) ;
473
- error_packet_ret = Some ( err_packet. failuremsg [ 2 ..] . to_vec ( ) ) ;
474
-
475
490
let ( debug_field, debug_field_size) = errors:: get_onion_debug_field ( error_code) ;
476
491
477
492
// indicate that payment parameter has failed and no need to update Route object
0 commit comments