Skip to content

Commit 827833c

Browse files
committed
Multi-hop blinded payment paths in ChannelManager
When constructing blinded payment paths for Bolt12Invoice, delegate to Router::create_blinded_payment_paths which may produce multi-hop blinded paths. Fallback to one-hop blinded paths if the Router fails or returns no paths.
1 parent 62f8669 commit 827833c

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7724,6 +7724,11 @@ where
77247724
/// node meeting the aforementioned criteria, but there's no guarantee that they will be
77257725
/// received and no retries will be made.
77267726
///
7727+
/// # Errors
7728+
///
7729+
/// Errors if the parameterized [`Router`] is unable to create a blinded payment path or reply
7730+
/// path for the invoice.
7731+
///
77277732
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
77287733
pub fn request_refund_payment(&self, refund: &Refund) -> Result<(), Bolt12SemanticError> {
77297734
let expanded_key = &self.inbound_payment_key;
@@ -7735,9 +7740,9 @@ where
77357740

77367741
match self.create_inbound_payment(Some(amount_msats), relative_expiry, None) {
77377742
Ok((payment_hash, payment_secret)) => {
7738-
let payment_paths = vec![
7739-
self.create_one_hop_blinded_payment_path(payment_secret),
7740-
];
7743+
let payment_paths = self.create_blinded_payment_paths(amount_msats, payment_secret)
7744+
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
7745+
77417746
#[cfg(not(feature = "no-std"))]
77427747
let builder = refund.respond_using_derived_keys(
77437748
payment_paths, payment_hash, expanded_key, entropy
@@ -7898,14 +7903,15 @@ where
78987903
.and_then(|paths| paths.into_iter().next().ok_or(()))
78997904
}
79007905

7901-
/// Creates a one-hop blinded payment path with [`ChannelManager::get_our_node_id`] as the
7902-
/// introduction node.
7903-
fn create_one_hop_blinded_payment_path(
7904-
&self, payment_secret: PaymentSecret
7905-
) -> (BlindedPayInfo, BlindedPath) {
7906+
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
7907+
/// [`Router::create_blinded_payment_paths`].
7908+
fn create_blinded_payment_paths(
7909+
&self, amount_msats: u64, payment_secret: PaymentSecret
7910+
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
79067911
let entropy_source = self.entropy_source.deref();
79077912
let secp_ctx = &self.secp_ctx;
79087913

7914+
let first_hops = self.list_usable_channels();
79097915
let payee_node_id = self.get_our_node_id();
79107916
let max_cltv_expiry = self.best_block.read().unwrap().height() + CLTV_FAR_FAR_AWAY
79117917
+ LATENCY_GRACE_PERIOD_BLOCKS;
@@ -7916,10 +7922,9 @@ where
79167922
htlc_minimum_msat: 1,
79177923
},
79187924
};
7919-
// TODO: Err for overflow?
7920-
BlindedPath::one_hop_for_payment(
7921-
payee_node_id, payee_tlvs, entropy_source, secp_ctx
7922-
).unwrap()
7925+
self.router.create_blinded_payment_paths(
7926+
payee_node_id, first_hops, payee_tlvs, amount_msats, entropy_source, secp_ctx
7927+
)
79237928
}
79247929

79257930
/// Gets a fake short channel id for use in receiving [phantom node payments]. These fake scids
@@ -9159,7 +9164,7 @@ where
91599164
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
91609165
&invoice_request
91619166
) {
9162-
Ok(amount_msats) => Some(amount_msats),
9167+
Ok(amount_msats) => amount_msats,
91639168
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
91649169
};
91659170
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
@@ -9171,11 +9176,17 @@ where
91719176
};
91729177
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
91739178

9174-
match self.create_inbound_payment(amount_msats, relative_expiry, None) {
9179+
match self.create_inbound_payment(Some(amount_msats), relative_expiry, None) {
91759180
Ok((payment_hash, payment_secret)) if invoice_request.keys.is_some() => {
9176-
let payment_paths = vec![
9177-
self.create_one_hop_blinded_payment_path(payment_secret),
9178-
];
9181+
let payment_paths = match self.create_blinded_payment_paths(
9182+
amount_msats, payment_secret
9183+
) {
9184+
Ok(payment_paths) => payment_paths,
9185+
Err(()) => {
9186+
let error = Bolt12SemanticError::MissingPaths;
9187+
return Some(OffersMessage::InvoiceError(error.into()));
9188+
},
9189+
};
91799190
#[cfg(not(feature = "no-std"))]
91809191
let builder = invoice_request.respond_using_derived_keys(
91819192
payment_paths, payment_hash
@@ -9194,9 +9205,16 @@ where
91949205
}
91959206
},
91969207
Ok((payment_hash, payment_secret)) => {
9197-
let payment_paths = vec![
9198-
self.create_one_hop_blinded_payment_path(payment_secret),
9199-
];
9208+
let payment_paths = match self.create_blinded_payment_paths(
9209+
amount_msats, payment_secret
9210+
) {
9211+
Ok(payment_paths) => payment_paths,
9212+
Err(()) => {
9213+
let error = Bolt12SemanticError::MissingPaths;
9214+
return Some(OffersMessage::InvoiceError(error.into()));
9215+
},
9216+
};
9217+
92009218
#[cfg(not(feature = "no-std"))]
92019219
let builder = invoice_request.respond_with(payment_paths, payment_hash);
92029220
#[cfg(feature = "no-std")]

0 commit comments

Comments
 (0)