Skip to content

Commit 9be364f

Browse files
committed
Pass PaymentContext through HTLC processing
PendingInboundPayment::BlindedReceive includes a PaymentContext, which the recipient includes in each blinded path. Included this when processing HTLCs in ChannelManager, first into PendingHTLCRouting and then to OnionPayload. Later, this will be included in the PaymentPurpose when surfaced to user in PaymentClaimable and PaymentClaimed events.
1 parent c881538 commit 9be364f

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

lightning/src/blinded_path/payment.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ pub struct PaymentConstraints {
104104
///
105105
/// [`BlindedPath`]: crate::blinded_path::BlindedPath
106106
/// [`PaymentPurpose`]: crate::events::PaymentPurpose
107-
#[derive(Clone, Debug)]
107+
#[derive(Clone, Debug, Eq, PartialEq)]
108108
pub enum PaymentContext {
109109
/// The payment context was unknown.
110110
Unknown(UnknownPaymentContext),
111111
}
112112

113113
/// An unknown payment context.
114-
#[derive(Clone, Debug)]
114+
#[derive(Clone, Debug, Eq, PartialEq)]
115115
pub struct UnknownPaymentContext(());
116116

117117
impl PaymentContext {

lightning/src/ln/channelmanager.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ pub enum PendingHTLCRouting {
155155
/// [`Event::PaymentClaimable::onion_fields`] as
156156
/// [`RecipientOnionFields::payment_metadata`].
157157
payment_metadata: Option<Vec<u8>>,
158+
/// The context of the payment included by the recipient in a blinded path, or `None` if a
159+
/// blinded path was not used.
160+
///
161+
/// Used in part to determine the [`events::PaymentPurpose`].
162+
payment_context: Option<PaymentContext>,
158163
/// CLTV expiry of the received HTLC.
159164
///
160165
/// Used to track when we should expire pending HTLCs that go unclaimed.
@@ -352,6 +357,11 @@ enum OnionPayload {
352357
/// This is only here for backwards-compatibility in serialization, in the future it can be
353358
/// removed, breaking clients running 0.0.106 and earlier.
354359
_legacy_hop_data: Option<msgs::FinalOnionHopData>,
360+
/// The context of the payment included by the recipient in a blinded path, or `None` if a
361+
/// blinded path was not used.
362+
///
363+
/// Used in part to determine the [`events::PaymentPurpose`].
364+
payment_context: Option<PaymentContext>,
355365
},
356366
/// Contains the payer-provided preimage.
357367
Spontaneous(PaymentPreimage),
@@ -5336,13 +5346,14 @@ where
53365346
let blinded_failure = routing.blinded_failure();
53375347
let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
53385348
PendingHTLCRouting::Receive {
5339-
payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
5340-
custom_tlvs, requires_blinded_error: _
5349+
payment_data, payment_metadata, payment_context,
5350+
incoming_cltv_expiry, phantom_shared_secret, custom_tlvs,
5351+
requires_blinded_error: _
53415352
} => {
53425353
let _legacy_hop_data = Some(payment_data.clone());
53435354
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
53445355
payment_metadata, custom_tlvs };
5345-
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
5356+
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data, payment_context },
53465357
Some(payment_data), phantom_shared_secret, onion_fields)
53475358
},
53485359
PendingHTLCRouting::ReceiveKeysend {
@@ -10677,6 +10688,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1067710688
(3, payment_metadata, option),
1067810689
(5, custom_tlvs, optional_vec),
1067910690
(7, requires_blinded_error, (default_value, false)),
10691+
(9, payment_context, option),
1068010692
},
1068110693
(2, ReceiveKeysend) => {
1068210694
(0, payment_preimage, required),
@@ -10791,9 +10803,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
1079110803

1079210804
impl Writeable for ClaimableHTLC {
1079310805
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
10794-
let (payment_data, keysend_preimage) = match &self.onion_payload {
10795-
OnionPayload::Invoice { _legacy_hop_data } => (_legacy_hop_data.as_ref(), None),
10796-
OnionPayload::Spontaneous(preimage) => (None, Some(preimage)),
10806+
let (payment_data, keysend_preimage, payment_context) = match &self.onion_payload {
10807+
OnionPayload::Invoice { _legacy_hop_data, payment_context } => {
10808+
(_legacy_hop_data.as_ref(), None, payment_context.as_ref())
10809+
},
10810+
OnionPayload::Spontaneous(preimage) => (None, Some(preimage), None),
1079710811
};
1079810812
write_tlv_fields!(writer, {
1079910813
(0, self.prev_hop, required),
@@ -10805,6 +10819,7 @@ impl Writeable for ClaimableHTLC {
1080510819
(6, self.cltv_expiry, required),
1080610820
(8, keysend_preimage, option),
1080710821
(10, self.counterparty_skimmed_fee_msat, option),
10822+
(11, payment_context, option),
1080810823
});
1080910824
Ok(())
1081010825
}
@@ -10822,6 +10837,7 @@ impl Readable for ClaimableHTLC {
1082210837
(6, cltv_expiry, required),
1082310838
(8, keysend_preimage, option),
1082410839
(10, counterparty_skimmed_fee_msat, option),
10840+
(11, payment_context, option),
1082510841
});
1082610842
let payment_data: Option<msgs::FinalOnionHopData> = payment_data_opt;
1082710843
let value = value_ser.0.unwrap();
@@ -10842,7 +10858,7 @@ impl Readable for ClaimableHTLC {
1084210858
}
1084310859
total_msat = Some(payment_data.as_ref().unwrap().total_msat);
1084410860
}
10845-
OnionPayload::Invoice { _legacy_hop_data: payment_data }
10861+
OnionPayload::Invoice { _legacy_hop_data: payment_data, payment_context }
1084610862
},
1084710863
};
1084810864
Ok(Self {
@@ -12079,7 +12095,7 @@ where
1207912095
return Err(DecodeError::InvalidValue);
1208012096
}
1208112097
let purpose = match &htlcs[0].onion_payload {
12082-
OnionPayload::Invoice { _legacy_hop_data } => {
12098+
OnionPayload::Invoice { _legacy_hop_data, payment_context: _ } => {
1208312099
if let Some(hop_data) = _legacy_hop_data {
1208412100
events::PaymentPurpose::InvoicePayment {
1208512101
payment_preimage: match pending_inbound_payments.get(&payment_hash) {

lightning/src/ln/msgs.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ pub struct FinalOnionHopData {
16721672

16731673
mod fuzzy_internal_msgs {
16741674
use bitcoin::secp256k1::PublicKey;
1675-
use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay};
1675+
use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, PaymentRelay};
16761676
use crate::ln::{PaymentPreimage, PaymentSecret};
16771677
use crate::ln::features::BlindedHopFeatures;
16781678
use super::{FinalOnionHopData, TrampolineOnionPacket};
@@ -1711,6 +1711,7 @@ mod fuzzy_internal_msgs {
17111711
cltv_expiry_height: u32,
17121712
payment_secret: PaymentSecret,
17131713
payment_constraints: PaymentConstraints,
1714+
payment_context: PaymentContext,
17141715
intro_node_blinding_point: Option<PublicKey>,
17151716
keysend_preimage: Option<PaymentPreimage>,
17161717
custom_tlvs: Vec<(u64, Vec<u8>)>,
@@ -2713,7 +2714,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
27132714
})
27142715
},
27152716
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {
2716-
payment_secret, payment_constraints, payment_context: _
2717+
payment_secret, payment_constraints, payment_context
27172718
})} => {
27182719
if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
27192720
Ok(Self::BlindedReceive {
@@ -2722,6 +2723,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
27222723
cltv_expiry_height: cltv_value.ok_or(DecodeError::InvalidValue)?,
27232724
payment_secret,
27242725
payment_constraints,
2726+
payment_context,
27252727
intro_node_blinding_point,
27262728
keysend_preimage,
27272729
custom_tlvs,

lightning/src/ln/onion_payment.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,18 @@ pub(super) fn create_recv_pending_htlc_info(
131131
) -> Result<PendingHTLCInfo, InboundHTLCErr> {
132132
let (
133133
payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, onion_cltv_expiry,
134-
payment_metadata, requires_blinded_error
134+
payment_metadata, payment_context, requires_blinded_error
135135
) = match hop_data {
136136
msgs::InboundOnionPayload::Receive {
137137
payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
138138
cltv_expiry_height, payment_metadata, ..
139139
} =>
140140
(payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
141-
cltv_expiry_height, payment_metadata, false),
141+
cltv_expiry_height, payment_metadata, None, false),
142142
msgs::InboundOnionPayload::BlindedReceive {
143143
sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
144-
intro_node_blinding_point, payment_constraints, keysend_preimage, custom_tlvs
144+
intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage,
145+
custom_tlvs
145146
} => {
146147
check_blinded_payment_constraints(
147148
sender_intended_htlc_amt_msat, cltv_expiry, &payment_constraints
@@ -155,7 +156,7 @@ pub(super) fn create_recv_pending_htlc_info(
155156
})?;
156157
let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
157158
(Some(payment_data), keysend_preimage, custom_tlvs,
158-
sender_intended_htlc_amt_msat, cltv_expiry_height, None,
159+
sender_intended_htlc_amt_msat, cltv_expiry_height, None, Some(payment_context),
159160
intro_node_blinding_point.is_none())
160161
}
161162
msgs::InboundOnionPayload::Forward { .. } => {
@@ -241,6 +242,7 @@ pub(super) fn create_recv_pending_htlc_info(
241242
PendingHTLCRouting::Receive {
242243
payment_data: data,
243244
payment_metadata,
245+
payment_context,
244246
incoming_cltv_expiry: onion_cltv_expiry,
245247
phantom_shared_secret,
246248
custom_tlvs,

0 commit comments

Comments
 (0)