Skip to content

Commit 4461115

Browse files
committed
Expand create_blinded_path Functionality for Enhanced Path Diversification
- Previously, the `create_blinded_path` function was limited to returning a single `BlindedPath`, which restricted the usage of `blinded_paths`. - This commit extends the `create_blinded_path` function to return the entire blinded path vector generated by the `MessageRouter`'s `create_blinded_paths`. - The updated functionality is integrated across the codebase, enabling the sending of Offers Response messages, such as `InvoiceRequest` (in `pay_for_offer`) and `Invoice` (in `request_refund_payment`), utilizing multiple reply paths.
1 parent 1d0c6c6 commit 4461115

File tree

1 file changed

+63
-41
lines changed

1 file changed

+63
-41
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8285,8 +8285,10 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
82858285
let entropy = &*$self.entropy_source;
82868286
let secp_ctx = &$self.secp_ctx;
82878287

8288-
let path = $self.create_blinded_path_using_absolute_expiry(absolute_expiry)
8288+
let path = $self.create_blinded_paths_using_absolute_expiry(absolute_expiry)
8289+
.and_then(|paths| paths.into_iter().next().ok_or(()))
82898290
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8291+
82908292
let builder = OfferBuilder::deriving_signing_pubkey(
82918293
node_id, expanded_key, entropy, secp_ctx
82928294
)
@@ -8357,8 +8359,10 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
83578359
let entropy = &*$self.entropy_source;
83588360
let secp_ctx = &$self.secp_ctx;
83598361

8360-
let path = $self.create_blinded_path_using_absolute_expiry(Some(absolute_expiry))
8362+
let path = $self.create_blinded_paths_using_absolute_expiry(Some(absolute_expiry))
8363+
.and_then(|paths| paths.into_iter().next().ok_or(()))
83618364
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8365+
83628366
let builder = RefundBuilder::deriving_payer_id(
83638367
node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
83648368
)?
@@ -8480,7 +8484,7 @@ where
84808484
Some(payer_note) => builder.payer_note(payer_note),
84818485
};
84828486
let invoice_request = builder.build_and_sign()?;
8483-
let reply_path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8487+
let reply_paths = self.create_blinded_paths().map_err(|_| Bolt12SemanticError::MissingPaths)?;
84848488

84858489
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
84868490

@@ -8493,25 +8497,32 @@ where
84938497

84948498
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
84958499
if !offer.paths().is_empty() {
8496-
// Send as many invoice requests as there are paths in the offer (with an upper bound).
8497-
// Using only one path could result in a failure if the path no longer exists. But only
8498-
// one invoice for a given payment id will be paid, even if more than one is received.
8500+
// Send as many invoice requests as there are paths in the offer using as many different
8501+
// reply_paths possible (with an upper bound).
8502+
// Using only one path could result in a failure if the path no longer exists.
8503+
// But only one invoice for a given payment ID will be paid, even if more than one is received.
84998504
const REQUEST_LIMIT: usize = 10;
8500-
for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8505+
reply_paths
8506+
.iter()
8507+
.flat_map(|reply_path| offer.paths().iter().map(move |path| (path, reply_path)))
8508+
.take(REQUEST_LIMIT)
8509+
.for_each(|(path, reply_path)| {
8510+
let message = new_pending_onion_message(
8511+
OffersMessage::InvoiceRequest(invoice_request.clone()),
8512+
Destination::BlindedPath(path.clone()),
8513+
Some(reply_path.clone()),
8514+
);
8515+
pending_offers_messages.push(message);
8516+
});
8517+
} else if let Some(signing_pubkey) = offer.signing_pubkey() {
8518+
for reply_path in reply_paths {
85018519
let message = new_pending_onion_message(
85028520
OffersMessage::InvoiceRequest(invoice_request.clone()),
8503-
Destination::BlindedPath(path.clone()),
8504-
Some(reply_path.clone()),
8521+
Destination::Node(signing_pubkey),
8522+
Some(reply_path),
85058523
);
85068524
pending_offers_messages.push(message);
85078525
}
8508-
} else if let Some(signing_pubkey) = offer.signing_pubkey() {
8509-
let message = new_pending_onion_message(
8510-
OffersMessage::InvoiceRequest(invoice_request),
8511-
Destination::Node(signing_pubkey),
8512-
Some(reply_path),
8513-
);
8514-
pending_offers_messages.push(message);
85158526
} else {
85168527
debug_assert!(false);
85178528
return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8580,26 +8591,37 @@ where
85808591
)?;
85818592
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
85828593
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
8583-
let reply_path = self.create_blinded_path()
8594+
let reply_paths = self.create_blinded_paths()
85848595
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
85858596

