Skip to content

Commit 19a5ea5

Browse files
committed
Use a single pre-allocated vec to build the failure packet.
Improve efficiency by not utilizing multiple vecs.
1 parent cf1cd5d commit 19a5ea5

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use crate::types::features::{ChannelFeatures, NodeFeatures};
2222
use crate::types::payment::{PaymentHash, PaymentPreimage};
2323
use crate::util::errors::{self, APIError};
2424
use crate::util::logger::Logger;
25-
use crate::util::ser::{LengthCalculatingWriter, Readable, ReadableArgs, Writeable, Writer};
25+
use crate::util::ser::{
26+
LengthCalculatingWriter, Readable, ReadableArgs, VecWriter, Writeable, Writer,
27+
};
2628

2729
use bitcoin::hashes::cmp::fixed_time_eq;
2830
use bitcoin::hashes::hmac::{Hmac, HmacEngine};
@@ -892,27 +894,38 @@ fn build_unencrypted_failure_packet(
892894
assert_eq!(shared_secret.len(), 32);
893895
assert!(failure_data.len() <= 256 - 2);
894896

895-
let um = gen_um_from_shared_secret(&shared_secret);
897+
// Failure len is 2 bytes type plus the data.
898+
let failure_len = 2 + failure_data.len();
896899

897-
let failuremsg = {
898-
let mut res = Vec::with_capacity(2 + failure_data.len());
899-
res.push(((failure_type >> 8) & 0xff) as u8);
900-
res.push(((failure_type >> 0) & 0xff) as u8);
901-
res.extend_from_slice(&failure_data[..]);
902-
res
903-
};
904-
let pad = {
905-
let mut res = Vec::with_capacity(256 - 2 - failure_data.len());
906-
res.resize(256 - 2 - failure_data.len(), 0);
907-
res
908-
};
909-
let mut packet = msgs::DecodedOnionErrorPacket { hmac: [0; 32], failuremsg, pad };
900+
let pad_len = 256 - failure_len;
901+
902+
// Total len is a 32 bytes HMAC, 2 bytes failure len, failure, 2 bytes pad len and pad.
903+
let total_len = 32 + 2 + failure_len + 2 + pad_len;
910904

905+
let mut writer = VecWriter(Vec::with_capacity(total_len));
906+
907+
// Reserve space for the HMAC.
908+
writer.0.extend_from_slice(&[0; 32]);
909+
910+
// Write failure len, type and data.
911+
(failure_len as u16).write(&mut writer).unwrap();
912+
failure_type.write(&mut writer).unwrap();
913+
writer.0.extend_from_slice(&failure_data[..]);
914+
915+
// Write pad len and resize to match padding.
916+
(pad_len as u16).write(&mut writer).unwrap();
917+
writer.0.resize(total_len, 0);
918+
919+
let mut data = writer.0;
920+
921+
// Calculate and store HMAC.
922+
let um = gen_um_from_shared_secret(&shared_secret);
911923
let mut hmac = HmacEngine::<Sha256>::new(&um);
912-
hmac.input(&packet.encode()[32..]);
913-
packet.hmac = Hmac::from_engine(hmac).to_byte_array();
924+
hmac.input(&data[32..]);
925+
let hmac = Hmac::from_engine(hmac).to_byte_array();
926+
data[..32].copy_from_slice(&hmac);
914927

915-
OnionErrorPacket { data: packet.encode(), attribution_data: None }
928+
OnionErrorPacket { data, attribution_data: None }
916929
}
917930

918931
pub(super) fn build_failure_packet(

0 commit comments

Comments
 (0)