Skip to content

Commit aa90229

Browse files
committed
Distinguish Between Sender and User Custom TLVs
- This update introduces a clear separation between two types of custom TLVs: those sent by the sender for the user, and those added by the user to the reply path, which are expected to return with the response. - This commit establishes this distinction in the codebase at relevant points. - The next commit will build on this by providing an interface for users to add their own custom TLVs to the reply path, allowing them to receive specific data back in the response. Note: 1. Similar to keysend, for serialization purposes, user_custom_tlv are assigned a specific TLV number. 2. For uniformity, user_custom_tlv are assigned the lowest possible odd number after (1 << 16), which is 65537.
1 parent 53996cc commit aa90229

9 files changed

+196
-124
lines changed

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ fn custom_tlvs_to_blinded_path() {
13231323
);
13241324

13251325
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty()
1326-
.with_custom_tlvs(vec![((1 << 16) + 1, vec![42, 42])])
1326+
.with_sender_custom_tlvs(vec![((1 << 16) + 3, vec![42, 42])])
13271327
.unwrap();
13281328
nodes[0].node.send_payment(payment_hash, recipient_onion_fields.clone(),
13291329
PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
@@ -1336,11 +1336,11 @@ fn custom_tlvs_to_blinded_path() {
13361336
let path = &[&nodes[1]];
13371337
let args = PassAlongPathArgs::new(&nodes[0], path, amt_msat, payment_hash, ev)
13381338
.with_payment_secret(payment_secret)
1339-
.with_custom_tlvs(recipient_onion_fields.custom_tlvs.clone());
1339+
.with_sender_custom_tlvs(recipient_onion_fields.sender_custom_tlvs.clone());
13401340
do_pass_along_path(args);
13411341
claim_payment_along_route(
13421342
ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], payment_preimage)
1343-
.with_custom_tlvs(recipient_onion_fields.custom_tlvs.clone())
1343+
.with_sender_custom_tlvs(recipient_onion_fields.sender_custom_tlvs.clone())
13441344
);
13451345
}
13461346

lightning/src/ln/channelmanager.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ pub enum PendingHTLCRouting {
187187
/// For HTLCs received by LDK, this will ultimately be exposed in
188188
/// [`Event::PaymentClaimable::onion_fields`] as
189189
/// [`RecipientOnionFields::custom_tlvs`].
190-
custom_tlvs: Vec<(u64, Vec<u8>)>,
190+
sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
191+
/// Custom TLVs which were set by us through the reply path
192+
user_custom_tlvs: Vec<u8>,
191193
/// Set if this HTLC is the final hop in a multi-hop blinded path.
192194
requires_blinded_error: bool,
193195
},
@@ -217,7 +219,9 @@ pub enum PendingHTLCRouting {
217219
///
218220
/// For HTLCs received by LDK, these will ultimately bubble back up as
219221
/// [`RecipientOnionFields::custom_tlvs`].
220-
custom_tlvs: Vec<(u64, Vec<u8>)>,
222+
sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
223+
/// Custom TLVs which were set by us through the reply path
224+
user_custom_tlvs: Vec<u8>,
221225
/// Set if this HTLC is the final hop in a multi-hop blinded path.
222226
requires_blinded_error: bool,
223227
},
@@ -929,10 +933,10 @@ impl ClaimablePayments {
929933
}
930934
}
931935

932-
if let Some(RecipientOnionFields { custom_tlvs, .. }) = &payment.onion_fields {
933-
if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
936+
if let Some(RecipientOnionFields { sender_custom_tlvs, .. }) = &payment.onion_fields {
937+
if !custom_tlvs_known && sender_custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
934938
log_info!(logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
935-
&payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
939+
&payment_hash, log_iter!(sender_custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
936940
return Err(payment.htlcs);
937941
}
938942
}
@@ -5839,23 +5843,24 @@ where
58395843
let (cltv_expiry, onion_payload, payment_data, payment_context, phantom_shared_secret, mut onion_fields) = match routing {
58405844
PendingHTLCRouting::Receive {
58415845
payment_data, payment_metadata, payment_context,
5842-
incoming_cltv_expiry, phantom_shared_secret, custom_tlvs,
5846+
incoming_cltv_expiry, phantom_shared_secret, sender_custom_tlvs, user_custom_tlvs,
58435847
requires_blinded_error: _
58445848
} => {
58455849
let _legacy_hop_data = Some(payment_data.clone());
58465850
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
5847-
payment_metadata, custom_tlvs };
5851+
payment_metadata, sender_custom_tlvs, user_custom_tlvs };
58485852
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
58495853
Some(payment_data), payment_context, phantom_shared_secret, onion_fields)
58505854
},
58515855
PendingHTLCRouting::ReceiveKeysend {
58525856
payment_data, payment_preimage, payment_metadata,
5853-
incoming_cltv_expiry, custom_tlvs, requires_blinded_error: _
5857+
incoming_cltv_expiry, sender_custom_tlvs, user_custom_tlvs, requires_blinded_error: _
58545858
} => {
58555859
let onion_fields = RecipientOnionFields {
58565860
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
58575861
payment_metadata,
5858-
custom_tlvs,
5862+
sender_custom_tlvs,
5863+
user_custom_tlvs,
58595864
};
58605865
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
58615866
payment_data, None, None, onion_fields)
@@ -11627,17 +11632,19 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1162711632
(1, phantom_shared_secret, option),
1162811633
(2, incoming_cltv_expiry, required),
1162911634
(3, payment_metadata, option),
11630-
(5, custom_tlvs, optional_vec),
11635+
(5, sender_custom_tlvs, optional_vec),
1163111636
(7, requires_blinded_error, (default_value, false)),
1163211637
(9, payment_context, option),
11638+
(11, user_custom_tlvs, optional_vec),
1163311639
},
1163411640
(2, ReceiveKeysend) => {
1163511641
(0, payment_preimage, required),
1163611642
(1, requires_blinded_error, (default_value, false)),
1163711643
(2, incoming_cltv_expiry, required),
1163811644
(3, payment_metadata, option),
1163911645
(4, payment_data, option), // Added in 0.0.116
11640-
(5, custom_tlvs, optional_vec),
11646+
(5, sender_custom_tlvs, optional_vec),
11647+
(7, user_custom_tlvs, optional_vec),
1164111648
},
1164211649
);
1164311650

