@@ -8376,8 +8376,10 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
83768376 let entropy = &*$self.entropy_source;
83778377 let secp_ctx = &$self.secp_ctx;
83788378
8379- let path = $self.create_blinded_path_using_absolute_expiry(absolute_expiry)
8379+ let path = $self.create_blinded_paths_using_absolute_expiry(absolute_expiry)
8380+ .and_then(|paths| paths.into_iter().next().ok_or(()))
83808381 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8382+
83818383 let builder = OfferBuilder::deriving_signing_pubkey(
83828384 node_id, expanded_key, entropy, secp_ctx
83838385 )
@@ -8448,8 +8450,10 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
84488450 let entropy = &*$self.entropy_source;
84498451 let secp_ctx = &$self.secp_ctx;
84508452
8451- let path = $self.create_blinded_path_using_absolute_expiry(Some(absolute_expiry))
8453+ let path = $self.create_blinded_paths_using_absolute_expiry(Some(absolute_expiry))
8454+ .and_then(|paths| paths.into_iter().next().ok_or(()))
84528455 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8456+
84538457 let builder = RefundBuilder::deriving_payer_id(
84548458 node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
84558459 )?
@@ -8470,6 +8474,13 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
84708474 }
84718475} }
84728476
8477+ /// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
8478+ /// along different paths.
8479+ /// Sending multiple requests increases the chances of successful delivery in case some
8480+ /// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
8481+ /// even if multiple invoices are received.
8482+ const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
8483+
84738484impl<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>
84748485where
84758486 M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
@@ -8571,7 +8582,7 @@ where
85718582 Some(payer_note) => builder.payer_note(payer_note),
85728583 };
85738584 let invoice_request = builder.build_and_sign()?;
8574- let reply_path = self.create_blinded_path ().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8585+ let reply_paths = self.create_blinded_paths ().map_err(|_| Bolt12SemanticError::MissingPaths)?;
85758586
85768587 let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
85778588
@@ -8584,25 +8595,27 @@ where
85848595
85858596 let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
85868597 if !offer.paths().is_empty() {
8587- // Send as many invoice requests as there are paths in the offer (with an upper bound).
8588- // Using only one path could result in a failure if the path no longer exists. But only
8589- // one invoice for a given payment id will be paid, even if more than one is received.
8590- const REQUEST_LIMIT: usize = 10;
8591- for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8598+ reply_paths
8599+ .iter()
8600+ .flat_map(|reply_path| offer.paths().iter().map(move |path| (path, reply_path)))
8601+ .take(OFFERS_MESSAGE_REQUEST_LIMIT)
8602+ .for_each(|(path, reply_path)| {
8603+ let message = new_pending_onion_message(
8604+ OffersMessage::InvoiceRequest(invoice_request.clone()),
8605+ Destination::BlindedPath(path.clone()),
8606+ Some(reply_path.clone()),
8607+ );
8608+ pending_offers_messages.push(message);
8609+ });
8610+ } else if let Some(signing_pubkey) = offer.signing_pubkey() {
8611+ for reply_path in reply_paths {
85928612 let message = new_pending_onion_message(
85938613 OffersMessage::InvoiceRequest(invoice_request.clone()),
8594- Destination::BlindedPath(path.clone() ),
8595- Some(reply_path.clone() ),
8614+ Destination::Node(signing_pubkey ),
8615+ Some(reply_path),
85968616 );
85978617 pending_offers_messages.push(message);
85988618 }
8599- } else if let Some(signing_pubkey) = offer.signing_pubkey() {
8600- let message = new_pending_onion_message(
8601- OffersMessage::InvoiceRequest(invoice_request),
8602- Destination::Node(signing_pubkey),
8603- Some(reply_path),
8604- );
8605- pending_offers_messages.push(message);
86068619 } else {
86078620 debug_assert!(false);
86088621 return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8671,26 +8684,32 @@ where
86718684 )?;
86728685 let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
86738686 let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
8674- let reply_path = self.create_blinded_path ()
8687+ let reply_paths = self.create_blinded_paths ()
86758688 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
86768689
86778690 let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
86788691 if refund.paths().is_empty() {
8679- let message = new_pending_onion_message(
8680- OffersMessage::Invoice(invoice.clone()),
8681- Destination::Node(refund.payer_id()),
8682- Some(reply_path),
8683- );
8684- pending_offers_messages.push(message);
8685- } else {
8686- for path in refund.paths() {
8692+ for reply_path in reply_paths {
86878693 let message = new_pending_onion_message(
86888694 OffersMessage::Invoice(invoice.clone()),
8689- Destination::BlindedPath(path.clone ()),
8690- Some(reply_path.clone() ),
8695+ Destination::Node(refund.payer_id ()),
8696+ Some(reply_path),
86918697 );
86928698 pending_offers_messages.push(message);
86938699 }
8700+ } else {
8701+ reply_paths
8702+ .iter()
8703+ .flat_map(|reply_path| refund.paths().iter().map(move |path| (path, reply_path)))
8704+ .take(OFFERS_MESSAGE_REQUEST_LIMIT)
8705+ .for_each(|(path, reply_path)| {
8706+ let message = new_pending_onion_message(
8707+ OffersMessage::Invoice(invoice.clone()),
8708+ Destination::BlindedPath(path.clone()),
8709+ Some(reply_path.clone()),
8710+ );
8711+ pending_offers_messages.push(message);
8712+ });
86948713 }
86958714
86968715 Ok(invoice)
@@ -8797,22 +8816,22 @@ where
87978816 inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
87988817 }
87998818
8800- /// Creates a blinded path by delegating to [`MessageRouter`] based on the path's intended
8801- /// lifetime.
8819+ /// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
8820+ /// the path's intended lifetime.
88028821 ///
88038822 /// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
88048823 /// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
88058824 /// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
8806- fn create_blinded_path_using_absolute_expiry (
8825+ fn create_blinded_paths_using_absolute_expiry (
88078826 &self, absolute_expiry: Option<Duration>
8808- ) -> Result<BlindedPath, ()> {
8827+ ) -> Result<Vec< BlindedPath> , ()> {
88098828 let now = self.duration_since_epoch();
88108829 let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
88118830
88128831 if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
8813- self.create_compact_blinded_path ()
8832+ self.create_compact_blinded_paths ()
88148833 } else {
8815- self.create_blinded_path ()
8834+ self.create_blinded_paths ()
88168835 }
88178836 }
88188837
@@ -8829,10 +8848,11 @@ where
88298848 now
88308849 }
88318850
8832- /// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
8851+ /// Creates a collection of blinded paths by delegating to
8852+ /// [`MessageRouter::create_blinded_paths`].
88338853 ///
8834- /// Errors if the `MessageRouter` errors or returns an empty `Vec` .
8835- fn create_blinded_path (&self) -> Result<BlindedPath, ()> {
8854+ /// Errors if the `MessageRouter` errors.
8855+ fn create_blinded_paths (&self) -> Result<Vec< BlindedPath> , ()> {
88368856 let recipient = self.get_our_node_id();
88378857 let secp_ctx = &self.secp_ctx;
88388858
@@ -8846,13 +8866,14 @@ where
88468866
88478867 self.router
88488868 .create_blinded_paths(recipient, peers, secp_ctx)
8849- .and_then(|paths| paths.into_iter().next( ).ok_or(()))
8869+ .and_then(|paths| (! paths.is_empty()).then(|| paths ).ok_or(()))
88508870 }
88518871
8852- /// Creates a blinded path by delegating to [`MessageRouter::create_compact_blinded_paths`].
8872+ /// Creates a collection of blinded paths by delegating to
8873+ /// [`MessageRouter::create_compact_blinded_paths`].
88538874 ///
8854- /// Errors if the `MessageRouter` errors or returns an empty `Vec` .
8855- fn create_compact_blinded_path (&self) -> Result<BlindedPath, ()> {
8875+ /// Errors if the `MessageRouter` errors.
8876+ fn create_compact_blinded_paths (&self) -> Result<Vec< BlindedPath> , ()> {
88568877 let recipient = self.get_our_node_id();
88578878 let secp_ctx = &self.secp_ctx;
88588879
@@ -8873,7 +8894,7 @@ where
88738894
88748895 self.router
88758896 .create_compact_blinded_paths(recipient, peers, secp_ctx)
8876- .and_then(|paths| paths.into_iter().next( ).ok_or(()))
8897+ .and_then(|paths| (! paths.is_empty()).then(|| paths ).ok_or(()))
88778898 }
88788899
88798900 /// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
0 commit comments