Skip to content

Commit f68b124

Browse files
Support next_blinding_override in blinded payment paths.
This allow us to forward blinded payments where the blinded path that we are forwarding within was concatenated to another blinded path that starts at the next hop. Also allows constructing blinded paths using this override.
1 parent 8fe3a56 commit f68b124

File tree

8 files changed

+40
-10
lines changed

8 files changed

+40
-10
lines changed

fuzz/src/invoice_request_deser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
113113
htlc_minimum_msat: 100,
114114
},
115115
features: BlindedHopFeatures::empty(),
116+
next_blinding_override: None,
116117
},
117118
node_id: pubkey(43),
118119
htlc_maximum_msat: 1_000_000_000_000,

fuzz/src/refund_deser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
9191
htlc_minimum_msat: 100,
9292
},
9393
features: BlindedHopFeatures::empty(),
94+
next_blinding_override: None,
9495
},
9596
node_id: pubkey(43),
9697
htlc_maximum_msat: 1_000_000_000_000,

lightning/src/blinded_path/payment.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
201201
///
202202
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
203203
pub features: BlindedHopFeatures,
204+
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
205+
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
206+
pub next_blinding_override: Option<PublicKey>,
204207
}
205208

206209
/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
@@ -379,6 +382,7 @@ impl Readable for BlindedPaymentTlvs {
379382
_init_and_read_tlv_stream!(r, {
380383
(1, _padding, option),
381384
(2, scid, option),
385+
(8, next_blinding_override, option),
382386
(10, payment_relay, option),
383387
(12, payment_constraints, required),
384388
(14, features, option),
@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
395399
short_channel_id,
396400
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
397401
payment_constraints: payment_constraints.0.unwrap(),
402+
next_blinding_override,
398403
features: features.unwrap_or_else(BlindedHopFeatures::empty),
399404
}))
400405
} else {
@@ -602,6 +607,7 @@ mod tests {
602607
max_cltv_expiry: 0,
603608
htlc_minimum_msat: 100,
604609
},
610+
next_blinding_override: None,
605611
features: BlindedHopFeatures::empty(),
606612
},
607613
htlc_maximum_msat: u64::max_value(),
@@ -618,6 +624,7 @@ mod tests {
618624
max_cltv_expiry: 0,
619625
htlc_minimum_msat: 1_000,
620626
},
627+
next_blinding_override: None,
621628
features: BlindedHopFeatures::empty(),
622629
},
623630
htlc_maximum_msat: u64::max_value(),
@@ -675,6 +682,7 @@ mod tests {
675682
max_cltv_expiry: 0,
676683
htlc_minimum_msat: 1,
677684
},
685+
next_blinding_override: None,
678686
features: BlindedHopFeatures::empty(),
679687
},
680688
htlc_maximum_msat: u64::max_value()
@@ -691,6 +699,7 @@ mod tests {
691699
max_cltv_expiry: 0,
692700
htlc_minimum_msat: 2_000,
693701
},
702+
next_blinding_override: None,
694703
features: BlindedHopFeatures::empty(),
695704
},
696705
htlc_maximum_msat: u64::max_value()
@@ -726,6 +735,7 @@ mod tests {
726735
max_cltv_expiry: 0,
727736
htlc_minimum_msat: 5_000,
728737
},
738+
next_blinding_override: None,
729739
features: BlindedHopFeatures::empty(),
730740
},
731741
htlc_maximum_msat: u64::max_value()
@@ -742,6 +752,7 @@ mod tests {
742752
max_cltv_expiry: 0,
743753
htlc_minimum_msat: 2_000,
744754
},
755+
next_blinding_override: None,
745756
features: BlindedHopFeatures::empty(),
746757
},
747758
htlc_maximum_msat: u64::max_value()
@@ -781,6 +792,7 @@ mod tests {
781792
max_cltv_expiry: 0,
782793
htlc_minimum_msat: 1,
783794
},
795+
next_blinding_override: None,
784796
features: BlindedHopFeatures::empty(),
785797
},
786798
htlc_maximum_msat: 5_000,
@@ -797,6 +809,7 @@ mod tests {
797809
max_cltv_expiry: 0,
798810
htlc_minimum_msat: 1,
799811
},
812+
next_blinding_override: None,
800813
features: BlindedHopFeatures::empty(),
801814
},
802815
htlc_maximum_msat: 10_000

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ fn blinded_payment_path(
4949
htlc_minimum_msat: intro_node_min_htlc_opt.take()
5050
.unwrap_or_else(|| channel_upds[idx - 1].htlc_minimum_msat),
5151
},
52+
next_blinding_override: None,
5253
features: BlindedHopFeatures::empty(),
5354
},
5455
htlc_maximum_msat: intro_node_max_htlc_opt.take()

