Skip to content

Commit 07def92

Browse files
committed
Help users support sending MPP keysend
When routing a keysend payment, the user may want to signal to the router whether to find multi-path routes in the `PaymentParameters::for_keysend` helper, without going through manual construction. Since some implementations do not support MPP keysend, we have the user make the choice here rather than making it the default. Some implementations will reject keysend payments with payment secrets, so this commit also adds docs to `RecipientOnionFields` to communicate this to the user.
1 parent 749ae12 commit 07def92

File tree

5 files changed

+31
-15
lines changed

5 files changed

+31
-15
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,8 +2924,6 @@ where
29242924
/// Similar to regular payments, you MUST NOT reuse a `payment_preimage` value. See
29252925
/// [`send_payment`] for more information about the risks of duplicate preimage usage.
29262926
///
2927-
/// Note that `route` must have exactly one path.
2928-
///
29292927
/// [`send_payment`]: Self::send_payment
29302928
pub fn send_spontaneous_payment(&self, route: &Route, payment_preimage: Option<PaymentPreimage>, recipient_onion: RecipientOnionFields, payment_id: PaymentId) -> Result<PaymentHash, PaymentSendFailure> {
29312929
let best_block_height = self.best_block.read().unwrap().height();
@@ -8580,7 +8578,7 @@ mod tests {
85808578

85818579
// Next, attempt a keysend payment and make sure it fails.
85828580
let route_params = RouteParameters {
8583-
payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV),
8581+
payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV, false),
85848582
final_value_msat: 100_000,
85858583
};
85868584
let route = find_route(
@@ -8673,7 +8671,7 @@ mod tests {
86738671

86748672
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
86758673
let route_params = RouteParameters {
8676-
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
8674+
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
86778675
final_value_msat: 10_000,
86788676
};
86798677
let network_graph = nodes[0].network_graph.clone();
@@ -8717,7 +8715,7 @@ mod tests {
87178715

87188716
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
87198717
let route_params = RouteParameters {
8720-
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
8718+
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
87218719
final_value_msat: 10_000,
87228720
};
87238721
let network_graph = nodes[0].network_graph.clone();

lightning/src/ln/features.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,17 @@ impl InvoiceFeatures {
533533
/// [`PaymentParameters::for_keysend`], thus omitting the need for payers to manually construct an
534534
/// `InvoiceFeatures` for [`find_route`].
535535
///
536+
/// MPP keysend is not widely supported yet, so we parameterize support to allow the user to
537+
/// choose whether their router should find multi-part routes.
538+
///
536539
/// [`PaymentParameters::for_keysend`]: crate::routing::router::PaymentParameters::for_keysend
537540
/// [`find_route`]: crate::routing::router::find_route
538-
pub(crate) fn for_keysend() -> InvoiceFeatures {
541+
pub(crate) fn for_keysend(allow_mpp: bool) -> InvoiceFeatures {
539542
let mut res = InvoiceFeatures::empty();
540543
res.set_variable_length_onion_optional();
544+
if allow_mpp {
545+
res.set_basic_mpp_optional();
546+
}
541547
res
542548
}
543549
}

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9478,7 +9478,7 @@ fn test_keysend_payments_to_public_node() {
94789478
let payer_pubkey = nodes[0].node.get_our_node_id();
94799479
let payee_pubkey = nodes[1].node.get_our_node_id();
94809480
let route_params = RouteParameters {
9481-
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
9481+
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
94829482
final_value_msat: 10000,
94839483
};
94849484
let scorer = test_utils::TestScorer::new();
@@ -9509,7 +9509,7 @@ fn test_keysend_payments_to_private_node() {
95099509

95109510
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
95119511
let route_params = RouteParameters {
9512-
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
9512+
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
95139513
final_value_msat: 10000,
95149514
};
95159515
let network_graph = nodes[0].network_graph.clone();

lightning/src/ln/outbound_payment.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,9 @@ pub struct RecipientOnionFields {
414414
/// If you do not have one, the [`Route`] you pay over must not contain multiple paths as
415415
/// multi-path payments require a recipient-provided secret.
416416
///
417-
/// Note that for spontaneous payments most lightning nodes do not currently support MPP
418-
/// receives, thus you should generally never be providing a secret here for spontaneous
419-
/// payments.
417+
/// Some implementations may reject spontaneous payments with payment secrets, so you may only
418+
/// want to provide a secret for a spontaneous payment if MPP is needed and you know your
419+
/// recipient will not reject it.
420420
pub payment_secret: Option<PaymentSecret>,
421421
/// The payment metadata serves a similar purpose as [`Self::payment_secret`] but is of
422422
/// arbitrary length. This gives recipients substantially more flexibility to receive
@@ -447,10 +447,13 @@ impl RecipientOnionFields {
447447
}
448448

449449
/// Creates a new [`RecipientOnionFields`] with no fields. This generally does not create
450-
/// payable HTLCs except for spontaneous payments, i.e. this should generally only be used for
451-
/// calls to [`ChannelManager::send_spontaneous_payment`].
450+
/// payable HTLCs except for single-path spontaneous payments, i.e. this should generally
451+
/// only be used for calls to [`ChannelManager::send_spontaneous_payment`]. If you are sending
452+
/// a spontaneous MPP this will not work as all MPP require payment secrets; you may
453+
/// instead want to use [`RecipientOnionFields::secret_only`].
452454
///
453455
/// [`ChannelManager::send_spontaneous_payment`]: super::channelmanager::ChannelManager::send_spontaneous_payment
456+
/// [`RecipientOnionFields::secret_only`]: RecipientOnionFields::secret_only
454457
pub fn spontaneous_empty() -> Self {
455458
Self { payment_secret: None, payment_metadata: None }
456459
}

lightning/src/routing/router.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,17 @@ impl PaymentParameters {
621621
///
622622
/// The `final_cltv_expiry_delta` should match the expected final CLTV delta the recipient has
623623
/// provided.
624-
pub fn for_keysend(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32) -> Self {
625-
Self::from_node_id(payee_pubkey, final_cltv_expiry_delta).with_bolt11_features(InvoiceFeatures::for_keysend()).expect("PaymentParameters::from_node_id should always initialize the payee as unblinded")
624+
///
625+
/// Note that MPP keysend is not widely supported yet. The `allow_mpp` lets you choose
626+
/// whether your router will be allowed to find a multi-part route for this payment. If you
627+
/// set `allow_mpp` to true, you should ensure a payment secret is set on send, likely via
628+
/// [`RecipientOnionFields::secret_only`].
629+
///
630+
/// [`RecipientOnionFields::secret_only`]: crate::ln::channelmanager::RecipientOnionFields::secret_only
631+
pub fn for_keysend(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32, allow_mpp: bool) -> Self {
632+
Self::from_node_id(payee_pubkey, final_cltv_expiry_delta)
633+
.with_bolt11_features(InvoiceFeatures::for_keysend(allow_mpp))
634+
.expect("PaymentParameters::from_node_id should always initialize the payee as unblinded")
626635
}
627636

628637
/// Includes the payee's features. Errors if the parameters were initialized with blinded payment

0 commit comments

Comments
 (0)