Skip to content

Commit 2170c9c

Browse files
committed
Introduce user_custom_data
1 parent ac9a7da commit 2170c9c

File tree

9 files changed

+131
-41
lines changed

9 files changed

+131
-41
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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:

lightning/src/ln/functional_test_utils.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,6 +2646,7 @@ pub struct PassAlongPathArgs<'a, 'b, 'c, 'd> {
26462646
pub expected_preimage: Option<PaymentPreimage>,
26472647
pub is_probe: bool,
26482648
pub sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
2649+
pub user_custom_data: Vec<u8>,
26492650
pub payment_metadata: Option<Vec<u8>>,
26502651
pub expected_failure: Option<HTLCDestination>,
26512652
}
@@ -2658,7 +2659,7 @@ impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
26582659
Self {
26592660
origin_node, expected_path, recv_value, payment_hash, payment_secret: None, event,
26602661
payment_claimable_expected: true, clear_recipient_events: true, expected_preimage: None,
2661-
is_probe: false, sender_custom_tlvs: Vec::new(), payment_metadata: None, expected_failure: None,
2662+
is_probe: false, sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(), payment_metadata: None, expected_failure: None,
26622663
}
26632664
}
26642665
pub fn without_clearing_recipient_events(mut self) -> Self {
@@ -2701,7 +2702,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
27012702
let PassAlongPathArgs {
27022703
origin_node, expected_path, recv_value, payment_hash: our_payment_hash,
27032704
payment_secret: our_payment_secret, event: ev, payment_claimable_expected,
2704-
clear_recipient_events, expected_preimage, is_probe, sender_custom_tlvs, payment_metadata,
2705+
clear_recipient_events, expected_preimage, is_probe, sender_custom_tlvs, user_custom_data, payment_metadata,
27052706
expected_failure
27062707
} = args;
27072708

@@ -2736,6 +2737,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
27362737
assert_eq!(node.node.get_our_node_id(), receiver_node_id.unwrap());
27372738
assert!(onion_fields.is_some());
27382739
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2740+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_data, user_custom_data);
27392741
assert_eq!(onion_fields.as_ref().unwrap().payment_metadata, payment_metadata);
27402742
match &purpose {
27412743
PaymentPurpose::Bolt11InvoicePayment { payment_preimage, payment_secret, .. } => {
@@ -2855,6 +2857,7 @@ pub struct ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28552857
pub skip_last: bool,
28562858
pub payment_preimage: PaymentPreimage,
28572859
pub sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
2860+
pub user_custom_data: Vec<u8>,
28582861
// Allow forwarding nodes to have taken 1 msat more fee than expected based on the downstream
28592862
// fulfill amount.
28602863
//
@@ -2873,7 +2876,7 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28732876
Self {
28742877
origin_node, expected_paths, expected_extra_fees: vec![0; expected_paths.len()],
28752878
expected_min_htlc_overpay: vec![0; expected_paths.len()], skip_last: false, payment_preimage,
2876-
allow_1_msat_fee_overpay: false, sender_custom_tlvs: vec![],
2879+
allow_1_msat_fee_overpay: false, sender_custom_tlvs: vec![], user_custom_data: vec![]
28772880
}
28782881
}
28792882
pub fn skip_last(mut self, skip_last: bool) -> Self {
@@ -2896,12 +2899,17 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28962899
self.sender_custom_tlvs = sender_custom_tlvs;
28972900
self
28982901
}
2902+
pub fn with_user_custom_data(mut self, user_custom_data: Vec<u8>) -> Self {
2903+
self.user_custom_data = user_custom_data;
2904+
self
2905+
}
28992906
}
29002907

29012908
pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
29022909
let ClaimAlongRouteArgs {
29032910
origin_node, expected_paths, expected_extra_fees, expected_min_htlc_overpay, skip_last,
29042911
payment_preimage: our_payment_preimage, allow_1_msat_fee_overpay, sender_custom_tlvs,
2912+
user_custom_data
29052913
} = args;
29062914
let claim_event = expected_paths[0].last().unwrap().node.get_and_clear_pending_events();
29072915
assert_eq!(claim_event.len(), 1);
@@ -2939,6 +2947,7 @@ pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
29392947
assert_eq!(htlcs.len(), expected_paths.len()); // One per path.
29402948
assert_eq!(htlcs.iter().map(|h| h.value_msat).sum::<u64>(), amount_msat);
29412949
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2950+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_data, user_custom_data);
29422951
check_claimed_htlcs_match_route(origin_node, expected_paths, htlcs);
29432952
fwd_amt_msat = amount_msat;
29442953
}

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fn large_payment_metadata() {
6161
payment_metadata: None,
6262
keysend_preimage: None,
6363
sender_custom_tlvs: &Vec::new(),
64+
user_custom_data: &Vec::new(),
6465
sender_intended_htlc_amt_msat: MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
6566
cltv_expiry_height: nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
6667
}.serialized_length();
@@ -77,7 +78,7 @@ fn large_payment_metadata() {
7778
let mut recipient_onion_max_md_size = RecipientOnionFields {
7879
payment_secret: Some(payment_secret),
7980
payment_metadata: Some(payment_metadata.clone()),
80-
sender_custom_tlvs: Vec::new(),
81+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
8182
};
8283
nodes[0].node.send_payment(payment_hash, recipient_onion_max_md_size.clone(), PaymentId(payment_hash.0), route_0_1.route_params.clone().unwrap(), Retry::Attempts(0)).unwrap();
8384
check_added_monitors!(nodes[0], 1);
@@ -125,7 +126,7 @@ fn large_payment_metadata() {
125126
let mut recipient_onion_allows_2_hops = RecipientOnionFields {
126127
payment_secret: Some(payment_secret_2),
127128
payment_metadata: Some(vec![42; max_metadata_len - INTERMED_PAYLOAD_LEN_ESTIMATE]),
128-
sender_custom_tlvs: Vec::new(),
129+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
129130
};
130131
let mut route_params_0_2 = route_0_2.route_params.clone().unwrap();
131132
route_params_0_2.payment_params.max_path_length = 2;
@@ -190,7 +191,8 @@ fn one_hop_blinded_path_with_custom_tlv() {
190191
intro_node_blinding_point: Some(blinded_path.blinding_point()),
191192
keysend_preimage: None,
192193
invoice_request: None,
193-
sender_custom_tlvs: &Vec::new()
194+
sender_custom_tlvs: &Vec::new(),
195+
user_custom_data: &Vec::new()
194196
}.serialized_length();
195197
let max_custom_tlv_len = 1300
196198
- crate::util::ser::BigSize(CUSTOM_TLV_TYPE).serialized_length() // custom TLV type

0 commit comments

Comments
 (0)