@@ -8621,8 +8621,10 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
86218621		let entropy = &*$self.entropy_source;
86228622		let secp_ctx = &$self.secp_ctx;
86238623
8624- 		let path = $self.create_blinded_path_using_absolute_expiry(OffersContext::Unknown {}, absolute_expiry)
8624+ 		let path = $self.create_blinded_paths_using_absolute_expiry(OffersContext::Unknown {}, absolute_expiry)
8625+ 			.and_then(|paths| paths.into_iter().next().ok_or(()))
86258626			.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8627+ 
86268628		let builder = OfferBuilder::deriving_signing_pubkey(
86278629			node_id, expanded_key, entropy, secp_ctx
86288630		)
@@ -8694,8 +8696,10 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
86948696		let secp_ctx = &$self.secp_ctx;
86958697
86968698		let context = OffersContext::OutboundPayment { payment_id };
8697- 		let path = $self.create_blinded_path_using_absolute_expiry(context, Some(absolute_expiry))
8699+ 		let path = $self.create_blinded_paths_using_absolute_expiry(context, Some(absolute_expiry))
8700+ 			.and_then(|paths| paths.into_iter().next().ok_or(()))
86988701			.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8702+ 
86998703		let builder = RefundBuilder::deriving_payer_id(
87008704			node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
87018705		)?
@@ -8716,6 +8720,13 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
87168720	}
87178721} }
87188722
8723+ /// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
8724+ /// along different paths.
8725+ /// Sending multiple requests increases the chances of successful delivery in case some
8726+ /// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
8727+ /// even if multiple invoices are received.
8728+ const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
8729+ 
87198730impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, L>
87208731where
87218732	M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
@@ -8819,7 +8830,7 @@ where
88198830		let invoice_request = builder.build_and_sign()?;
88208831
88218832		let context = OffersContext::OutboundPayment { payment_id };
8822- 		let reply_path  = self.create_blinded_path (context).map_err(|_| Bolt12SemanticError::MissingPaths)?;
8833+ 		let reply_paths  = self.create_blinded_paths (context).map_err(|_| Bolt12SemanticError::MissingPaths)?;
88238834
88248835		let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
88258836
@@ -8832,25 +8843,27 @@ where
88328843
88338844		let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
88348845		if !offer.paths().is_empty() {
8835- 			// Send as many invoice requests as there are paths in the offer (with an upper bound).
8836- 			// Using only one path could result in a failure if the path no longer exists. But only
8837- 			// one invoice for a given payment id will be paid, even if more than one is received.
8838- 			const REQUEST_LIMIT: usize = 10;
8839- 			for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8846+ 			reply_paths
8847+ 				.iter()
8848+ 				.flat_map(|reply_path| offer.paths().iter().map(move |path| (path, reply_path)))
8849+ 				.take(OFFERS_MESSAGE_REQUEST_LIMIT)
8850+ 				.for_each(|(path, reply_path)| {
8851+ 					let message = new_pending_onion_message(
8852+ 						OffersMessage::InvoiceRequest(invoice_request.clone()),
8853+ 						Destination::BlindedPath(path.clone()),
8854+ 						Some(reply_path.clone()),
8855+ 					);
8856+ 					pending_offers_messages.push(message);
8857+ 				});
8858+ 		} else if let Some(signing_pubkey) = offer.signing_pubkey() {
8859+ 			for reply_path in reply_paths {
88408860				let message = new_pending_onion_message(
88418861					OffersMessage::InvoiceRequest(invoice_request.clone()),
8842- 					Destination::BlindedPath(path.clone() ),
8843- 					Some(reply_path.clone() ),
8862+ 					Destination::Node(signing_pubkey ),
8863+ 					Some(reply_path),
88448864				);
88458865				pending_offers_messages.push(message);
88468866			}
8847- 		} else if let Some(signing_pubkey) = offer.signing_pubkey() {
8848- 			let message = new_pending_onion_message(
8849- 				OffersMessage::InvoiceRequest(invoice_request),
8850- 				Destination::Node(signing_pubkey),
8851- 				Some(reply_path),
8852- 			);
8853- 			pending_offers_messages.push(message);
88548867		} else {
88558868			debug_assert!(false);
88568869			return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8919,26 +8932,32 @@ where
89198932				)?;
89208933				let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
89218934				let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
8922- 				let reply_path  = self.create_blinded_path (OffersContext::Unknown {})
8935+ 				let reply_paths  = self.create_blinded_paths (OffersContext::Unknown {})
89238936					.map_err(|_| Bolt12SemanticError::MissingPaths)?;
89248937
89258938				let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
89268939				if refund.paths().is_empty() {
8927- 					let message = new_pending_onion_message(
8928- 						OffersMessage::Invoice(invoice.clone()),
8929- 						Destination::Node(refund.payer_id()),
8930- 						Some(reply_path),
8931- 					);
8932- 					pending_offers_messages.push(message);
8933- 				} else {
8934- 					for path in refund.paths() {
8940+ 					for reply_path in reply_paths {
89358941						let message = new_pending_onion_message(
89368942							OffersMessage::Invoice(invoice.clone()),
8937- 							Destination::BlindedPath(path.clone ()),
8938- 							Some(reply_path.clone() ),
8943+ 							Destination::Node(refund.payer_id ()),
8944+ 							Some(reply_path),
89398945						);
89408946						pending_offers_messages.push(message);
89418947					}
8948+ 				} else {
8949+ 					reply_paths
8950+ 						.iter()
8951+ 						.flat_map(|reply_path| refund.paths().iter().map(move |path| (path, reply_path)))
8952+ 						.take(OFFERS_MESSAGE_REQUEST_LIMIT)
8953+ 						.for_each(|(path, reply_path)| {
8954+ 							let message = new_pending_onion_message(
8955+ 								OffersMessage::Invoice(invoice.clone()),
8956+ 								Destination::BlindedPath(path.clone()),
8957+ 								Some(reply_path.clone()),
8958+ 							);
8959+ 							pending_offers_messages.push(message);
8960+ 						});
89428961				}
89438962
89448963				Ok(invoice)
@@ -9045,22 +9064,22 @@ where
90459064		inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
90469065	}
90479066
9048- 	/// Creates a blinded path  by delegating to [`MessageRouter`] based on the path's intended 
9049- 	/// lifetime.
9067+ 	/// Creates a collection of  blinded paths  by delegating to [`MessageRouter`] based on
9068+ 	/// the path's intended  lifetime.
90509069	///
90519070	/// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
90529071	/// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
90539072	/// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
9054- 	fn create_blinded_path_using_absolute_expiry (
9073+ 	fn create_blinded_paths_using_absolute_expiry (
90559074		&self, context: OffersContext, absolute_expiry: Option<Duration>,
9056- 	) -> Result<BlindedPath, ()> {
9075+ 	) -> Result<Vec< BlindedPath> , ()> {
90579076		let now = self.duration_since_epoch();
90589077		let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
90599078
90609079		if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
9061- 			self.create_compact_blinded_path (context)
9080+ 			self.create_compact_blinded_paths (context)
90629081		} else {
9063- 			self.create_blinded_path (context)
9082+ 			self.create_blinded_paths (context)
90649083		}
90659084	}
90669085
@@ -9077,10 +9096,11 @@ where
90779096		now
90789097	}
90799098
9080- 	/// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
9099+ 	/// Creates a collection of blinded paths by delegating to
9100+ 	/// [`MessageRouter::create_blinded_paths`].
90819101	///
9082- 	/// Errors if the `MessageRouter` errors or returns an empty `Vec` .
9083- 	fn create_blinded_path (&self, context: OffersContext) -> Result<BlindedPath, ()> {
9102+ 	/// Errors if the `MessageRouter` errors.
9103+ 	fn create_blinded_paths (&self, context: OffersContext) -> Result<Vec< BlindedPath> , ()> {
90849104		let recipient = self.get_our_node_id();
90859105		let secp_ctx = &self.secp_ctx;
90869106
@@ -9094,13 +9114,14 @@ where
90949114
90959115		self.router
90969116			.create_blinded_paths(recipient, MessageContext::Offers(context), peers, secp_ctx)
9097- 			.and_then(|paths| paths.into_iter().next( ).ok_or(()))
9117+ 			.and_then(|paths| (! paths.is_empty()).then(|| paths ).ok_or(()))
90989118	}
90999119
9100- 	/// Creates a blinded path by delegating to [`MessageRouter::create_compact_blinded_paths`].
9120+ 	/// Creates a collection of blinded paths by delegating to
9121+ 	/// [`MessageRouter::create_compact_blinded_paths`].
91019122	///
9102- 	/// Errors if the `MessageRouter` errors or returns an empty `Vec` .
9103- 	fn create_compact_blinded_path (&self, context: OffersContext) -> Result<BlindedPath, ()> {
9123+ 	/// Errors if the `MessageRouter` errors.
9124+ 	fn create_compact_blinded_paths (&self, context: OffersContext) -> Result<Vec< BlindedPath> , ()> {
91049125		let recipient = self.get_our_node_id();
91059126		let secp_ctx = &self.secp_ctx;
91069127
@@ -9121,7 +9142,7 @@ where
91219142
91229143		self.router
91239144			.create_compact_blinded_paths(recipient, MessageContext::Offers(context), peers, secp_ctx)
9124- 			.and_then(|paths| paths.into_iter().next( ).ok_or(()))
9145+ 			.and_then(|paths| (! paths.is_empty()).then(|| paths ).ok_or(()))
91259146	}
91269147
91279148	/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
0 commit comments