85868597
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
85878598
if refund.paths().is_empty() {
8588-
let message = new_pending_onion_message(
8589-
OffersMessage::Invoice(invoice.clone()),
8590-
Destination::Node(refund.payer_id()),
8591-
Some(reply_path),
8592-
);
8593-
pending_offers_messages.push(message);
8594-
} else {
8595-
for path in refund.paths() {
8599+
for reply_path in reply_paths {
85968600
let message = new_pending_onion_message(
85978601
OffersMessage::Invoice(invoice.clone()),
8598-
Destination::BlindedPath(path.clone()),
8599-
Some(reply_path.clone()),
8602+
Destination::Node(refund.payer_id()),
8603+
Some(reply_path),
86008604
);
86018605
pending_offers_messages.push(message);
86028606
}
8607+
} else {
8608+
// Send as many BOLT12Invoices as there are paths in the refund using as many different
8609+
// reply_paths possible (with an upper bound).
8610+
// Using only one path could result in a failure if the path no longer exists.
8611+
// But only one invoice for a given payment ID will be paid, even if more than one is received.
8612+
const REQUEST_LIMIT: usize = 10;
8613+
reply_paths
8614+
.iter()
8615+
.flat_map(|reply_path| refund.paths().iter().map(move |path| (path, reply_path)))
8616+
.take(REQUEST_LIMIT)
8617+
.for_each(|(path, reply_path)| {
8618+
let message = new_pending_onion_message(
8619+
OffersMessage::Invoice(invoice.clone()),
8620+
Destination::BlindedPath(path.clone()),
8621+
Some(reply_path.clone()),
8622+
);
8623+
pending_offers_messages.push(message);
8624+
});
86038625
}
86048626

86058627
Ok(invoice)
@@ -8706,22 +8728,22 @@ where
87068728
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
87078729
}
87088730

8709-
/// Creates a blinded path by delegating to [`MessageRouter`] based on the path's intended
8710-
/// lifetime.
8731+
/// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
8732+
/// the path's intended lifetime.
87118733
///
87128734
/// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
87138735
/// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
87148736
/// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
8715-
fn create_blinded_path_using_absolute_expiry(
8737+
fn create_blinded_paths_using_absolute_expiry(
87168738
&self, absolute_expiry: Option<Duration>
8717-
) -> Result<BlindedPath, ()> {
8739+
) -> Result<Vec<BlindedPath>, ()> {
87188740
let now = self.duration_since_epoch();
87198741
let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
87208742

87218743
if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
8722-
self.create_compact_blinded_path()
8744+
self.create_compact_blinded_paths()
87238745
} else {
8724-
self.create_blinded_path()
8746+
self.create_blinded_paths()
87258747
}
87268748
}
87278749

@@ -8738,10 +8760,11 @@ where
87388760
now
87398761
}
87408762

8741-
/// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
8763+
/// Creates a collection of blinded paths by delegating to
8764+
/// [`MessageRouter::create_blinded_paths`].
87428765
///
8743-
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
8744-
fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
8766+
/// Errors if the `MessageRouter` errors.
8767+
fn create_blinded_paths(&self) -> Result<Vec<BlindedPath>, ()> {
87458768
let recipient = self.get_our_node_id();
87468769
let secp_ctx = &self.secp_ctx;
87478770

@@ -8755,13 +8778,13 @@ where
87558778

87568779
self.router
87578780
.create_blinded_paths(recipient, peers, secp_ctx)
8758-
.and_then(|paths| paths.into_iter().next().ok_or(()))
87598781
}
87608782

8761-
/// Creates a blinded path by delegating to [`MessageRouter::create_compact_blinded_paths`].
8783+
/// Creates a collection of blinded paths by delegating to
8784+
/// [`MessageRouter::create_compact_blinded_paths`].
87628785
///
8763-
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
8764-
fn create_compact_blinded_path(&self) -> Result<BlindedPath, ()> {
8786+
/// Errors if the `MessageRouter` errors.
8787+
fn create_compact_blinded_paths(&self) -> Result<Vec<BlindedPath>, ()> {
87658788
let recipient = self.get_our_node_id();
87668789
let secp_ctx = &self.secp_ctx;
87678790

@@ -8782,7 +8805,6 @@ where
87828805

87838806
self.router
87848807
.create_compact_blinded_paths(recipient, peers, secp_ctx)
8785-
.and_then(|paths| paths.into_iter().next().ok_or(()))
87868808
}
87878809

87888810
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to

0 commit comments

Comments
 (0)