@@ -32,7 +32,7 @@ use bitcoin::secp256k1::Secp256k1;
32
32
use bitcoin::{secp256k1, Sequence};
33
33
34
34
use crate::blinded_path::BlindedPath;
35
- use crate::blinded_path::payment::{PaymentConstraints, ReceiveTlvs};
35
+ use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, ReceiveTlvs};
36
36
use crate::chain;
37
37
use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
38
38
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
@@ -155,6 +155,8 @@ pub enum PendingHTLCRouting {
155
155
/// [`Event::PaymentClaimable::onion_fields`] as
156
156
/// [`RecipientOnionFields::payment_metadata`].
157
157
payment_metadata: Option<Vec<u8>>,
158
+ ///
159
+ payment_context: Option<PaymentContext>,
158
160
/// CLTV expiry of the received HTLC.
159
161
///
160
162
/// Used to track when we should expire pending HTLCs that go unclaimed.
@@ -352,6 +354,8 @@ enum OnionPayload {
352
354
/// This is only here for backwards-compatibility in serialization, in the future it can be
353
355
/// removed, breaking clients running 0.0.106 and earlier.
354
356
_legacy_hop_data: Option<msgs::FinalOnionHopData>,
357
+ ///
358
+ payment_context: Option<PaymentContext>,
355
359
},
356
360
/// Contains the payer-provided preimage.
357
361
Spontaneous(PaymentPreimage),
@@ -4516,13 +4520,14 @@ where
4516
4520
let blinded_failure = routing.blinded_failure();
4517
4521
let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
4518
4522
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: _
4521
4526
} => {
4522
4527
let _legacy_hop_data = Some(payment_data.clone());
4523
4528
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
4524
4529
payment_metadata, custom_tlvs };
4525
- (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
4530
+ (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data, payment_context },
4526
4531
Some(payment_data), phantom_shared_secret, onion_fields)
4527
4532
},
4528
4533
PendingHTLCRouting::ReceiveKeysend {
@@ -4700,7 +4705,7 @@ where
4700
4705
match payment_secrets.entry(payment_hash) {
4701
4706
hash_map::Entry::Vacant(_) => {
4702
4707
match claimable_htlc.onion_payload {
4703
- OnionPayload::Invoice { .. } => {
4708
+ OnionPayload::Invoice { ref payment_context, .. } => {
4704
4709
let payment_data = payment_data.unwrap();
4705
4710
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) {
4706
4711
Ok(result) => result,
@@ -4720,6 +4725,7 @@ where
4720
4725
let purpose = events::PaymentPurpose::InvoicePayment {
4721
4726
payment_preimage: payment_preimage.clone(),
4722
4727
payment_secret: payment_data.payment_secret,
4728
+ payment_context: payment_context.clone(),
4723
4729
};
4724
4730
check_total_value!(purpose);
4725
4731
},
@@ -4730,10 +4736,13 @@ where
4730
4736
}
4731
4737
},
4732
4738
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
+ };
4737
4746
let payment_data = payment_data.unwrap();
4738
4747
if inbound_payment.get().payment_secret != payment_data.payment_secret {
4739
4748
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
4746
4755
let purpose = events::PaymentPurpose::InvoicePayment {
4747
4756
payment_preimage: inbound_payment.get().payment_preimage,
4748
4757
payment_secret: payment_data.payment_secret,
4758
+ payment_context: payment_context.clone(),
4749
4759
};
4750
4760
let payment_claimable_generated = check_total_value!(purpose);
4751
4761
if payment_claimable_generated {
@@ -9794,6 +9804,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
9794
9804
(3, payment_metadata, option),
9795
9805
(5, custom_tlvs, optional_vec),
9796
9806
(7, requires_blinded_error, (default_value, false)),
9807
+ (9, payment_context, upgradable_option),
9797
9808
},
9798
9809
(2, ReceiveKeysend) => {
9799
9810
(0, payment_preimage, required),
@@ -9908,9 +9919,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
9908
9919
9909
9920
impl Writeable for ClaimableHTLC {
9910
9921
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),
9914
9927
};
9915
9928
write_tlv_fields!(writer, {
9916
9929
(0, self.prev_hop, required),
@@ -9922,6 +9935,7 @@ impl Writeable for ClaimableHTLC {
9922
9935
(6, self.cltv_expiry, required),
9923
9936
(8, keysend_preimage, option),
9924
9937
(10, self.counterparty_skimmed_fee_msat, option),
9938
+ (11, payment_context, option),
9925
9939
});
9926
9940
Ok(())
9927
9941
}
@@ -9939,6 +9953,7 @@ impl Readable for ClaimableHTLC {
9939
9953
(6, cltv_expiry, required),
9940
9954
(8, keysend_preimage, option),
9941
9955
(10, counterparty_skimmed_fee_msat, option),
9956
+ (11, payment_context, upgradable_option),
9942
9957
});
9943
9958
let payment_data: Option<msgs::FinalOnionHopData> = payment_data_opt;
9944
9959
let value = value_ser.0.unwrap();
@@ -9959,7 +9974,7 @@ impl Readable for ClaimableHTLC {
9959
9974
}
9960
9975
total_msat = Some(payment_data.as_ref().unwrap().total_msat);
9961
9976
}
9962
- OnionPayload::Invoice { _legacy_hop_data: payment_data }
9977
+ OnionPayload::Invoice { _legacy_hop_data: payment_data, payment_context }
9963
9978
},
9964
9979
};
9965
9980
Ok(Self {
@@ -11174,7 +11189,7 @@ where
11174
11189
return Err(DecodeError::InvalidValue);
11175
11190
}
11176
11191
let purpose = match &htlcs[0].onion_payload {
11177
- OnionPayload::Invoice { _legacy_hop_data } => {
11192
+ OnionPayload::Invoice { _legacy_hop_data, payment_context } => {
11178
11193
if let Some(hop_data) = _legacy_hop_data {
11179
11194
events::PaymentPurpose::InvoicePayment {
11180
11195
payment_preimage: match pending_inbound_payments.get(&payment_hash) {
@@ -11188,6 +11203,7 @@ where
11188
11203
}
11189
11204
},
11190
11205
payment_secret: hop_data.payment_secret,
11206
+ payment_context: payment_context.clone(),
11191
11207
}
11192
11208
} else { return Err(DecodeError::InvalidValue); }
11193
11209
},
0 commit comments