@@ -14441,7 +14448,8 @@ mod tests {
1444114448
payment_data: Some(msgs::FinalOnionHopData {
1444214449
payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
1444314450
}),
14444-
custom_tlvs: Vec::new(),
14451+
sender_custom_tlvs: Vec::new(),
14452+
user_custom_tlvs: Vec::new(),
1444514453
};
1444614454
// Check that if the amount we received + the penultimate hop extra fee is less than the sender
1444714455
// intended amount, we fail the payment.
@@ -14463,7 +14471,8 @@ mod tests {
1446314471
payment_data: Some(msgs::FinalOnionHopData {
1446414472
payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
1446514473
}),
14466-
custom_tlvs: Vec::new(),
14474+
sender_custom_tlvs: Vec::new(),
14475+
user_custom_tlvs: Vec::new(),
1446714476
};
1446814477
let current_height: u32 = node[0].node.best_block.read().unwrap().height;
1446914478
assert!(create_recv_pending_htlc_info(hop_data, [0; 32], PaymentHash([0; 32]),
@@ -14487,7 +14496,8 @@ mod tests {
1448714496
payment_data: Some(msgs::FinalOnionHopData {
1448814497
payment_secret: PaymentSecret([0; 32]), total_msat: 100,
1448914498
}),
14490-
custom_tlvs: Vec::new(),
14499+
sender_custom_tlvs: Vec::new(),
14500+
user_custom_tlvs: Vec::new(),
1449114501
}, [0; 32], PaymentHash([0; 32]), 100, 23, None, true, None, current_height,
1449214502
node[0].node.default_configuration.accept_mpp_keysend);
1449314503

lightning/src/ln/functional_test_utils.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,7 +2585,8 @@ pub struct PassAlongPathArgs<'a, 'b, 'c, 'd> {
25852585
pub clear_recipient_events: bool,
25862586
pub expected_preimage: Option<PaymentPreimage>,
25872587
pub is_probe: bool,
2588-
pub custom_tlvs: Vec<(u64, Vec<u8>)>,
2588+
pub sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
2589+
pub user_custom_tlvs: Vec<u8>,
25892590
pub payment_metadata: Option<Vec<u8>>,
25902591
}
25912592

@@ -2597,7 +2598,7 @@ impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
25972598
Self {
25982599
origin_node, expected_path, recv_value, payment_hash, payment_secret: None, event,
25992600
payment_claimable_expected: true, clear_recipient_events: true, expected_preimage: None,
2600-
is_probe: false, custom_tlvs: Vec::new(), payment_metadata: None,
2601+
is_probe: false, sender_custom_tlvs: Vec::new(), user_custom_tlvs: Vec::new(), payment_metadata: None,
26012602
}
26022603
}
26032604
pub fn without_clearing_recipient_events(mut self) -> Self {
@@ -2621,8 +2622,12 @@ impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
26212622
self.expected_preimage = Some(payment_preimage);
26222623
self
26232624
}
2624-
pub fn with_custom_tlvs(mut self, custom_tlvs: Vec<(u64, Vec<u8>)>) -> Self {
2625-
self.custom_tlvs = custom_tlvs;
2625+
pub fn with_sender_custom_tlvs(mut self, custom_tlvs: Vec<(u64, Vec<u8>)>) -> Self {
2626+
self.sender_custom_tlvs = custom_tlvs;
2627+
self
2628+
}
2629+
pub fn with_user_custom_tlvs(mut self, custom_tlvs: Vec<u8>) -> Self {
2630+
self.user_custom_tlvs = custom_tlvs;
26262631
self
26272632
}
26282633
pub fn with_payment_metadata(mut self, payment_metadata: Vec<u8>) -> Self {
@@ -2635,7 +2640,8 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
26352640
let PassAlongPathArgs {
26362641
origin_node, expected_path, recv_value, payment_hash: our_payment_hash,
26372642
payment_secret: our_payment_secret, event: ev, payment_claimable_expected,
2638-
clear_recipient_events, expected_preimage, is_probe, custom_tlvs, payment_metadata,
2643+
clear_recipient_events, expected_preimage, is_probe, sender_custom_tlvs, user_custom_tlvs,
2644+
payment_metadata,
26392645
} = args;
26402646

26412647
let mut payment_event = SendEvent::from_event(ev);
@@ -2668,7 +2674,8 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
26682674
assert_eq!(our_payment_hash, *payment_hash);
26692675
assert_eq!(node.node.get_our_node_id(), receiver_node_id.unwrap());
26702676
assert!(onion_fields.is_some());
2671-
assert_eq!(onion_fields.as_ref().unwrap().custom_tlvs, custom_tlvs);
2677+
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2678+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_tlvs, user_custom_tlvs);
26722679
assert_eq!(onion_fields.as_ref().unwrap().payment_metadata, payment_metadata);
26732680
match &purpose {
26742681
PaymentPurpose::Bolt11InvoicePayment { payment_preimage, payment_secret, .. } => {
@@ -2782,7 +2789,8 @@ pub struct ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
27822789
pub expected_min_htlc_overpay: Vec<u32>,
27832790
pub skip_last: bool,
27842791
pub payment_preimage: PaymentPreimage,
2785-
pub custom_tlvs: Vec<(u64, Vec<u8>)>,
2792+
pub sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
2793+
pub user_custom_tlvs: Vec<u8>,
27862794
// Allow forwarding nodes to have taken 1 msat more fee than expected based on the downstream
27872795
// fulfill amount.
27882796
//
@@ -2801,7 +2809,7 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28012809
Self {
28022810
origin_node, expected_paths, expected_extra_fees: vec![0; expected_paths.len()],
28032811
expected_min_htlc_overpay: vec![0; expected_paths.len()], skip_last: false, payment_preimage,
2804-
allow_1_msat_fee_overpay: false, custom_tlvs: vec![],
2812+
allow_1_msat_fee_overpay: false, sender_custom_tlvs: vec![], user_custom_tlvs: vec![],
28052813
}
28062814
}
28072815
pub fn skip_last(mut self, skip_last: bool) -> Self {
@@ -2820,16 +2828,16 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28202828
self.allow_1_msat_fee_overpay = true;
28212829
self
28222830
}
2823-
pub fn with_custom_tlvs(mut self, custom_tlvs: Vec<(u64, Vec<u8>)>) -> Self {
2824-
self.custom_tlvs = custom_tlvs;
2831+
pub fn with_sender_custom_tlvs(mut self, custom_tlvs: Vec<(u64, Vec<u8>)>) -> Self {
2832+
self.sender_custom_tlvs = custom_tlvs;
28252833
self
28262834
}
28272835
}
28282836

28292837
pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
28302838
let ClaimAlongRouteArgs {
28312839
origin_node, expected_paths, expected_extra_fees, expected_min_htlc_overpay, skip_last,
2832-
payment_preimage: our_payment_preimage, allow_1_msat_fee_overpay, custom_tlvs,
2840+
payment_preimage: our_payment_preimage, allow_1_msat_fee_overpay, sender_custom_tlvs, user_custom_tlvs,
28332841
} = args;
28342842
let claim_event = expected_paths[0].last().unwrap().node.get_and_clear_pending_events();
28352843
assert_eq!(claim_event.len(), 1);
@@ -2849,7 +2857,8 @@ pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
28492857
assert_eq!(preimage, our_payment_preimage);
28502858
assert_eq!(htlcs.len(), expected_paths.len()); // One per path.
28512859
assert_eq!(htlcs.iter().map(|h| h.value_msat).sum::<u64>(), amount_msat);
2852-
assert_eq!(onion_fields.as_ref().unwrap().custom_tlvs, custom_tlvs);
2860+
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2861+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_tlvs, user_custom_tlvs);
28532862
check_claimed_htlcs_match_route(origin_node, expected_paths, htlcs);
28542863
fwd_amt_msat = amount_msat;
28552864
},
@@ -2866,7 +2875,8 @@ pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
28662875
assert_eq!(&payment_hash.0, &Sha256::hash(&our_payment_preimage.0)[..]);
28672876
assert_eq!(htlcs.len(), expected_paths.len()); // One per path.
28682877
assert_eq!(htlcs.iter().map(|h| h.value_msat).sum::<u64>(), amount_msat);
2869-
assert_eq!(onion_fields.as_ref().unwrap().custom_tlvs, custom_tlvs);
2878+
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2879+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_tlvs, user_custom_tlvs);
28702880
check_claimed_htlcs_match_route(origin_node, expected_paths, htlcs);
28712881
fwd_amt_msat = amount_msat;
28722882
}

0 commit comments

Comments
 (0)