@@ -204,6 +204,12 @@ pub enum PendingHTLCRouting {
204204 /// [`Event::PaymentClaimable::onion_fields`] as
205205 /// [`RecipientOnionFields::sender_custom_tlvs`].
206206 sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
207+ /// Custom TLVs set by the receiver in the blinded path used to reach them.
208+ ///
209+ /// For HTLCs received by LDK, this will be exposed in
210+ /// [`Event::PaymentClaimable::onion_fields`] as
211+ /// [`RecipientOnionFields::user_custom_data`].
212+ user_custom_data: Vec<u8>,
207213 /// Set if this HTLC is the final hop in a multi-hop blinded path.
208214 requires_blinded_error: bool,
209215 },
@@ -234,6 +240,11 @@ pub enum PendingHTLCRouting {
234240 /// For HTLCs received by LDK, these will ultimately bubble back up as
235241 /// [`RecipientOnionFields::sender_custom_tlvs`].
236242 sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
243+ /// Custom TLVs set by the receiver in the blinded path used to reach them.
244+ ///
245+ /// For HTLCs received by LDK, these will ultimately bubble back up as
246+ /// [`RecipientOnionFields::user_custom_data`].
247+ user_custom_data: Vec<u8>,
237248 /// Set if this HTLC is the final hop in a multi-hop blinded path.
238249 requires_blinded_error: bool,
239250 /// Set if we are receiving a keysend to a blinded path, meaning we created the
@@ -6039,24 +6050,25 @@ where
60396050 PendingHTLCRouting::Receive {
60406051 payment_data, payment_metadata, payment_context,
60416052 incoming_cltv_expiry, phantom_shared_secret, sender_custom_tlvs,
6042- requires_blinded_error: _
6053+ user_custom_data, requires_blinded_error: _
60436054 } => {
60446055 let _legacy_hop_data = Some(payment_data.clone());
60456056 let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
6046- payment_metadata, sender_custom_tlvs };
6057+ payment_metadata, sender_custom_tlvs, user_custom_data };
60476058 (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
60486059 Some(payment_data), payment_context, phantom_shared_secret, onion_fields,
60496060 true)
60506061 },
60516062 PendingHTLCRouting::ReceiveKeysend {
60526063 payment_data, payment_preimage, payment_metadata,
6053- incoming_cltv_expiry, sender_custom_tlvs, requires_blinded_error: _ ,
6054- has_recipient_created_payment_secret,
6064+ incoming_cltv_expiry, sender_custom_tlvs, user_custom_data ,
6065+ requires_blinded_error: _, has_recipient_created_payment_secret,
60556066 } => {
60566067 let onion_fields = RecipientOnionFields {
60576068 payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
60586069 payment_metadata,
60596070 sender_custom_tlvs,
6071+ user_custom_data
60606072 };
60616073 (incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
60626074 payment_data, None, None, onion_fields, has_recipient_created_payment_secret)
@@ -12456,6 +12468,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1245612468 (5, sender_custom_tlvs, optional_vec),
1245712469 (7, requires_blinded_error, (default_value, false)),
1245812470 (9, payment_context, option),
12471+ (11, user_custom_data, optional_vec),
1245912472 },
1246012473 (2, ReceiveKeysend) => {
1246112474 (0, payment_preimage, required),
@@ -12465,6 +12478,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1246512478 (4, payment_data, option), // Added in 0.0.116
1246612479 (5, sender_custom_tlvs, optional_vec),
1246712480 (7, has_recipient_created_payment_secret, (default_value, false)),
12481+ (9, user_custom_data, optional_vec),
1246812482 },
1246912483);
1247012484
@@ -15472,7 +15486,7 @@ mod tests {
1547215486 payment_data: Some(msgs::FinalOnionHopData {
1547315487 payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
1547415488 }),
15475- sender_custom_tlvs: Vec::new(),
15489+ sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
1547615490 };
1547715491 // Check that if the amount we received + the penultimate hop extra fee is less than the sender
1547815492 // intended amount, we fail the payment.
@@ -15494,7 +15508,7 @@ mod tests {
1549415508 payment_data: Some(msgs::FinalOnionHopData {
1549515509 payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
1549615510 }),
15497- sender_custom_tlvs: Vec::new(),
15511+ sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
1549815512 };
1549915513 let current_height: u32 = node[0].node.best_block.read().unwrap().height;
1550015514 assert!(create_recv_pending_htlc_info(hop_data, [0; 32], PaymentHash([0; 32]),
@@ -15518,7 +15532,7 @@ mod tests {
1551815532 payment_data: Some(msgs::FinalOnionHopData {
1551915533 payment_secret: PaymentSecret([0; 32]), total_msat: 100,
1552015534 }),
15521- sender_custom_tlvs: Vec::new(),
15535+ sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
1552215536 }, [0; 32], PaymentHash([0; 32]), 100, 23, None, true, None, current_height);
1552315537
1552415538 // Should not return an error as this condition:
0 commit comments