Skip to content

Commit 12e1821

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 0543b80 commit 12e1821

File tree

1 file changed

+49
-11
lines changed

1 file changed

+49
-11
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7658,9 +7658,7 @@ where
76587658

76597659
match self.create_inbound_payment(Some(amount_msats), relative_expiry, None) {
76607660
Ok((payment_hash, payment_secret)) => {
7661-
let payment_paths = vec![
7662-
self.create_one_hop_blinded_payment_path(payment_secret),
7663-
];
7661+
let payment_paths = self.create_blinded_payment_paths(amount_msats, payment_secret);
76647662
#[cfg(not(feature = "no-std"))]
76657663
let builder = refund.respond_using_derived_keys(
76667664
payment_paths, payment_hash, expanded_key, entropy
@@ -7821,6 +7819,18 @@ where
78217819
.and_then(|paths| paths.into_iter().next().ok_or(()))
78227820
}
78237821

7822+
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
7823+
/// [`Router::create_blinded_payment_paths`]. If the router returns an error or no paths,
7824+
/// creates a one-hop blinded payment path instead.
7825+
fn create_blinded_payment_paths(
7826+
&self, amount_msats: u64, payment_secret: PaymentSecret
7827+
) -> Vec<(BlindedPayInfo, BlindedPath)> {
7828+
self.create_multi_hop_blinded_payment_paths(amount_msats, payment_secret)
7829+
.ok()
7830+
.and_then(|paths| (!paths.is_empty()).then(|| paths))
7831+
.unwrap_or_else(|| vec![self.create_one_hop_blinded_payment_path(payment_secret)])
7832+
}
7833+
78247834
/// Creates a one-hop blinded payment path with [`ChannelManager::get_our_node_id`] as the
78257835
/// introduction node.
78267836
fn create_one_hop_blinded_payment_path(
@@ -7844,6 +7854,34 @@ where
78447854
).unwrap()
78457855
}
78467856

7857+
/// Creates multi-hop blinded payment paths for the given `amount_msats` by delegating to
7858+
/// [`Router::create_blinded_payment_paths`].
7859+
///
7860+
/// May return no paths if no peers [support route blinding] or whose channels don't have enough
7861+
/// inbound liquidity.
7862+
///
7863+
/// [support route blinding]: crate::ln::features::InitFeatures::supports_route_blinding
7864+
fn create_multi_hop_blinded_payment_paths(
7865+
&self, amount_msats: u64, payment_secret: PaymentSecret
7866+
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
7867+
let entropy_source = self.entropy_source.deref();
7868+
let secp_ctx = &self.secp_ctx;
7869+
7870+
let first_hops = self.list_usable_channels();
7871+
let payee_node_id = self.get_our_node_id();
7872+
let max_cltv_expiry = self.best_block.read().unwrap().height() + LATENCY_GRACE_PERIOD_BLOCKS;
7873+
let payee_tlvs = ReceiveTlvs {
7874+
payment_secret,
7875+
payment_constraints: PaymentConstraints {
7876+
max_cltv_expiry,
7877+
htlc_minimum_msat: 1,
7878+
},
7879+
};
7880+
self.router.create_blinded_payment_paths(
7881+
payee_node_id, first_hops, payee_tlvs, amount_msats, entropy_source, secp_ctx
7882+
)
7883+
}
7884+
78477885
/// Gets a fake short channel id for use in receiving [phantom node payments]. These fake scids
78487886
/// are used when constructing the phantom invoice's route hints.
78497887
///
@@ -9081,7 +9119,7 @@ where
90819119
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
90829120
&invoice_request
90839121
) {
9084-
Ok(amount_msats) => Some(amount_msats),
9122+
Ok(amount_msats) => amount_msats,
90859123
Err(error) => return Some(OffersMessage::InvoiceError(error.into())),
90869124
};
90879125
let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) {
@@ -9093,11 +9131,11 @@ where
90939131
};
90949132
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
90959133

9096-
match self.create_inbound_payment(amount_msats, relative_expiry, None) {
9134+
match self.create_inbound_payment(Some(amount_msats), relative_expiry, None) {
90979135
Ok((payment_hash, payment_secret)) if invoice_request.keys.is_some() => {
9098-
let payment_paths = vec![
9099-
self.create_one_hop_blinded_payment_path(payment_secret),
9100-
];
9136+
let payment_paths = self.create_blinded_payment_paths(
9137+
amount_msats, payment_secret
9138+
);
91019139
#[cfg(not(feature = "no-std"))]
91029140
let builder = invoice_request.respond_using_derived_keys(
91039141
payment_paths, payment_hash
@@ -9116,9 +9154,9 @@ where
91169154
}
91179155
},
91189156
Ok((payment_hash, payment_secret)) => {
9119-
let payment_paths = vec![
9120-
self.create_one_hop_blinded_payment_path(payment_secret),
9121-
];
9157+
let payment_paths = self.create_blinded_payment_paths(
9158+
amount_msats, payment_secret
9159+
);
91229160
#[cfg(not(feature = "no-std"))]
91239161
let builder = invoice_request.respond_with(payment_paths, payment_hash);
91249162
#[cfg(feature = "no-std")]

0 commit comments

Comments
 (0)