Skip to content

Commit d2ad2b9

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 4c43a5b commit d2ad2b9

File tree

1 file changed

+33
-30
lines changed

1 file changed

+33
-30
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -965,34 +965,46 @@ 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+
let mut onion_keys = Vec::with_capacity(path.hops.len());
978+
construct_onion_keys_generic_callback(
979+
secp_ctx,
980+
&path.hops,
981+
path.blinded_tail.as_ref(),
982+
session_priv,
983+
|shared_secret, _, _, route_hop_option: Option<&RouteHop>, _| {
984+
onion_keys.push((route_hop_option.cloned(), shared_secret))
985+
},
986+
)
987+
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
988+
977989
// Handle packed channel/node updates for passing back for the route handler
978-
let callback = |shared_secret, _, _, route_hop_opt: Option<&RouteHop>, route_hop_idx| {
990+
for (route_hop_idx, (route_hop_option, shared_secret)) in onion_keys.into_iter().enumerate() {
979991
if res.is_some() {
980-
return;
992+
break;
981993
}
982994

983-
let route_hop = match route_hop_opt {
995+
let route_hop = match route_hop_option.as_ref() {
984996
Some(hop) => hop,
985997
None => {
986998
// Got an error from within a blinded route.
987-
error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
988-
error_packet_ret = Some(vec![0; 32]);
999+
_error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
1000+
_error_packet_ret = Some(vec![0; 32]);
9891001
res = Some(FailureLearnings {
9901002
network_update: None,
9911003
short_channel_id: None,
9921004
payment_failed_permanently: false,
9931005
failed_within_blinded_path: true,
9941006
});
995-
return;
1007+
break;
9961008
},
9971009
};
9981010

@@ -1010,8 +1022,8 @@ where
10101022
// The failing hop is within a multi-hop blinded path.
10111023
#[cfg(not(test))]
10121024
{
1013-
error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
1014-
error_packet_ret = Some(vec![0; 32]);
1025+
_error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding
1026+
_error_packet_ret = Some(vec![0; 32]);
10151027
}
10161028
#[cfg(test)]
10171029
{
@@ -1022,10 +1034,10 @@ where
10221034
&encrypted_packet,
10231035
))
10241036
.unwrap();
1025-
error_code_ret = Some(u16::from_be_bytes(
1037+
_error_code_ret = Some(u16::from_be_bytes(
10261038
err_packet.failuremsg.get(0..2).unwrap().try_into().unwrap(),
10271039
));
1028-
error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
1040+
_error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
10291041
}
10301042

10311043
res = Some(FailureLearnings {
@@ -1034,7 +1046,7 @@ where
10341046
payment_failed_permanently: false,
10351047
failed_within_blinded_path: true,
10361048
});
1037-
return;
1049+
break;
10381050
},
10391051
}
10401052
};
@@ -1049,7 +1061,7 @@ where
10491061
hmac.input(&encrypted_packet[32..]);
10501062

10511063
if !fixed_time_eq(&Hmac::from_engine(hmac).to_byte_array(), &encrypted_packet[..32]) {
1052-
return;
1064+
continue;
10531065
}
10541066

10551067
let err_packet =
@@ -1069,7 +1081,7 @@ where
10691081
payment_failed_permanently: is_from_final_node,
10701082
failed_within_blinded_path: false,
10711083
});
1072-
return;
1084+
break;
10731085
},
10741086
};
10751087

@@ -1091,13 +1103,13 @@ where
10911103
payment_failed_permanently: is_from_final_node,
10921104
failed_within_blinded_path: false,
10931105
});
1094-
return;
1106+
break;
10951107
},
10961108
};
10971109

10981110
let error_code = u16::from_be_bytes(error_code_slice.try_into().expect("len is 2"));
1099-
error_code_ret = Some(error_code);
1100-
error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
1111+
_error_code_ret = Some(error_code);
1112+
_error_packet_ret = Some(err_packet.failuremsg[2..].to_vec());
11011113

11021114
let (debug_field, debug_field_size) = errors::get_onion_debug_field(error_code);
11031115

@@ -1208,16 +1220,7 @@ where
12081220
description
12091221
);
12101222
}
1211-
};
1212-
1213-
construct_onion_keys_generic_callback(
1214-
secp_ctx,
1215-
&path.hops,
1216-
path.blinded_tail.as_ref(),
1217-
session_priv,
1218-
callback,
1219-
)
1220-
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
1223+
}
12211224

12221225
if let Some(FailureLearnings {
12231226
network_update,
@@ -1232,9 +1235,9 @@ where
12321235
payment_failed_permanently,
12331236
failed_within_blinded_path,
12341237
#[cfg(any(test, feature = "_test_utils"))]
1235-
onion_error_code: error_code_ret,
1238+
onion_error_code: _error_code_ret,
12361239
#[cfg(any(test, feature = "_test_utils"))]
1237-
onion_error_data: error_packet_ret,
1240+
onion_error_data: _error_packet_ret,
12381241
}
12391242
} else {
12401243
// only not set either packet unparseable or hmac does not match with any

0 commit comments

Comments
 (0)