Skip to content

Commit 4862ae1

Browse files
authored
Merge pull request #4556 from TheBlueMatt/2026-04-over-alloc-empty-route
Avoid `Vec::with_capacity(huge)` on empty `Route`s
2 parents dc58563 + 4c398bb commit 4862ae1

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fn large_payment_metadata() {
149149
.unwrap_err();
150150
match err {
151151
APIError::InvalidRoute { err } => {
152-
assert_eq!(err, "Route size too large considering onion data");
152+
assert_eq!(err, "Route size too large (or empty) considering onion data");
153153
},
154154
_ => panic!(),
155155
}
@@ -441,7 +441,7 @@ fn blinded_path_with_custom_tlv() {
441441
.unwrap_err();
442442
match err {
443443
APIError::InvalidRoute { err } => {
444-
assert_eq!(err, "Route size too large considering onion data");
444+
assert_eq!(err, "Route size too large (or empty) considering onion data");
445445
},
446446
_ => panic!(),
447447
}

lightning/src/ln/onion_utils.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,10 @@ fn construct_onion_packet_with_init_noise<HD: Writeable, P: Packet>(
832832
mut payloads: Vec<HD>, onion_keys: Vec<OnionKeys>, mut packet_data: P::Data,
833833
associated_data: Option<&PaymentHash>,
834834
) -> Result<P, ()> {
835+
if payloads.is_empty() {
836+
return Err(());
837+
}
838+
835839
let filler = {
836840
let packet_data = packet_data.as_mut();
837841
const ONION_HOP_DATA_LEN: usize = 65; // We may decrease this eventually after TLV is common
@@ -2682,7 +2686,7 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
26822686
None,
26832687
)
26842688
.map_err(|_| APIError::InvalidRoute {
2685-
err: "Route size too large considering onion data".to_owned(),
2689+
err: "Route size too large (or empty) considering onion data".to_owned(),
26862690
})?;
26872691

26882692
(&trampoline_outer_onion, Some(trampoline_packet))
@@ -2706,7 +2710,7 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
27062710
let onion_keys = construct_onion_keys(&secp_ctx, &path, session_priv);
27072711
let onion_packet = construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash)
27082712
.map_err(|_| APIError::InvalidRoute {
2709-
err: "Route size too large considering onion data".to_owned(),
2713+
err: "Route size too large (or empty) considering onion data".to_owned(),
27102714
})?;
27112715
Ok((onion_packet, htlc_msat, htlc_cltv))
27122716
}
@@ -4104,4 +4108,33 @@ mod tests {
41044108

41054109
assert_eq!(buffer.len(), 65535);
41064110
}
4111+
4112+
#[test]
4113+
fn create_payment_onion_fails_for_empty_route() {
4114+
let secp_ctx = Secp256k1::new();
4115+
let session_priv = get_test_session_key();
4116+
let recipient_onion = RecipientOnionFields::spontaneous_empty(1000);
4117+
let payment_hash = PaymentHash([0; 32]);
4118+
let empty_path = Path { hops: vec![], blinded_tail: None };
4119+
4120+
let err = super::create_payment_onion(
4121+
&secp_ctx,
4122+
&empty_path,
4123+
&session_priv,
4124+
&recipient_onion,
4125+
100,
4126+
&payment_hash,
4127+
&None,
4128+
None,
4129+
[0; 32],
4130+
)
4131+
.unwrap_err();
4132+
4133+
match err {
4134+
APIError::InvalidRoute { err } => {
4135+
assert_eq!(err, "Route size too large (or empty) considering onion data");
4136+
},
4137+
_ => panic!("Expected InvalidRoute error, got {:?}", err),
4138+
}
4139+
}
41074140
}

0 commit comments

Comments
 (0)