Skip to content

Commit ec8edf7

Browse files
Parse onion error codes that occurred within blinded paths
1 parent f7825ba commit ec8edf7

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

lightning/src/ln/onion_utils.rs

+33-21
Original file line numberDiff line numberDiff line change
@@ -409,18 +409,10 @@ where L::Target: Logger {
409409

410410
// Handle packed channel/node updates for passing back for the route handler
411411
construct_onion_keys_callback(secp_ctx, &path, session_priv,
412-
|shared_secret, _, _, route_hop_opt, route_hop_idx|
412+
|shared_secret, _, pubkey, route_hop_opt, route_hop_idx|
413413
{
414414
if res.is_some() { return; }
415415

416-
let route_hop = match route_hop_opt {
417-
Some(hop) => hop,
418-
None => return,
419-
};
420-
421-
let amt_to_forward = htlc_msat - route_hop.fee_msat;
422-
htlc_msat = amt_to_forward;
423-
424416
let ammag = gen_ammag_from_shared_secret(shared_secret.as_ref());
425417

426418
let mut decryption_tmp = Vec::with_capacity(packet_decrypted.len());
@@ -429,11 +421,6 @@ where L::Target: Logger {
429421
chacha.process(&packet_decrypted, &mut decryption_tmp[..]);
430422
packet_decrypted = decryption_tmp;
431423

432-
// The failing hop includes either the inbound channel to the recipient or the outbound channel
433-
// from the current hop (i.e., the next hop's inbound channel).
434-
is_from_final_node = route_hop_idx + 1 == path.hops.len();
435-
let failing_route_hop = if is_from_final_node { route_hop } else { &path.hops[route_hop_idx + 1] };
436-
437424
let err_packet = match msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
438425
Ok(p) => p,
439426
Err(_) => return
@@ -445,27 +432,52 @@ where L::Target: Logger {
445432
if !fixed_time_eq(&Hmac::from_engine(hmac).into_inner(), &err_packet.hmac) { return }
446433
let error_code_slice = match err_packet.failuremsg.get(0..2) {
447434
Some(s) => s,
448-
None => {
435+
None if route_hop_opt.is_some() => {
449436
// Useless packet that we can't use but it passed HMAC, so it definitely came from the peer
450437
// in question
451438
let network_update = Some(NetworkUpdate::NodeFailure {
452-
node_id: route_hop.pubkey,
439+
node_id: pubkey,
453440
is_permanent: true,
454441
});
455-
let short_channel_id = Some(route_hop.short_channel_id);
442+
let short_channel_id = Some(route_hop_opt.as_ref().unwrap().short_channel_id);
456443
res = Some((network_update, short_channel_id, !is_from_final_node));
457444
return
445+
},
446+
None => return, // Useless packet from a blinded path hop
447+
};
448+
449+
let error_code = u16::from_be_bytes(error_code_slice.try_into().expect("len is 2"));
450+
error_code_ret = Some(error_code);
451+
error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
452+
453+
let route_hop = match route_hop_opt {
454+
Some(hop) => hop,
455+
None => {
456+
res = Some((None, None, true));
457+
return
458+
}
459+
};
460+
let amt_to_forward = htlc_msat - route_hop.fee_msat;
461+
htlc_msat = amt_to_forward;
462+
463+
// The failing hop includes either the inbound channel to the recipient or the outbound channel
464+
// from the current hop (i.e., the next hop's inbound channel).
465+
is_from_final_node = route_hop_idx + 1 == path.hops.len() && path.blinded_tail.is_none();
466+
let failing_route_hop = if is_from_final_node { route_hop } else {
467+
match path.hops.get(route_hop_idx + 1) {
468+
Some(hop) => hop,
469+
None => {
470+
res = Some((None, None, true));
471+
return
472+
}
458473
}
459474
};
475+
460476
const BADONION: u16 = 0x8000;
461477
const PERM: u16 = 0x4000;
462478
const NODE: u16 = 0x2000;
463479
const UPDATE: u16 = 0x1000;
464480

465-
let error_code = u16::from_be_bytes(error_code_slice.try_into().expect("len is 2"));
466-
error_code_ret = Some(error_code);
467-
error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
468-
469481
let (debug_field, debug_field_size) = errors::get_onion_debug_field(error_code);
470482

471483
// indicate that payment parameter has failed and no need to update Route object

0 commit comments

Comments
 (0)