Skip to content

Commit f85fc8a

Browse files
committed
WIP: Pipe PaymentContext from PendingInboundPayment to Event
1 parent 73aedd4 commit f85fc8a

File tree

7 files changed

+56
-25
lines changed

7 files changed

+56
-25
lines changed

lightning/src/blinded_path/payment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub struct PaymentConstraints {
105105
///
106106
/// [`BlindedPath`]: crate::blinded_path::BlindedPath
107107
/// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable
108-
#[derive(Clone, Debug)]
108+
#[derive(Clone, Debug, Eq, PartialEq)]
109109
pub enum PaymentContext {
110110
/// The payment was made for an invoice requested from a BOLT 12 [`Offer`].
111111
///

lightning/src/events/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod bump_transaction;
1818

1919
pub use bump_transaction::BumpTransactionEvent;
2020

21+
use crate::blinded_path::payment::PaymentContext;
2122
use crate::sign::SpendableOutputDescriptor;
2223
use crate::ln::channelmanager::{InterceptId, PaymentId, RecipientOnionFields};
2324
use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
@@ -67,6 +68,8 @@ pub enum PaymentPurpose {
6768
/// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
6869
/// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
6970
payment_secret: PaymentSecret,
71+
///
72+
payment_context: Option<PaymentContext>,
7073
},
7174
/// Because this is a spontaneous payment, the payer generated their own preimage rather than us
7275
/// (the payee) providing a preimage.
@@ -86,6 +89,7 @@ impl PaymentPurpose {
8689
impl_writeable_tlv_based_enum!(PaymentPurpose,
8790
(0, InvoicePayment) => {
8891
(0, payment_preimage, option),
92+
(1, payment_context, upgradable_option),
8993
(2, payment_secret, required),
9094
};
9195
(2, SpontaneousPayment)
@@ -1052,10 +1056,14 @@ impl Writeable for Event {
10521056
} => {
10531057
1u8.write(writer)?;
10541058
let mut payment_secret = None;
1059+
let mut payment_context = None;
10551060
let payment_preimage;
10561061
match &purpose {
1057-
PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret: secret } => {
1062+
PaymentPurpose::InvoicePayment {
1063+
payment_preimage: preimage, payment_secret: secret, payment_context: context
1064+
} => {
10581065
payment_secret = Some(secret);
1066+
payment_context = context.as_ref();
10591067
payment_preimage = *preimage;
10601068
},
10611069
PaymentPurpose::SpontaneousPayment(preimage) => {
@@ -1076,6 +1084,7 @@ impl Writeable for Event {
10761084
(8, payment_preimage, option),
10771085
(9, onion_fields, option),
10781086
(10, skimmed_fee_opt, option),
1087+
(11, payment_context, option),
10791088
});
10801089
},
10811090
&Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => {
@@ -1298,6 +1307,7 @@ impl MaybeReadable for Event {
12981307
let mut payment_hash = PaymentHash([0; 32]);
12991308
let mut payment_preimage = None;
13001309
let mut payment_secret = None;
1310+
let mut payment_context = None;
13011311
let mut amount_msat = 0;
13021312
let mut counterparty_skimmed_fee_msat_opt = None;
13031313
let mut receiver_node_id = None;
@@ -1318,11 +1328,13 @@ impl MaybeReadable for Event {
13181328
(8, payment_preimage, option),
13191329
(9, onion_fields, option),
13201330
(10, counterparty_skimmed_fee_msat_opt, option),
1331+
(11, payment_context, upgradable_option),
13211332
});
13221333
let purpose = match payment_secret {
13231334
Some(secret) => PaymentPurpose::InvoicePayment {
13241335
payment_preimage,
1325-
payment_secret: secret
1336+
payment_secret: secret,
1337+
payment_context,
13261338
},
13271339
None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()),
13281340
None => return Err(msgs::DecodeError::InvalidValue),

lightning/src/ln/channelmanager.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use bitcoin::secp256k1::Secp256k1;
3232
use bitcoin::{secp256k1, Sequence};
3333

3434
use crate::blinded_path::BlindedPath;
35-
use crate::blinded_path::payment::{PaymentConstraints, ReceiveTlvs};
35+
use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, ReceiveTlvs};
3636
use crate::chain;
3737
use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
3838
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
@@ -155,6 +155,8 @@ pub enum PendingHTLCRouting {
155155
/// [`Event::PaymentClaimable::onion_fields`] as
156156
/// [`RecipientOnionFields::payment_metadata`].
157157
payment_metadata: Option<Vec<u8>>,
158+
///
159+
payment_context: Option<PaymentContext>,
158160
/// CLTV expiry of the received HTLC.
159161
///
160162
/// Used to track when we should expire pending HTLCs that go unclaimed.
@@ -352,6 +354,8 @@ enum OnionPayload {
352354
/// This is only here for backwards-compatibility in serialization, in the future it can be
353355
/// removed, breaking clients running 0.0.106 and earlier.
354356
_legacy_hop_data: Option<msgs::FinalOnionHopData>,
357+
///
358+
payment_context: Option<PaymentContext>,
355359
},
356360
/// Contains the payer-provided preimage.
357361
Spontaneous(PaymentPreimage),
@@ -4516,13 +4520,14 @@ where
45164520
let blinded_failure = routing.blinded_failure();
45174521
let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
45184522
PendingHTLCRouting::Receive {
4519-
payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
4520-
custom_tlvs, requires_blinded_error: _
4523+
payment_data, payment_metadata, payment_context,
4524+
incoming_cltv_expiry, phantom_shared_secret, custom_tlvs,
4525+
requires_blinded_error: _
45214526
} => {
45224527
let _legacy_hop_data = Some(payment_data.clone());
45234528
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
45244529
payment_metadata, custom_tlvs };
4525-
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
4530+
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data, payment_context },
45264531
Some(payment_data), phantom_shared_secret, onion_fields)
45274532
},
45284533
PendingHTLCRouting::ReceiveKeysend {
@@ -4700,7 +4705,7 @@ where
47004705
match payment_secrets.entry(payment_hash) {
47014706
hash_map::Entry::Vacant(_) => {
47024707
match claimable_htlc.onion_payload {
4703-
OnionPayload::Invoice { .. } => {
4708+
OnionPayload::Invoice { ref payment_context, .. } => {
47044709
let payment_data = payment_data.unwrap();
47054710
let (payment_preimage, min_final_cltv_expiry_delta) = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
47064711
Ok(result) => result,
@@ -4720,6 +4725,7 @@ where
47204725
let purpose = events::PaymentPurpose::InvoicePayment {
47214726
payment_preimage: payment_preimage.clone(),
47224727
payment_secret: payment_data.payment_secret,
4728+
payment_context: payment_context.clone(),
47234729
};
47244730
check_total_value!(purpose);
47254731
},
@@ -4730,10 +4736,13 @@ where
47304736
}
47314737
},
47324738
hash_map::Entry::Occupied(inbound_payment) => {
4733-
if let OnionPayload::Spontaneous(_) = claimable_htlc.onion_payload {
4734-
log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", &payment_hash);
4735-
fail_htlc!(claimable_htlc, payment_hash);
4736-
}
4739+
let payment_context = match claimable_htlc.onion_payload {
4740+
OnionPayload::Spontaneous(_) => {
4741+
log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", &payment_hash);
4742+
fail_htlc!(claimable_htlc, payment_hash);
4743+
},
4744+
OnionPayload::Invoice { ref payment_context, .. } => payment_context,
4745+
};
47374746
let payment_data = payment_data.unwrap();
47384747
if inbound_payment.get().payment_secret != payment_data.payment_secret {
47394748
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", &payment_hash);
@@ -4746,6 +4755,7 @@ where
47464755
let purpose = events::PaymentPurpose::InvoicePayment {
47474756
payment_preimage: inbound_payment.get().payment_preimage,
47484757
payment_secret: payment_data.payment_secret,
4758+
payment_context: payment_context.clone(),
47494759
};
47504760
let payment_claimable_generated = check_total_value!(purpose);
47514761
if payment_claimable_generated {
@@ -9794,6 +9804,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
97949804
(3, payment_metadata, option),
97959805
(5, custom_tlvs, optional_vec),
97969806
(7, requires_blinded_error, (default_value, false)),
9807+
(9, payment_context, upgradable_option),
97979808
},
97989809
(2, ReceiveKeysend) => {
97999810
(0, payment_preimage, required),
@@ -9908,9 +9919,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
99089919

99099920
impl Writeable for ClaimableHTLC {
99109921
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
9911-
let (payment_data, keysend_preimage) = match &self.onion_payload {
9912-
OnionPayload::Invoice { _legacy_hop_data } => (_legacy_hop_data.as_ref(), None),
9913-
OnionPayload::Spontaneous(preimage) => (None, Some(preimage)),
9922+
let (payment_data, keysend_preimage, payment_context) = match &self.onion_payload {
9923+
OnionPayload::Invoice { _legacy_hop_data, payment_context } => {
9924+
(_legacy_hop_data.as_ref(), None, payment_context.as_ref())
9925+
},
9926+
OnionPayload::Spontaneous(preimage) => (None, Some(preimage), None),
99149927
};
99159928
write_tlv_fields!(writer, {
99169929
(0, self.prev_hop, required),
@@ -9922,6 +9935,7 @@ impl Writeable for ClaimableHTLC {
99229935
(6, self.cltv_expiry, required),
99239936
(8, keysend_preimage, option),
99249937
(10, self.counterparty_skimmed_fee_msat, option),
9938+
(11, payment_context, option),
99259939
});
99269940
Ok(())
99279941
}
@@ -9939,6 +9953,7 @@ impl Readable for ClaimableHTLC {
99399953
(6, cltv_expiry, required),
99409954
(8, keysend_preimage, option),
99419955
(10, counterparty_skimmed_fee_msat, option),
9956+
(11, payment_context, upgradable_option),
99429957
});
99439958
let payment_data: Option<msgs::FinalOnionHopData> = payment_data_opt;
99449959
let value = value_ser.0.unwrap();
@@ -9959,7 +9974,7 @@ impl Readable for ClaimableHTLC {
99599974
}
99609975
total_msat = Some(payment_data.as_ref().unwrap().total_msat);
99619976
}
9962-
OnionPayload::Invoice { _legacy_hop_data: payment_data }
9977+
OnionPayload::Invoice { _legacy_hop_data: payment_data, payment_context }
99639978
},
99649979
};
99659980
Ok(Self {
@@ -11174,7 +11189,7 @@ where
1117411189
return Err(DecodeError::InvalidValue);
1117511190
}
1117611191
let purpose = match &htlcs[0].onion_payload {
11177-
OnionPayload::Invoice { _legacy_hop_data } => {
11192+
OnionPayload::Invoice { _legacy_hop_data, payment_context } => {
1117811193
if let Some(hop_data) = _legacy_hop_data {
1117911194
events::PaymentPurpose::InvoicePayment {
1118011195
payment_preimage: match pending_inbound_payments.get(&payment_hash) {
@@ -11188,6 +11203,7 @@ where
1118811203
}
1118911204
},
1119011205
payment_secret: hop_data.payment_secret,
11206+
payment_context: payment_context.clone(),
1119111207
}
1119211208
} else { return Err(DecodeError::InvalidValue); }
1119311209
},

lightning/src/ln/inbound_payment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl ExpandedKey {
102102
///
103103
/// [`Offer::metadata`]: crate::offers::offer::Offer::metadata
104104
/// [`Offer::signing_pubkey`]: crate::offers::offer::Offer::signing_pubkey
105-
#[derive(Clone, Copy, Debug, PartialEq)]
105+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
106106
pub(crate) struct Nonce(pub(crate) [u8; Self::LENGTH]);
107107

108108
impl Nonce {

lightning/src/ln/msgs.rs

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

16631663
mod fuzzy_internal_msgs {
16641664
use bitcoin::secp256k1::PublicKey;
1665-
use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay};
1665+
use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, PaymentRelay};
16661666
use crate::prelude::*;
16671667
use crate::ln::{PaymentPreimage, PaymentSecret};
16681668
use crate::ln::features::BlindedHopFeatures;
@@ -1699,6 +1699,7 @@ mod fuzzy_internal_msgs {
16991699
cltv_expiry_height: u32,
17001700
payment_secret: PaymentSecret,
17011701
payment_constraints: PaymentConstraints,
1702+
payment_context: Option<PaymentContext>,
17021703
intro_node_blinding_point: Option<PublicKey>,
17031704
keysend_preimage: Option<PaymentPreimage>,
17041705
}
@@ -2666,7 +2667,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
26662667
})
26672668
},
26682669
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {
2669-
payment_secret, payment_constraints, payment_context: _
2670+
payment_secret, payment_constraints, payment_context
26702671
})} => {
26712672
if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
26722673
Ok(Self::BlindedReceive {
@@ -2675,6 +2676,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
26752676
cltv_expiry_height: cltv_value.ok_or(DecodeError::InvalidValue)?,
26762677
payment_secret,
26772678
payment_constraints,
2679+
payment_context,
26782680
intro_node_blinding_point,
26792681
keysend_preimage,
26802682
})

lightning/src/ln/onion_payment.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,17 @@ pub(super) fn create_recv_pending_htlc_info(
129129
) -> Result<PendingHTLCInfo, InboundHTLCErr> {
130130
let (
131131
payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, onion_cltv_expiry,
132-
payment_metadata, requires_blinded_error
132+
payment_metadata, payment_context, requires_blinded_error
133133
) = match hop_data {
134134
msgs::InboundOnionPayload::Receive {
135135
payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
136136
cltv_expiry_height, payment_metadata, ..
137137
} =>
138138
(payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
139-
cltv_expiry_height, payment_metadata, false),
139+
cltv_expiry_height, payment_metadata, None, false),
140140
msgs::InboundOnionPayload::BlindedReceive {
141141
sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
142-
intro_node_blinding_point, payment_constraints, keysend_preimage, ..
142+
intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage, ..
143143
} => {
144144
check_blinded_payment_constraints(
145145
sender_intended_htlc_amt_msat, cltv_expiry, &payment_constraints
@@ -153,7 +153,7 @@ pub(super) fn create_recv_pending_htlc_info(
153153
})?;
154154
let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
155155
(Some(payment_data), keysend_preimage, Vec::new(),
156-
sender_intended_htlc_amt_msat, cltv_expiry_height, None,
156+
sender_intended_htlc_amt_msat, cltv_expiry_height, None, payment_context,
157157
intro_node_blinding_point.is_none())
158158
}
159159
msgs::InboundOnionPayload::Forward { .. } => {
@@ -239,6 +239,7 @@ pub(super) fn create_recv_pending_htlc_info(
239239
PendingHTLCRouting::Receive {
240240
payment_data: data,
241241
payment_metadata,
242+
payment_context,
242243
incoming_cltv_expiry: onion_cltv_expiry,
243244
phantom_shared_secret,
244245
custom_tlvs,

lightning/src/offers/offer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ use std::time::SystemTime;
115115
pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Offer ~~~~~~";
116116

117117
/// An identifier for an [`Offer`] built using [`DerivedMetadata`].
118-
#[derive(Clone, Copy, Debug, PartialEq)]
118+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
119119
pub struct OfferId(Nonce);
120120

121121
impl Writeable for OfferId {

0 commit comments

Comments
 (0)