From: Valentine Wallace Date: Wed, 18 Sep 2024 15:27:09 +0000 (-0400) Subject: Factor invoice requests into payment path length limiting X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=34e710edd1f7c673bccdcc174620b74bb6b496b6;p=rust-lightning 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. --- diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 3757d6773..960209c0e 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -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, best_block_height: u32, + keysend_preimage: Option, 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()) diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index e7d32f9f8..4ba89ea99 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -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( - &self, payment_id: PaymentId, payment_hash: PaymentHash, - recipient_onion: &RecipientOnionFields, keysend_preimage: Option, + &self, payment_id: PaymentId, payment_hash: PaymentHash, recipient_onion: &RecipientOnionFields, + keysend_preimage: Option, invoice_request: Option<&InvoiceRequest>, route_params: &mut RouteParameters, router: &R, first_hops: &Vec, inflight_htlcs: &IH, node_signer: &NS, best_block_height: u32, logger: &L, ) -> Result @@ -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, )?; diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 4c01bdcc4..b91b1b47d 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -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 ) } }