Factor invoice requests into payment path length limiting

Async payments include the original invoice request in the payment onion.
Since invreqs may include blinded paths, it's important to factor them into our
max path length calculations since they may take up a significant portion of
the 1300-byte onion.
This commit is contained in:
Valentine Wallace 2024-09-18 11:27:09 -04:00
parent d574de95f5
commit 34e710edd1
No known key found for this signature in database
GPG key ID: FD3E106A2CE099B4
3 changed files with 13 additions and 10 deletions

View file

@ -320,7 +320,8 @@ pub(crate) const MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY: u64 = 100_000_000;
pub(crate) fn set_max_path_length(
route_params: &mut RouteParameters, recipient_onion: &RecipientOnionFields,
keysend_preimage: Option<PaymentPreimage>, best_block_height: u32,
keysend_preimage: Option<PaymentPreimage>, invoice_request: Option<&InvoiceRequest>,
best_block_height: u32,
) -> Result<(), ()> {
const PAYLOAD_HMAC_LEN: usize = 32;
let unblinded_intermed_payload_len = msgs::OutboundOnionPayload::Forward {
@ -367,7 +368,7 @@ pub(crate) fn set_max_path_length(
&recipient_onion,
best_block_height,
&keysend_preimage,
None,
invoice_request,
|_, payload| {
num_reserved_bytes = num_reserved_bytes
.saturating_add(payload.serialized_length())

View file

@ -932,8 +932,9 @@ impl OutboundPayments {
custom_tlvs: vec![],
};
let route = match self.find_initial_route(
payment_id, payment_hash, &recipient_onion, None, &mut route_params, router,
&first_hops, &inflight_htlcs, node_signer, best_block_height, logger,
payment_id, payment_hash, &recipient_onion, keysend_preimage, invoice_request,
&mut route_params, router, &first_hops, &inflight_htlcs, node_signer, best_block_height,
logger,
) {
Ok(route) => route,
Err(e) => {
@ -1052,7 +1053,7 @@ impl OutboundPayments {
if let Err(()) = onion_utils::set_max_path_length(
&mut route_params, &RecipientOnionFields::spontaneous_empty(), Some(keysend_preimage),
best_block_height
Some(invreq), best_block_height
) {
abandon_with_entry!(entry, PaymentFailureReason::RouteNotFound);
return Err(Bolt12PaymentError::SendingFailed(RetryableSendFailure::OnionPacketSizeExceeded))
@ -1182,8 +1183,8 @@ impl OutboundPayments {
}
fn find_initial_route<R: Deref, NS: Deref, IH, L: Deref>(
&self, payment_id: PaymentId, payment_hash: PaymentHash,
recipient_onion: &RecipientOnionFields, keysend_preimage: Option<PaymentPreimage>,
&self, payment_id: PaymentId, payment_hash: PaymentHash, recipient_onion: &RecipientOnionFields,
keysend_preimage: Option<PaymentPreimage>, invoice_request: Option<&InvoiceRequest>,
route_params: &mut RouteParameters, router: &R, first_hops: &Vec<ChannelDetails>,
inflight_htlcs: &IH, node_signer: &NS, best_block_height: u32, logger: &L,
) -> Result<Route, RetryableSendFailure>
@ -1202,7 +1203,7 @@ impl OutboundPayments {
}
onion_utils::set_max_path_length(
route_params, recipient_onion, keysend_preimage, best_block_height
route_params, recipient_onion, keysend_preimage, invoice_request, best_block_height
)
.map_err(|()| {
log_error!(logger, "Can't construct an onion packet without exceeding 1300-byte onion \
@ -1250,7 +1251,7 @@ impl OutboundPayments {
SP: Fn(SendAlongPathArgs) -> Result<(), APIError>,
{
let route = self.find_initial_route(
payment_id, payment_hash, &recipient_onion, keysend_preimage, &mut route_params, router,
payment_id, payment_hash, &recipient_onion, keysend_preimage, None, &mut route_params, router,
&first_hops, &inflight_htlcs, node_signer, best_block_height, logger,
)?;

View file

@ -613,8 +613,9 @@ impl RouteParameters {
&mut self, recipient_onion: &RecipientOnionFields, is_keysend: bool, best_block_height: u32
) -> Result<(), ()> {
let keysend_preimage_opt = is_keysend.then(|| PaymentPreimage([42; 32]));
// TODO: no way to account for the invoice request here yet
onion_utils::set_max_path_length(
self, recipient_onion, keysend_preimage_opt, best_block_height
self, recipient_onion, keysend_preimage_opt, None, best_block_height
)
}
}