Skip to content

Commit 9df61dc

Browse files
Fix PaymentPathFailed::payment_failed_permanently on blinded path fail
Previously this value would be incorrectly set to true because we wouldn't account for blinded hops when determining if we were processing the last hop's failure packet.
1 parent 5f5119f commit 9df61dc

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,26 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
481481
},
482482
};
483483

484+
// The failing hop includes either the inbound channel to the recipient or the outbound channel
485+
// from the current hop (i.e., the next hop's inbound channel).
486+
let num_blinded_hops = path.blinded_tail.as_ref().map_or(0, |bt| bt.hops.len());
487+
// For 1-hop blinded paths, the final `path.hops` entry is the recipient.
488+
is_from_final_node = route_hop_idx + 1 == path.hops.len() && num_blinded_hops <= 1;
489+
let failing_route_hop = if is_from_final_node { route_hop } else {
490+
match path.hops.get(route_hop_idx + 1) {
491+
Some(hop) => hop,
492+
None => {
493+
// The failing hop is within a multi-hop blinded path.
494+
error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
495+
error_packet_ret = Some(vec![0; 32]);
496+
res = Some(FailureLearnings {
497+
network_update: None, short_channel_id: None, payment_failed_permanently: false
498+
});
499+
return
500+
}
501+
}
502+
};
503+
484504
let amt_to_forward = htlc_msat - route_hop.fee_msat;
485505
htlc_msat = amt_to_forward;
486506

@@ -492,11 +512,6 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
492512
chacha.process(&packet_decrypted, &mut decryption_tmp[..]);
493513
packet_decrypted = decryption_tmp;
494514

495-
// The failing hop includes either the inbound channel to the recipient or the outbound channel
496-
// from the current hop (i.e., the next hop's inbound channel).
497-
is_from_final_node = route_hop_idx + 1 == path.hops.len();
498-
let failing_route_hop = if is_from_final_node { route_hop } else { &path.hops[route_hop_idx + 1] };
499-
500515
let err_packet = match msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
501516
Ok(p) => p,
502517
Err(_) => return

0 commit comments

Comments
 (0)