Skip to content

Commit fbd44c7

Browse files
f move method to onion_utils + use build_payloads_callback
1 parent 32c52f2 commit fbd44c7

File tree

3 files changed

+82
-76
lines changed

3 files changed

+82
-76
lines changed

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,9 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
282282

283283
let amt_msat = 5000;
284284
let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[3], Some(amt_msat), None);
285-
let mut route_params = get_blinded_route_parameters(amt_msat, payment_secret, 1, 1_0000_0000,
285+
let route_params = get_blinded_route_parameters(amt_msat, payment_secret, 1, 1_0000_0000,
286286
nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(),
287287
&[&chan_upd_1_2, &chan_upd_2_3], &chanmon_cfgs[3].keys_manager);
288-
route_params.payment_params.max_intermediate_hops = 17;
289288

290289
let route = get_route(&nodes[0], &route_params).unwrap();
291290
node_cfgs[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
@@ -805,7 +804,6 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
805804
let mut route_params = get_blinded_route_parameters(amt_msat, payment_secret, 1, 1_0000_0000,
806805
nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(), &[&chan_upd_1_2],
807806
&chanmon_cfgs[2].keys_manager);
808-
route_params.payment_params.max_intermediate_hops = 18;
809807

810808
let route = if check == ReceiveCheckFail::ProcessPendingHTLCsCheck {
811809
let mut route = get_route(&nodes[0], &route_params).unwrap();

lightning/src/ln/onion_utils.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use crate::blinded_path::BlindedHop;
1111
use crate::crypto::chacha20::ChaCha20;
1212
use crate::crypto::streams::ChaChaReader;
1313
use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields};
14+
use crate::ln::features::{ChannelFeatures, NodeFeatures};
1415
use crate::ln::msgs;
1516
use crate::ln::wire::Encode;
1617
use crate::ln::{PaymentHash, PaymentPreimage};
1718
use crate::routing::gossip::NetworkUpdate;
18-
use crate::routing::router::{Path, RouteHop};
19+
use crate::routing::router::{Path, Payee, RouteHop, RouteParameters, MAX_PATH_LENGTH_ESTIMATE};
1920
use crate::sign::NodeSigner;
2021
use crate::util::errors::{self, APIError};
2122
use crate::util::logger::Logger;
@@ -310,6 +311,81 @@ pub(super) fn build_onion_payloads<'a>(
310311
Ok((res, value_msat, cltv))
311312
}
312313

314+
pub(crate) fn set_max_path_length(
315+
route_params: &mut RouteParameters, recipient_onion: &RecipientOnionFields,
316+
keysend_preimage: Option<PaymentPreimage>, best_block_height: u32,
317+
) -> Result<(), ()> {
318+
const PAYLOAD_HMAC_LEN: usize = 32;
319+
let unblinded_intermed_payload_len = msgs::OutboundOnionPayload::Forward {
320+
short_channel_id: 42,
321+
amt_to_forward: u64::max_value(),
322+
outgoing_cltv_value: u32::max_value(),
323+
}
324+
.serialized_length()
325+
.saturating_add(PAYLOAD_HMAC_LEN);
326+
327+
let (cltv_expiry_delta, num_reserved_hops, blinded_tail_opt) =
328+
match &route_params.payment_params.payee {
329+
Payee::Blinded { route_hints, .. } => {
330+
let (blinded_payinfo, largest_path) = route_hints
331+
.iter()
332+
.max_by(|(_, path_a), (_, path_b)| {
333+
path_a.serialized_length().cmp(&path_b.serialized_length())
334+
})
335+
.ok_or(())?;
336+
let blinded_tail = BlindedTailHopIter {
337+
hops: largest_path.blinded_hops.iter(),
338+
blinding_point: largest_path.blinding_point,
339+
final_value_msat: route_params.final_value_msat,
340+
excess_final_cltv_expiry_delta: 0,
341+
};
342+
(
343+
blinded_payinfo.cltv_expiry_delta as u32,
344+
largest_path.blinded_hops.len(),
345+
Some(blinded_tail),
346+
)
347+
},
348+
Payee::Clear { final_cltv_expiry_delta, .. } => {
349+
(*final_cltv_expiry_delta, 1 as usize, None)
350+
},
351+
};
352+
353+
let unblinded_route_hop = RouteHop {
354+
pubkey: PublicKey::from_slice(&[2; 33]).unwrap(),
355+
node_features: NodeFeatures::empty(),
356+
short_channel_id: 42,
357+
channel_features: ChannelFeatures::empty(),
358+
fee_msat: route_params.final_value_msat,
359+
cltv_expiry_delta,
360+
maybe_announced_channel: false,
361+
};
362+
let mut num_reserved_bytes: usize = 0;
363+
let build_payloads_res = build_onion_payloads_callback(
364+
core::iter::once(&unblinded_route_hop),
365+
blinded_tail_opt,
366+
route_params.final_value_msat,
367+
&recipient_onion,
368+
best_block_height,
369+
&keysend_preimage,
370+
|_, payload| {
371+
num_reserved_bytes = num_reserved_bytes
372+
.saturating_add(payload.serialized_length())
373+
.saturating_add(PAYLOAD_HMAC_LEN);
374+
},
375+
);
376+
debug_assert!(build_payloads_res.is_ok());
377+
378+
let max_path_length = 1300usize
379+
.checked_sub(num_reserved_bytes)
380+
.map(|p| p / unblinded_intermed_payload_len)
381+
.and_then(|l| u8::try_from(l.saturating_add(num_reserved_hops)).ok())
382+
.ok_or(())?;
383+
384+
route_params.payment_params.max_path_length =
385+
core::cmp::min(max_path_length, MAX_PATH_LENGTH_ESTIMATE);
386+
Ok(())
387+
}
388+
313389
/// Length of the onion data packet. Before TLV-based onions this was 20 65-byte hops, though now
314390
/// the hops can be of variable length.
315391
pub(crate) const ONION_DATA_LEN: usize = 20 * 65;

lightning/src/ln/outbound_payment.rs

Lines changed: 4 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ use crate::sign::{EntropySource, NodeSigner, Recipient};
1717
use crate::events::{self, PaymentFailureReason};
1818
use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
1919
use crate::ln::channelmanager::{ChannelDetails, EventCompletionAction, HTLCSource, PaymentId};
20-
use crate::ln::msgs;
20+
use crate::ln::onion_utils;
2121
use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
2222
use crate::offers::invoice::Bolt12Invoice;
23-
use crate::routing::router::{BlindedTail, InFlightHtlcs, MAX_PATH_LENGTH_ESTIMATE, Path, Payee, PaymentParameters, Route, RouteParameters, Router};
23+
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteParameters, Router};
2424
use crate::util::errors::APIError;
2525
use crate::util::logger::Logger;
2626
use crate::util::time::Time;
2727
#[cfg(all(feature = "std", test))]
2828
use crate::util::time::tests::SinceEpoch;
29-
use crate::util::ser::{ReadableArgs, Writeable};
29+
use crate::util::ser::ReadableArgs;
3030

