@@ -8270,7 +8270,12 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
8270
8270
let entropy = &*$self.entropy_source;
8271
8271
let secp_ctx = &$self.secp_ctx;
8272
8272
8273
- let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8273
+ // TODO: Introduce a parameter to allow adding more paths to the created Offer.
8274
+ let path = $self.create_blinded_path(1)
8275
+ .and_then(|paths| paths.into_iter().next().ok_or(()))
8276
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8277
+
8278
+
8274
8279
let builder = OfferBuilder::deriving_signing_pubkey(
8275
8280
node_id, expanded_key, entropy, secp_ctx
8276
8281
)
@@ -8337,7 +8342,11 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
8337
8342
let entropy = &*$self.entropy_source;
8338
8343
let secp_ctx = &$self.secp_ctx;
8339
8344
8340
- let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8345
+ // TODO: Introduce a parameter to allow adding more paths to the created Refund.
8346
+ let path = $self.create_blinded_path(1)
8347
+ .and_then(|paths| paths.into_iter().next().ok_or(()))
8348
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8349
+
8341
8350
let builder = RefundBuilder::deriving_payer_id(
8342
8351
node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
8343
8352
)?
@@ -8438,6 +8447,11 @@ where
8438
8447
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
8439
8448
max_total_routing_fee_msat: Option<u64>
8440
8449
) -> Result<(), Bolt12SemanticError> {
8450
+
8451
+ // Maximum number of unique reply paths to be calculated for use
8452
+ // with the generated InvoiceRequest messages.
8453
+ const MAX_REPLY_PATHS: usize = 5;
8454
+
8441
8455
let expanded_key = &self.inbound_payment_key;
8442
8456
let entropy = &*self.entropy_source;
8443
8457
let secp_ctx = &self.secp_ctx;
@@ -8460,7 +8474,8 @@ where
8460
8474
Some(payer_note) => builder.payer_note(payer_note),
8461
8475
};
8462
8476
let invoice_request = builder.build_and_sign()?;
8463
- let reply_path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8477
+ let reply_paths = self.create_blinded_path(MAX_REPLY_PATHS)
8478
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
8464
8479
8465
8480
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
8466
8481
@@ -8473,25 +8488,32 @@ where
8473
8488
8474
8489
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8475
8490
if !offer.paths().is_empty() {
8476
- // Send as many invoice requests as there are paths in the offer (with an upper bound).
8477
- // Using only one path could result in a failure if the path no longer exists. But only
8478
- // one invoice for a given payment id will be paid, even if more than one is received.
8491
+ // Send as many invoice requests as there are paths in the offer using as many different
8492
+ // reply_paths possible (with an upper bound).
8493
+ // Using only one path could result in a failure if the path no longer exists.
8494
+ // But only one invoice for a given payment ID will be paid, even if more than one is received.
8479
8495
const REQUEST_LIMIT: usize = 10;
8480
- for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8496
+ reply_paths
8497
+ .iter()
8498
+ .flat_map(|reply_path| offer.paths().iter().map(move |path| (path, reply_path)))
8499
+ .take(REQUEST_LIMIT)
8500
+ .for_each(|(path, reply_path)| {
8501
+ let message = new_pending_onion_message(
8502
+ OffersMessage::InvoiceRequest(invoice_request.clone()),
8503
+ Destination::BlindedPath(path.clone()),
8504
+ Some(reply_path.clone()),
8505
+ );
8506
+ pending_offers_messages.push(message);
8507
+ });
8508
+ } else if let Some(signing_pubkey) = offer.signing_pubkey() {
8509
+ for reply_path in reply_paths {
8481
8510
let message = new_pending_onion_message(
8482
8511
OffersMessage::InvoiceRequest(invoice_request.clone()),
8483
- Destination::BlindedPath(path.clone() ),
8484
- Some(reply_path.clone() ),
8512
+ Destination::Node(signing_pubkey ),
8513
+ Some(reply_path),
8485
8514
);
8486
8515
pending_offers_messages.push(message);
8487
8516
}
8488
- } else if let Some(signing_pubkey) = offer.signing_pubkey() {
8489
- let message = new_pending_onion_message(
8490
- OffersMessage::InvoiceRequest(invoice_request),
8491
- Destination::Node(signing_pubkey),
8492
- Some(reply_path),
8493
- );
8494
- pending_offers_messages.push(message);
8495
8517
} else {
8496
8518
debug_assert!(false);
8497
8519
return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8525,6 +8547,11 @@ where
8525
8547
pub fn request_refund_payment(
8526
8548
&self, refund: &Refund
8527
8549
) -> Result<Bolt12Invoice, Bolt12SemanticError> {
8550
+
8551
+ // Maximum number of unique reply paths to be calculated for use
8552
+ // with the generated BOLT12Invoice messages.
8553
+ const MAX_REPLY_PATHS: usize = 5;
8554
+
8528
8555
let expanded_key = &self.inbound_payment_key;
8529
8556
let entropy = &*self.entropy_source;
8530
8557
let secp_ctx = &self.secp_ctx;
@@ -8560,26 +8587,37 @@ where
8560
8587
)?;
8561
8588
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
8562
8589
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
8563
- let reply_path = self.create_blinded_path()
8590
+ let reply_paths = self.create_blinded_path(MAX_REPLY_PATHS )
8564
8591
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8565
8592
8566
8593
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8567
8594
if refund.paths().is_empty() {
8568
- let message = new_pending_onion_message(
8569
- OffersMessage::Invoice(invoice.clone()),
8570
- Destination::Node(refund.payer_id()),
8571
- Some(reply_path),
8572
- );
8573
- pending_offers_messages.push(message);
8574
- } else {
8575
- for path in refund.paths() {
8595
+ for reply_path in reply_paths {
8576
8596
let message = new_pending_onion_message(
8577
8597
OffersMessage::Invoice(invoice.clone()),
8578
- Destination::BlindedPath(path.clone ()),
8579
- Some(reply_path.clone() ),
8598
+ Destination::Node(refund.payer_id ()),
8599
+ Some(reply_path),
8580
8600
);
8581
8601
pending_offers_messages.push(message);
8582
8602
}
8603
+ } else {
8604
+ // Send as many BOLT12Invoices as there are paths in the refund using as many different
8605
+ // reply_paths possible (with an upper bound).
8606
+ // Using only one path could result in a failure if the path no longer exists.
8607
+ // But only one invoice for a given payment ID will be paid, even if more than one is received.
8608
+ const REQUEST_LIMIT: usize = 10;
8609
+ reply_paths
8610
+ .iter()
8611
+ .flat_map(|reply_path| refund.paths().iter().map(move |path| (path, reply_path)))
8612
+ .take(REQUEST_LIMIT)
8613
+ .for_each(|(path, reply_path)| {
8614
+ let message = new_pending_onion_message(
8615
+ OffersMessage::Invoice(invoice.clone()),
8616
+ Destination::BlindedPath(path.clone()),
8617
+ Some(reply_path.clone()),
8618
+ );
8619
+ pending_offers_messages.push(message);
8620
+ });
8583
8621
}
8584
8622
8585
8623
Ok(invoice)
@@ -8689,7 +8727,7 @@ where
8689
8727
/// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
8690
8728
///
8691
8729
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
8692
- fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
8730
+ fn create_blinded_path(&self, count: usize ) -> Result<Vec< BlindedPath> , ()> {
8693
8731
let recipient = self.get_our_node_id();
8694
8732
let secp_ctx = &self.secp_ctx;
8695
8733
@@ -8708,8 +8746,7 @@ where
8708
8746
.collect::<Vec<_>>();
8709
8747
8710
8748
self.router
8711
- .create_blinded_paths(recipient, peers, secp_ctx)
8712
- .and_then(|paths| paths.into_iter().next().ok_or(()))
8749
+ .create_blinded_paths(recipient, peers, secp_ctx, count)
8713
8750
}
8714
8751
8715
8752
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
0 commit comments