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.
This commit is contained in:
Valentine Wallace 2023-09-14 11:46:02 -04:00
parent 5f5119fa3d
commit 9df61dc0b8
No known key found for this signature in database
GPG key ID: FD3E106A2CE099B4

View file

@ -481,6 +481,26 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
},
};
// The failing hop includes either the inbound channel to the recipient or the outbound channel
// from the current hop (i.e., the next hop's inbound channel).
let num_blinded_hops = path.blinded_tail.as_ref().map_or(0, |bt| bt.hops.len());
// For 1-hop blinded paths, the final `path.hops` entry is the recipient.
is_from_final_node = route_hop_idx + 1 == path.hops.len() && num_blinded_hops <= 1;
let failing_route_hop = if is_from_final_node { route_hop } else {
match path.hops.get(route_hop_idx + 1) {
Some(hop) => hop,
None => {
// The failing hop is within a multi-hop blinded path.
error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
error_packet_ret = Some(vec![0; 32]);
res = Some(FailureLearnings {
network_update: None, short_channel_id: None, payment_failed_permanently: false
});
return
}
}
};
let amt_to_forward = htlc_msat - route_hop.fee_msat;
htlc_msat = amt_to_forward;
@ -492,11 +512,6 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
chacha.process(&packet_decrypted, &mut decryption_tmp[..]);
packet_decrypted = decryption_tmp;
// The failing hop includes either the inbound channel to the recipient or the outbound channel
// from the current hop (i.e., the next hop's inbound channel).
is_from_final_node = route_hop_idx + 1 == path.hops.len();
let failing_route_hop = if is_from_final_node { route_hop } else { &path.hops[route_hop_idx + 1] };
let err_packet = match msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
Ok(p) => p,
Err(_) => return