Skip to content

Commit b6e38c2

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 b6e38c2

File tree

2 files changed

+56
-33
lines changed

2 files changed

+56
-33
lines changed

lightning/src/ln/channelmanager.rs

+52-30
Original file line numberDiff line numberDiff line change
@@ -8285,8 +8285,11 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
82858285
let entropy = &*$self.entropy_source;
82868286
let secp_ctx = &$self.secp_ctx;
82878287

8288+
// TODO: Introduce a parameter to allow adding more paths to the created Offer.
82888289
let path = $self.create_blinded_path_using_absolute_expiry(absolute_expiry)
8290+
.and_then(|paths| paths.into_iter().next().ok_or(()))
82898291
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8292+
82908293
let builder = OfferBuilder::deriving_signing_pubkey(
82918294
node_id, expanded_key, entropy, secp_ctx
82928295
)
@@ -8357,8 +8360,11 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
83578360
let entropy = &*$self.entropy_source;
83588361
let secp_ctx = &$self.secp_ctx;
83598362

8363+
// TODO: Introduce a parameter to allow adding more paths to the created Refund.
83608364
let path = $self.create_blinded_path_using_absolute_expiry(Some(absolute_expiry))
8365+
.and_then(|paths| paths.into_iter().next().ok_or(()))
83618366
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
8367+
83628368
let builder = RefundBuilder::deriving_payer_id(
83638369
node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
83648370
)?
@@ -8480,7 +8486,7 @@ where
84808486
Some(payer_note) => builder.payer_note(payer_note),
84818487
};
84828488
let invoice_request = builder.build_and_sign()?;
8483-
let reply_path = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
8489+
let reply_paths = self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?;
84848490

84858491
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
84868492

@@ -8493,25 +8499,32 @@ where
84938499

84948500
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
84958501
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.
8502+
// Send as many invoice requests as there are paths in the offer using as many different
8503+
// reply_paths possible (with an upper bound).
8504+
// Using only one path could result in a failure if the path no longer exists.
8505+
// But only one invoice for a given payment ID will be paid, even if more than one is received.
84998506
const REQUEST_LIMIT: usize = 10;
8500-
for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8507+
reply_paths
8508+
.iter()
8509+
.flat_map(|reply_path| offer.paths().iter().map(move |path| (path, reply_path)))
8510+
.take(REQUEST_LIMIT)
8511+
.for_each(|(path, reply_path)| {
8512+
let message = new_pending_onion_message(
8513+
OffersMessage::InvoiceRequest(invoice_request.clone()),
8514+
Destination::BlindedPath(path.clone()),
8515+
Some(reply_path.clone()),
8516+
);
8517+
pending_offers_messages.push(message);
8518+
});
8519+
} else if let Some(signing_pubkey) = offer.signing_pubkey() {
8520+
for reply_path in reply_paths {
85018521
let message = new_pending_onion_message(
85028522
OffersMessage::InvoiceRequest(invoice_request.clone()),
8503-
Destination::BlindedPath(path.clone()),
8504-
Some(reply_path.clone()),
8523+
Destination::Node(signing_pubkey),
8524+
Some(reply_path),
85058525
);
85068526
pending_offers_messages.push(message);
85078527
}
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);
85158528
} else {
85168529
debug_assert!(false);
85178530
return Err(Bolt12SemanticError::MissingSigningPubkey);
@@ -8580,26 +8593,37 @@ where
85808593
)?;
85818594
let builder: InvoiceBuilder<DerivedSigningPubkey> = builder.into();
85828595
let invoice = builder.allow_mpp().build_and_sign(secp_ctx)?;
8583-
let reply_path = self.create_blinded_path()
8596+
let reply_paths = self.create_blinded_path()
85848597
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
85858598

85868599
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
85878600
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() {
8601+
for reply_path in reply_paths {
85968602
let message = new_pending_onion_message(
85978603
OffersMessage::Invoice(invoice.clone()),
8598-
Destination::BlindedPath(path.clone()),
8599-
Some(reply_path.clone()),
8604+
Destination::Node(refund.payer_id()),
8605+
Some(reply_path),
86008606
);
86018607
pending_offers_messages.push(message);
86028608
}
8609+
} else {
8610+
// Send as many BOLT12Invoices as there are paths in the refund using as many different
8611+
// reply_paths possible (with an upper bound).
8612+
// Using only one path could result in a failure if the path no longer exists.
8613+
// But only one invoice for a given payment ID will be paid, even if more than one is received.
8614+
const REQUEST_LIMIT: usize = 10;
8615+
reply_paths
8616+
.iter()
8617+
.flat_map(|reply_path| refund.paths().iter().map(move |path| (path, reply_path)))
8618+
.take(REQUEST_LIMIT)
8619+
.for_each(|(path, reply_path)| {
8620+
let message = new_pending_onion_message(
8621+
OffersMessage::Invoice(invoice.clone()),
8622+
Destination::BlindedPath(path.clone()),
8623+
Some(reply_path.clone()),
8624+
);
8625+
pending_offers_messages.push(message);
8626+
});
86038627
}
86048628

86058629
Ok(invoice)
@@ -8714,7 +8738,7 @@ where
87148738
/// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
87158739
fn create_blinded_path_using_absolute_expiry(
87168740
&self, absolute_expiry: Option<Duration>
8717-
) -> Result<BlindedPath, ()> {
8741+
) -> Result<Vec<BlindedPath>, ()> {
87188742
let now = self.duration_since_epoch();
87198743
let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
87208744

@@ -8741,7 +8765,7 @@ where
87418765
/// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
87428766
///
87438767
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
8744-
fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
8768+
fn create_blinded_path(&self) -> Result<Vec<BlindedPath>, ()> {
87458769
let recipient = self.get_our_node_id();
87468770
let secp_ctx = &self.secp_ctx;
87478771

@@ -8755,13 +8779,12 @@ where
87558779

87568780
self.router
87578781
.create_blinded_paths(recipient, peers, secp_ctx)
8758-
.and_then(|paths| paths.into_iter().next().ok_or(()))
87598782
}
87608783

87618784
/// Creates a blinded path by delegating to [`MessageRouter::create_compact_blinded_paths`].
87628785
///
87638786
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
8764-
fn create_compact_blinded_path(&self) -> Result<BlindedPath, ()> {
8787+
fn create_compact_blinded_path(&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

lightning/src/onion_message/messenger.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ where
11271127
.map_err(|_| SendError::PathNotFound)
11281128
}
11291129

1130-
fn create_blinded_path(&self) -> Result<BlindedPath, SendError> {
1130+
fn create_blinded_path(&self) -> Result<Vec<BlindedPath>, SendError> {
11311131
let recipient = self.node_signer
11321132
.get_node_id(Recipient::Node)
11331133
.map_err(|_| SendError::GetNodeIdFailed)?;
@@ -1141,7 +1141,6 @@ where
11411141

11421142
self.message_router
11431143
.create_blinded_paths(recipient, peers, secp_ctx)
1144-
.and_then(|paths| paths.into_iter().next().ok_or(()))
11451144
.map_err(|_| SendError::PathNotFound)
11461145
}
11471146

@@ -1237,7 +1236,9 @@ where
12371236

12381237
let message_type = response.message.msg_type();
12391238
let reply_path = if create_reply_path {
1240-
match self.create_blinded_path() {
1239+
match self.create_blinded_path().and_then(
1240+
|paths| paths.into_iter().next().ok_or(SendError::PathNotFound)
1241+
) {
12411242
Ok(reply_path) => Some(reply_path),
12421243
Err(err) => {
12431244
log_trace!(

0 commit comments

Comments
 (0)