3131
use core::fmt::{self, Display, Formatter};
3232
use core::ops::Deref;
@@ -914,7 +914,7 @@ impl OutboundPayments {
914914
}
915915
}
916916

917-
set_max_path_length(
917+
onion_utils::set_max_path_length(
918918
&mut route_params, &recipient_onion, keysend_preimage, best_block_height
919919
)
920920
.map_err(|()| {
@@ -1787,74 +1787,6 @@ impl OutboundPayments {
17871787
}
17881788
}
17891789

1790-
fn set_max_path_length(
1791-
route_params: &mut RouteParameters, recipient_onion: &RecipientOnionFields,
1792-
keysend_preimage: Option<PaymentPreimage>, best_block_height: u32,
1793-
) -> Result<(), ()> {
1794-
const PAYLOAD_HMAC_LEN: usize = 32;
1795-
const UNBLINDED_INTERMED_PAYLOAD_LEN: usize = PAYLOAD_HMAC_LEN
1796-
+ 1 + 1 + 8 // amt_to_forward
1797-
+ 1 + 1 + 4 // outgoing_cltv
1798-
+ 1 + 1 + 8; // short_channel_id
1799-
1800-
let num_reserved_bytes = match &route_params.payment_params.payee {
1801-
Payee::Blinded { route_hints, .. } => {
1802-
let (blinded_payinfo, largest_path) = route_hints
1803-
.iter()
1804-
.max_by(|(_, path_a), (_, path_b)|
1805-
path_a.serialized_length().cmp(&path_b.serialized_length()))
1806-
.ok_or(())?;
1807-
1808-
largest_path.blinded_hops
1809-
.iter()
1810-
.rev()
1811-
.skip(1)
1812-
.map(|bh| msgs::OutboundOnionPayload::BlindedForward {
1813-
encrypted_tlvs: &bh.encrypted_payload,
1814-
// For simplicity, always set the intro_node_blinding_point in the
1815-
// final payload.
1816-
intro_node_blinding_point: None,
1817-
})
1818-
.chain(core::iter::once(msgs::OutboundOnionPayload::BlindedReceive {
1819-
sender_intended_htlc_amt_msat: route_params.final_value_msat,
1820-
total_msat: route_params.final_value_msat,
1821-
cltv_expiry_height:
1822-
best_block_height.saturating_add(blinded_payinfo.cltv_expiry_delta as u32),
1823-
encrypted_tlvs: largest_path.blinded_hops
1824-
.last()
1825-
.map(|bh| &bh.encrypted_payload)
1826-
.unwrap_or(&Vec::new()),
1827-
intro_node_blinding_point: Some(largest_path.blinding_point),
1828-
keysend_preimage,
1829-
custom_tlvs: &recipient_onion.custom_tlvs,
1830-
}))
1831-
.map(|payload| payload.serialized_length().saturating_add(PAYLOAD_HMAC_LEN))
1832-
.fold(0, |acc: usize, payload_len| acc.saturating_add(payload_len))
1833-
},
1834-
Payee::Clear { final_cltv_expiry_delta, .. } => {
1835-
msgs::OutboundOnionPayload::Receive {
1836-
payment_data: recipient_onion.payment_secret.map(|payment_secret| {
1837-
msgs::FinalOnionHopData { payment_secret, total_msat: route_params.final_value_msat }
1838-
}),
1839-
payment_metadata: recipient_onion.payment_metadata.as_ref(),
1840-
keysend_preimage,
1841-
custom_tlvs: &recipient_onion.custom_tlvs,
1842-
sender_intended_htlc_amt_msat: route_params.final_value_msat,
1843-
cltv_expiry_height: best_block_height.saturating_add(*final_cltv_expiry_delta),
1844-
}
1845-
.serialized_length()
1846-
.saturating_add(PAYLOAD_HMAC_LEN)
1847-
}
1848-
};
1849-
let max_intermediate_unblinded_hops = 1300usize.checked_sub(num_reserved_bytes)
1850-
.map(|p| p / UNBLINDED_INTERMED_PAYLOAD_LEN)
1851-
.and_then(|l| u8::try_from(l).ok())
1852-
.ok_or(())?;
1853-
1854-
route_params.payment_params.max_intermediate_hops = core::cmp::min(max_intermediate_unblinded_hops, MAX_PATH_LENGTH_ESTIMATE);
1855-
Ok(())
1856-
}
1857-
18581790
/// Returns whether a payment with the given [`PaymentHash`] and [`PaymentId`] is, in fact, a
18591791
/// payment probe.
18601792
pub(super) fn payment_is_probe(payment_hash: &PaymentHash, payment_id: &PaymentId,

0 commit comments

Comments
 (0)