]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Factor invoice requests into payment path length limiting
authorValentine Wallace <vwallace@protonmail.com>
Wed, 18 Sep 2024 15:27:09 +0000 (11:27 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Wed, 30 Oct 2024 20:17:59 +0000 (16:17 -0400)
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.

lightning/src/ln/onion_utils.rs
lightning/src/ln/outbound_payment.rs
lightning/src/routing/router.rs

index 3757d67732072b2b3f49bd33badf1bc9cedb846a..960209c0e0a384301f4843a03f5bd3495ccaabd9 100644 (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())
index e7d32f9f8e1c3cef6315b5ded0d681dc17aef96c..4ba89ea993d39cc21c90957e13e819c591422332 100644 (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,
                )?;
 
index 4c01bdcc4c031af1e7051ea6eda7053f8ad72a8e..b91b1b47d6ef3da07573f60d2480be73970a05a3 100644 (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
                )
        }
 }