@@ -8584,12 +8584,15 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
8584
8584
let entropy = &*$self.entropy_source;
8585
8585
let secp_ctx = &$self.secp_ctx;
8586
8586
8587
- let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8587
+ // TODO: Introduce a parameter to allow adding more paths to the created Offer.
8588
+ let paths = $self.create_blinded_path(1)
8589
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8590
+
8588
8591
let builder = OfferBuilder::deriving_signing_pubkey(
8589
8592
node_id, expanded_key, entropy, secp_ctx
8590
8593
)
8591
8594
.chain_hash($self.chain_hash)
8592
- .path(path );
8595
+ .path(paths );
8593
8596
8594
8597
Ok(builder.into())
8595
8598
}
@@ -8651,13 +8654,16 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
8651
8654
let entropy = &*$self.entropy_source;
8652
8655
let secp_ctx = &$self.secp_ctx;
8653
8656
8654
- let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8657
+ // TODO: Introduce a parameter to allow adding more paths to the created Refund.
8658
+ let paths = $self.create_blinded_path(1)
8659
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8660
+
8655
8661
let builder = RefundBuilder::deriving_payer_id(
8656
8662
node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
8657
8663
)?
8658
8664
.chain_hash($self.chain_hash)
8659
8665
.absolute_expiry(absolute_expiry)
8660
- .path(path );
8666
+ .path(paths );
8661
8667
8662
8668
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop($self);
8663
8669
@@ -8774,7 +8780,8 @@ where
8774
8780
Some(payer_note) => builder.payer_note(payer_note),
8775
8781
};
8776
8782
let invoice_request = builder.build_and_sign()?;
8777
- let reply_path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8783
+ let reply_paths = self.create_blinded_path(5)
8784
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8778
8785
8779
8786
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
8780
8787
@@ -8787,25 +8794,32 @@ where
8787
8794
8788
8795
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8789
8796
if !offer.paths().is_empty() {
8790
- // Send as many invoice requests as there are paths in the offer (with an upper bound).
8791
- // Using only one path could result in a failure if the path no longer exists. But only
8792
- // one invoice for a given payment id will be paid, even if more than one is received.
8797
+ // Send as many invoice requests as there are paths in the offer using as many different
8798
+ // reply_paths possible (with an upper bound).
8799
+ // Using only one path could result in a failure if the path no longer exists.
8800
+ // But only one invoice for a given payment ID will be paid, even if more than one is received.
8793
8801
const REQUEST_LIMIT: usize = 10;
8794
- for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8802
+ reply_paths
8803
+ .iter()
8804
+ .flat_map(|reply_path| offer.paths().iter().map(|path| (path.clone(), reply_path.clone())))
8805
+ .take(REQUEST_LIMIT)
8806
+ .for_each(|(path, reply_path)| {
8807
+ let message = new_pending_onion_message(
8808
+ OffersMessage::InvoiceRequest(invoice_request.clone()),
8809
+ Destination::BlindedPath(path.clone()),
8810
+ Some(reply_path.clone()),
8811
+ );
8812
+ pending_offers_messages.push(message);
8813
+ });
8814
+ } else if let Some(signing_pubkey) = offer.signing_pubkey() {
8815
+ for reply_path in reply_paths {
8795
8816
let message = new_pending_onion_message(
8796
8817
OffersMessage::InvoiceRequest(invoice_request.clone()),
8797
- Destination::BlindedPath(path.clone() ),
8798
- Some(reply_path.clone() ),
8818
+ Destination::Node(signing_pubkey ),
8819
+ Some(reply_path),
8799
8820
);
8800
8821
pending_offers_messages.push(message);
8801
8822
}
8802
- } else if let Some(signing_pubkey) = offer.signing_pubkey() {
8803
- let message = new_pending_onion_message(
8804
- OffersMessage::InvoiceRequest(invoice_request),
8805
- Destination::Node(signing_pubkey),
8806
- Some(reply_path),
8807
- );
8808
- pending_offers_messages.push(message);
8809
8823
} else {
8810
8824
debug_assert!(false);
8811
8825
return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8874,26 +8888,30 @@ where
8874
8888
)?;
8875
8889
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
8876
8890
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
8877
- let reply_path = self.create_blinded_path()
8891
+ let reply_paths = self.create_blinded_path(5 )
8878
8892
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8879
8893
8880
8894
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8881
8895
if refund.paths().is_empty() {
8882
- let message = new_pending_onion_message(
8883
- OffersMessage::Invoice(invoice.clone()),
8884
- Destination::Node(refund.payer_id()),
8885
- Some(reply_path),
8886
- );
8887
- pending_offers_messages.push(message);
8888
- } else {
8889
- for path in refund.paths() {
8896
+ for reply_path in reply_paths {
8890
8897
let message = new_pending_onion_message(
8891
8898
OffersMessage::Invoice(invoice.clone()),
8892
- Destination::BlindedPath(path.clone ()),
8893
- Some(reply_path.clone() ),
8899
+ Destination::Node(refund.payer_id ()),
8900
+ Some(reply_path),
8894
8901
);
8895
8902
pending_offers_messages.push(message);
8896
8903
}
8904
+ } else {
8905
+ for path in refund.paths() {
8906
+ for reply_path in reply_paths.clone() {
8907
+ let message = new_pending_onion_message(
8908
+ OffersMessage::Invoice(invoice.clone()),
8909
+ Destination::BlindedPath(path.clone()),
8910
+ Some(reply_path.clone()),
8911
+ );
8912
+ pending_offers_messages.push(message);
8913
+ }
8914
+ }
8897
8915
}
8898
8916
8899
8917
Ok(invoice)
@@ -9003,7 +9021,7 @@ where
9003
9021
/// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
9004
9022
///
9005
9023
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
9006
- fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
9024
+ fn create_blinded_path(&self, count: usize ) -> Result<Vec< BlindedPath> , ()> {
9007
9025
let recipient = self.get_our_node_id();
9008
9026
let secp_ctx = &self.secp_ctx;
9009
9027
@@ -9022,8 +9040,7 @@ where
9022
9040
.collect::<Vec<_>>();
9023
9041
9024
9042
self.router
9025
- .create_blinded_paths(recipient, peers, secp_ctx)
9026
- .and_then(|paths| paths.into_iter().next().ok_or(()))
9043
+ .create_blinded_paths(recipient, peers, secp_ctx, count)
9027
9044
}
9028
9045
9029
9046
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
0 commit comments