@@ -8376,8 +8376,10 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
8376
8376
let entropy = &*$self.entropy_source;
8377
8377
let secp_ctx = &$self.secp_ctx;
8378
8378
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(()))
8380
8381
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8382
+
8381
8383
let builder = OfferBuilder::deriving_signing_pubkey(
8382
8384
node_id, expanded_key, entropy, secp_ctx
8383
8385
)
@@ -8448,8 +8450,10 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
8448
8450
let entropy = &*$self.entropy_source;
8449
8451
let secp_ctx = &$self.secp_ctx;
8450
8452
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(()))
8452
8455
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8456
+
8453
8457
let builder = RefundBuilder::deriving_payer_id(
8454
8458
node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
8455
8459
)?
@@ -8470,6 +8474,13 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
8470
8474
}
8471
8475
} }
8472
8476
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
+
8473
8484
impl<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>
8474
8485
where
8475
8486
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
@@ -8571,7 +8582,7 @@ where
8571
8582
Some(payer_note) => builder.payer_note(payer_note),
8572
8583
};
8573
8584
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)?;
8575
8586
8576
8587
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
8577
8588
@@ -8584,25 +8595,27 @@ where
8584
8595
8585
8596
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8586
8597
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 {
8592
8612
let message = new_pending_onion_message(
8593
8613
OffersMessage::InvoiceRequest(invoice_request.clone()),
8594
- Destination::BlindedPath(path.clone() ),
8595
- Some(reply_path.clone() ),
8614
+ Destination::Node(signing_pubkey ),
8615
+ Some(reply_path),
8596
8616
);
8597
8617
pending_offers_messages.push(message);
8598
8618
}
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);
8606
8619
} else {
8607
8620
debug_assert!(false);
8608
8621
return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8671,26 +8684,32 @@ where
8671
8684
)?;
8672
8685
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
8673
8686
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 ()
8675
8688
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8676
8689
8677
8690
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8678
8691
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 {
8687
8693
let message = new_pending_onion_message(
8688
8694
OffersMessage::Invoice(invoice.clone()),
8689
- Destination::BlindedPath(path.clone ()),
8690
- Some(reply_path.clone() ),
8695
+ Destination::Node(refund.payer_id ()),
8696
+ Some(reply_path),
8691
8697
);
8692
8698
pending_offers_messages.push(message);
8693
8699
}
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
+ });
8694
8713
}
8695
8714
8696
8715
Ok(invoice)
@@ -8797,22 +8816,22 @@ where
8797
8816
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
8798
8817
}
8799
8818
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.
8802
8821
///
8803
8822
/// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
8804
8823
/// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
8805
8824
/// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
8806
- fn create_blinded_path_using_absolute_expiry (
8825
+ fn create_blinded_paths_using_absolute_expiry (
8807
8826
&self, absolute_expiry: Option<Duration>
8808
- ) -> Result<BlindedPath, ()> {
8827
+ ) -> Result<Vec< BlindedPath> , ()> {
8809
8828
let now = self.duration_since_epoch();
8810
8829
let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
8811
8830
8812
8831
if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
8813
- self.create_compact_blinded_path ()
8832
+ self.create_compact_blinded_paths ()
8814
8833
} else {
8815
- self.create_blinded_path ()
8834
+ self.create_blinded_paths ()
8816
8835
}
8817
8836
}
8818
8837
@@ -8829,10 +8848,11 @@ where
8829
8848
now
8830
8849
}
8831
8850
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`].
8833
8853
///
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> , ()> {
8836
8856
let recipient = self.get_our_node_id();
8837
8857
let secp_ctx = &self.secp_ctx;
8838
8858
@@ -8846,13 +8866,14 @@ where
8846
8866
8847
8867
self.router
8848
8868
.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(()))
8850
8870
}
8851
8871
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`].
8853
8874
///
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> , ()> {
8856
8877
let recipient = self.get_our_node_id();
8857
8878
let secp_ctx = &self.secp_ctx;
8858
8879
@@ -8873,7 +8894,7 @@ where
8873
8894
8874
8895
self.router
8875
8896
.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(()))
8877
8898
}
8878
8899
8879
8900
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
0 commit comments