Skip to content

Commit 6b5df57

Browse files
committed
Make process_onion_failure iterate over Vec
In an upcoming commit, we will need to decrypt error onions constructed from multiple session_privs. In order to simplify the code legibility, we move from a single-iteration model to one where we first aggregate the shared secrets, and then use them for the error decryption.
1 parent 00ee0ef commit 6b5df57

File tree

1 file changed

+34
-37
lines changed

1 file changed

+34
-37
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -965,44 +965,48 @@ where
965965
}
966966
let mut res: Option<FailureLearnings> = None;
967967
let mut htlc_msat = *first_hop_htlc_msat;
968-
let mut error_code_ret = None;
969-
let mut error_packet_ret = None;
968+
let mut _error_code_ret = None;
969+
let mut _error_packet_ret = None;
970970
let mut is_from_final_node = false;
971971

972972
const BADONION: u16 = 0x8000;
973973
const PERM: u16 = 0x4000;
974974
const NODE: u16 = 0x2000;
975975
const UPDATE: u16 = 0x1000;
976976

977-
// Handle packed channel/node updates for passing back for the route handler
978-
let callback = |shared_secret: SharedSecret,
979-
_,
980-
_,
981-
route_hop_opt: Option<&RouteHop>,
982-
route_hop_idx| {
983-
if res.is_some() {
984-
return;
985-
}
977+
let num_blinded_hops = path.blinded_tail.as_ref().map_or(0, |bt| bt.hops.len());
978+
let mut onion_keys = Vec::with_capacity(path.hops.len() + num_blinded_hops);
979+
construct_onion_keys_generic_callback(
980+
secp_ctx,
981+
&path.hops,
982+
path.blinded_tail.as_ref(),
983+
session_priv,
984+
|shared_secret, _, _, route_hop_option: Option<&RouteHop>, _| {
985+
onion_keys.push((route_hop_option.cloned(), shared_secret))
986+
},
987+
)
988+
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
986989

987-
let route_hop = match route_hop_opt {
990+
// Handle packed channel/node updates for passing back for the route handler
991+
for (route_hop_idx, (route_hop_option, shared_secret)) in onion_keys.into_iter().enumerate() {
992+
let route_hop = match route_hop_option.as_ref() {
988993
Some(hop) => hop,
989994
None => {
990995
// Got an error from within a blinded route.
991-
error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
992-
error_packet_ret = Some(vec![0; 32]);
996+
_error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
997+
_error_packet_ret = Some(vec![0; 32]);
993998
res = Some(FailureLearnings {
994999
network_update: None,
9951000
short_channel_id: None,
9961001
payment_failed_permanently: false,
9971002
failed_within_blinded_path: true,
9981003
});
999-
return;
1004+
break;
10001005
},
10011006
};
10021007

10031008
// The failing hop includes either the inbound channel to the recipient or the outbound channel
10041009
// from the current hop (i.e., the next hop's inbound channel).
1005-
let num_blinded_hops = path.blinded_tail.as_ref().map_or(0, |bt| bt.hops.len());
10061010
// For 1-hop blinded paths, the final `path.hops` entry is the recipient.
10071011
is_from_final_node = route_hop_idx + 1 == path.hops.len() && num_blinded_hops <= 1;
10081012
let failing_route_hop = if is_from_final_node {
@@ -1014,8 +1018,8 @@ where
10141018
// The failing hop is within a multi-hop blinded path.
10151019
#[cfg(not(test))]
10161020
{
1017-
error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
1018-
error_packet_ret = Some(vec![0; 32]);
1021+
_error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
1022+
_error_packet_ret = Some(vec![0; 32]);
10191023
}
10201024
#[cfg(test)]
10211025
{
@@ -1026,10 +1030,10 @@ where
10261030
&encrypted_packet.data,
10271031
))
10281032
.unwrap();
1029-
error_code_ret = Some(u16::from_be_bytes(
1033+
_error_code_ret = Some(u16::from_be_bytes(
10301034
err_packet.failuremsg.get(0..2).unwrap().try_into().unwrap(),
10311035
));
1032-
error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
1036+
_error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
10331037
}
10341038

10351039
res = Some(FailureLearnings {
@@ -1038,7 +1042,7 @@ where
10381042
payment_failed_permanently: false,
10391043
failed_within_blinded_path: true,
10401044
});
1041-
return;
1045+
break;
10421046
},
10431047
}
10441048
};
@@ -1053,7 +1057,7 @@ where
10531057
hmac.input(&encrypted_packet.data[32..]);
10541058

10551059
if !fixed_time_eq(&Hmac::from_engine(hmac).to_byte_array(), &encrypted_packet.data[..32]) {
1056-
return;
1060+
continue;
10571061
}
10581062

10591063
let err_packet =
@@ -1073,7 +1077,7 @@ where
10731077
payment_failed_permanently: is_from_final_node,
10741078
failed_within_blinded_path: false,
10751079
});
1076-
return;
1080+
break;
10771081
},
10781082
};
10791083

@@ -1095,13 +1099,13 @@ where
10951099
payment_failed_permanently: is_from_final_node,
10961100
failed_within_blinded_path: false,
10971101
});
1098-
return;
1102+
break;
10991103
},
11001104
};
11011105

11021106
let error_code = u16::from_be_bytes(error_code_slice.try_into().expect("len is 2"));
1103-
error_code_ret = Some(error_code);
1104-
error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
1107+
_error_code_ret = Some(error_code);
1108+
_error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
11051109

11061110
let (debug_field, debug_field_size) = errors::get_onion_debug_field(error_code);
11071111

@@ -1212,16 +1216,9 @@ where
12121216
description
12131217
);
12141218
}
1215-
};
12161219

1217-
construct_onion_keys_generic_callback(
1218-
secp_ctx,
1219-
&path.hops,
1220-
path.blinded_tail.as_ref(),
1221-
session_priv,
1222-
callback,
1223-
)
1224-
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
1220+
break;
1221+
}
12251222

12261223
if let Some(FailureLearnings {
12271224
network_update,
@@ -1236,9 +1233,9 @@ where
12361233
payment_failed_permanently,
12371234
failed_within_blinded_path,
12381235
#[cfg(any(test, feature = "_test_utils"))]
1239-
onion_error_code: error_code_ret,
1236+
onion_error_code: _error_code_ret,
12401237
#[cfg(any(test, feature = "_test_utils"))]
1241-
onion_error_data: error_packet_ret,
1238+
onion_error_data: _error_packet_ret,
12421239
}
12431240
} else {
12441241
// only not set either packet unparseable or hmac does not match with any

0 commit comments

Comments
 (0)