lightning/src/ln/channelmanager.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ pub struct BlindedForward {
226226
/// If needed, this determines how this HTLC should be failed backwards, based on whether we are
227227
/// the introduction node.
228228
pub failure: BlindedFailure,
229+
/// Overrides the next hop's [`msgs::UpdateAddHTLC::blinding_point`]. Set if this HTLC is being
230+
/// forwarded within a [`BlindedPaymentPath`] that was concatenated to another blinded path that
231+
/// starts at the next hop.
232+
pub next_blinding_override: Option<PublicKey>,
229233
}
230234

231235
impl PendingHTLCRouting {
@@ -5313,12 +5317,14 @@ where
53135317
blinded_failure: blinded.map(|b| b.failure),
53145318
});
53155319
let next_blinding_point = blinded.and_then(|b| {
5316-
let encrypted_tlvs_ss = self.node_signer.ecdh(
5317-
Recipient::Node, &b.inbound_blinding_point, None
5318-
).unwrap().secret_bytes();
5319-
onion_utils::next_hop_pubkey(
5320-
&self.secp_ctx, b.inbound_blinding_point, &encrypted_tlvs_ss
5321-
).ok()
5320+
b.next_blinding_override.or_else(|| {
5321+
let encrypted_tlvs_ss = self.node_signer.ecdh(
5322+
Recipient::Node, &b.inbound_blinding_point, None
5323+
).unwrap().secret_bytes();
5324+
onion_utils::next_hop_pubkey(
5325+
&self.secp_ctx, b.inbound_blinding_point, &encrypted_tlvs_ss
5326+
).ok()
5327+
})
53225328
});
53235329

53245330
// Forward the HTLC over the most appropriate channel with the corresponding peer,
@@ -11034,6 +11040,7 @@ impl_writeable_tlv_based!(PhantomRouteHints, {
1103411040
impl_writeable_tlv_based!(BlindedForward, {
1103511041
(0, inbound_blinding_point, required),
1103611042
(1, failure, (default_value, BlindedFailure::FromIntroductionNode)),
11043+
(3, next_blinding_override, option),
1103711044
});
1103811045

1103911046
impl_writeable_tlv_based_enum!(PendingHTLCRouting,

lightning/src/ln/msgs.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,7 @@ mod fuzzy_internal_msgs {
17641764
payment_constraints: PaymentConstraints,
17651765
features: BlindedHopFeatures,
17661766
intro_node_blinding_point: Option<PublicKey>,
1767+
next_blinding_override: Option<PublicKey>,
17671768
},
17681769
BlindedReceive {
17691770
sender_intended_htlc_amt_msat: u64,
@@ -2808,7 +2809,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
28082809
let mut reader = FixedLengthReader::new(&mut s, enc_tlvs.len() as u64);
28092810
match ChaChaPolyReadAdapter::read(&mut reader, rho)? {
28102811
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Forward(ForwardTlvs {
2811-
short_channel_id, payment_relay, payment_constraints, features
2812+
short_channel_id, payment_relay, payment_constraints, features, next_blinding_override
28122813
})} => {
28132814
if amt.is_some() || cltv_value.is_some() || total_msat.is_some() ||
28142815
keysend_preimage.is_some()
@@ -2821,6 +2822,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
28212822
payment_constraints,
28222823
features,
28232824
intro_node_blinding_point,
2825+
next_blinding_override,
28242826
})
28252827
},
28262828
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {

lightning/src/ln/onion_payment.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,14 @@ pub(super) fn create_fwd_pending_htlc_info(
7575
};
7676

7777
let (
78-
short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point
78+
short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
79+
next_blinding_override
7980
) = match hop_data {
8081
msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } =>
81-
(short_channel_id, amt_to_forward, outgoing_cltv_value, None),
82+
(short_channel_id, amt_to_forward, outgoing_cltv_value, None, None),
8283
msgs::InboundOnionPayload::BlindedForward {
8384
short_channel_id, payment_relay, payment_constraints, intro_node_blinding_point, features,
85+
next_blinding_override,
8486
} => {
8587
let (amt_to_forward, outgoing_cltv_value) = check_blinded_forward(
8688
msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features
@@ -93,7 +95,8 @@ pub(super) fn create_fwd_pending_htlc_info(
9395
err_data: vec![0; 32],
9496
}
9597
})?;
96-
(short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point)
98+
(short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
99+
next_blinding_override)
97100
},
98101
msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
99102
return Err(InboundHTLCErr {
@@ -110,6 +113,7 @@ pub(super) fn create_fwd_pending_htlc_info(
110113
blinded: intro_node_blinding_point.or(msg.blinding_point)
111114
.map(|bp| BlindedForward {
112115
inbound_blinding_point: bp,
116+
next_blinding_override,
113117
failure: intro_node_blinding_point
114118
.map(|_| BlindedFailure::FromIntroductionNode)
115119
.unwrap_or(BlindedFailure::FromBlindedNode),

lightning/src/routing/router.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref, S: Deref, SP: Size
151151
short_channel_id,
152152
payment_relay,
153153
payment_constraints,
154+
next_blinding_override: None,
154155
features: BlindedHopFeatures::empty(),
155156
},
156157
node_id: details.counterparty.node_id,

0 commit comments

Comments
 (0)