Skip to content

Commit c256f30

Browse files
committed
Introduce user_custom_data
1 parent 58e89d1 commit c256f30

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
@@ -195,6 +195,12 @@ pub enum PendingHTLCRouting {
195195
/// [`Event::PaymentClaimable::onion_fields`] as
196196
/// [`RecipientOnionFields::sender_custom_tlvs`].
197197
sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
198+
/// Custom TLVs set by the receiver in the blinded path used to reach them.
199+
///
200+
/// For HTLCs received by LDK, this will be exposed in
201+
/// [`Event::PaymentClaimable::onion_fields`] as
202+
/// [`RecipientOnionFields::user_custom_data`].
203+
user_custom_data: Vec<u8>,
198204
/// Set if this HTLC is the final hop in a multi-hop blinded path.
199205
requires_blinded_error: bool,
200206
},
@@ -225,6 +231,11 @@ pub enum PendingHTLCRouting {
225231
/// For HTLCs received by LDK, these will ultimately bubble back up as
226232
/// [`RecipientOnionFields::sender_custom_tlvs`].
227233
sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
234+
/// Custom TLVs set by the receiver in the blinded path used to reach them.
235+
///
236+
/// For HTLCs received by LDK, these will ultimately bubble back up as
237+
/// [`RecipientOnionFields::user_custom_data`].
238+
user_custom_data: Vec<u8>,
228239
/// Set if this HTLC is the final hop in a multi-hop blinded path.
229240
requires_blinded_error: bool,
230241
/// Set if we are receiving a keysend to a blinded path, meaning we created the
@@ -6052,24 +6063,25 @@ where
60526063
PendingHTLCRouting::Receive {
60536064
payment_data, payment_metadata, payment_context,
60546065
incoming_cltv_expiry, phantom_shared_secret, sender_custom_tlvs,
6055-
requires_blinded_error: _
6066+
user_custom_data, requires_blinded_error: _
60566067
} => {
60576068
let _legacy_hop_data = Some(payment_data.clone());
60586069
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
6059-
payment_metadata, sender_custom_tlvs };
6070+
payment_metadata, sender_custom_tlvs, user_custom_data };
60606071
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
60616072
Some(payment_data), payment_context, phantom_shared_secret, onion_fields,
60626073
true)
60636074
},
60646075
PendingHTLCRouting::ReceiveKeysend {
60656076
payment_data, payment_preimage, payment_metadata,
6066-
incoming_cltv_expiry, sender_custom_tlvs, requires_blinded_error: _,
6067-
has_recipient_created_payment_secret,
6077+
incoming_cltv_expiry, sender_custom_tlvs, user_custom_data,
6078+
requires_blinded_error: _, has_recipient_created_payment_secret,
60686079
} => {
60696080
let onion_fields = RecipientOnionFields {
60706081
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
60716082
payment_metadata,
60726083
sender_custom_tlvs,
6084+
user_custom_data
60736085
};
60746086
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
60756087
payment_data, None, None, onion_fields, has_recipient_created_payment_secret)
@@ -12392,6 +12404,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1239212404
(5, sender_custom_tlvs, optional_vec),
1239312405
(7, requires_blinded_error, (default_value, false)),
1239412406
(9, payment_context, option),
12407+
(11, user_custom_data, optional_vec),
1239512408
},
1239612409
(2, ReceiveKeysend) => {
1239712410
(0, payment_preimage, required),
@@ -12401,6 +12414,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
1240112414
(4, payment_data, option), // Added in 0.0.116
1240212415
(5, sender_custom_tlvs, optional_vec),
1240312416
(7, has_recipient_created_payment_secret, (default_value, false)),
12417+
(9, user_custom_data, optional_vec),
1240412418
},
1240512419
);
1240612420

@@ -15365,7 +15379,7 @@ mod tests {
1536515379
payment_data: Some(msgs::FinalOnionHopData {
1536615380
payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
1536715381
}),
15368-
sender_custom_tlvs: Vec::new(),
15382+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
1536915383
};
1537015384
// Check that if the amount we received + the penultimate hop extra fee is less than the sender
1537115385
// intended amount, we fail the payment.
@@ -15387,7 +15401,7 @@ mod tests {
1538715401
payment_data: Some(msgs::FinalOnionHopData {
1538815402
payment_secret: PaymentSecret([0; 32]), total_msat: sender_intended_amt_msat,
1538915403
}),
15390-
sender_custom_tlvs: Vec::new(),
15404+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
1539115405
};
1539215406
let current_height: u32 = node[0].node.best_block.read().unwrap().height;
1539315407
assert!(create_recv_pending_htlc_info(hop_data, [0; 32], PaymentHash([0; 32]),
@@ -15411,7 +15425,7 @@ mod tests {
1541115425
payment_data: Some(msgs::FinalOnionHopData {
1541215426
payment_secret: PaymentSecret([0; 32]), total_msat: 100,
1541315427
}),
15414-
sender_custom_tlvs: Vec::new(),
15428+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
1541515429
}, [0; 32], PaymentHash([0; 32]), 100, 23, None, true, None, current_height);
1541615430

1541715431
// 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
@@ -2634,6 +2634,7 @@ pub struct PassAlongPathArgs<'a, 'b, 'c, 'd> {
26342634
pub expected_preimage: Option<PaymentPreimage>,
26352635
pub is_probe: bool,
26362636
pub sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
2637+
pub user_custom_data: Vec<u8>,
26372638
pub payment_metadata: Option<Vec<u8>>,
26382639
pub expected_failure: Option<HTLCDestination>,
26392640
}
@@ -2646,7 +2647,7 @@ impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
26462647
Self {
26472648
origin_node, expected_path, recv_value, payment_hash, payment_secret: None, event,
26482649
payment_claimable_expected: true, clear_recipient_events: true, expected_preimage: None,
2649-
is_probe: false, sender_custom_tlvs: Vec::new(), payment_metadata: None, expected_failure: None,
2650+
is_probe: false, sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(), payment_metadata: None, expected_failure: None,
26502651
}
26512652
}
26522653
pub fn without_clearing_recipient_events(mut self) -> Self {
@@ -2689,7 +2690,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
26892690
let PassAlongPathArgs {
26902691
origin_node, expected_path, recv_value, payment_hash: our_payment_hash,
26912692
payment_secret: our_payment_secret, event: ev, payment_claimable_expected,
2692-
clear_recipient_events, expected_preimage, is_probe, sender_custom_tlvs, payment_metadata,
2693+
clear_recipient_events, expected_preimage, is_probe, sender_custom_tlvs, user_custom_data, payment_metadata,
26932694
expected_failure
26942695
} = args;
26952696

@@ -2724,6 +2725,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
27242725
assert_eq!(node.node.get_our_node_id(), receiver_node_id.unwrap());
27252726
assert!(onion_fields.is_some());
27262727
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2728+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_data, user_custom_data);
27272729
assert_eq!(onion_fields.as_ref().unwrap().payment_metadata, payment_metadata);
27282730
match &purpose {
27292731
PaymentPurpose::Bolt11InvoicePayment { payment_preimage, payment_secret, .. } => {
@@ -2843,6 +2845,7 @@ pub struct ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28432845
pub skip_last: bool,
28442846
pub payment_preimage: PaymentPreimage,
28452847
pub sender_custom_tlvs: Vec<(u64, Vec<u8>)>,
2848+
pub user_custom_data: Vec<u8>,
28462849
// Allow forwarding nodes to have taken 1 msat more fee than expected based on the downstream
28472850
// fulfill amount.
28482851
//
@@ -2861,7 +2864,7 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28612864
Self {
28622865
origin_node, expected_paths, expected_extra_fees: vec![0; expected_paths.len()],
28632866
expected_min_htlc_overpay: vec![0; expected_paths.len()], skip_last: false, payment_preimage,
2864-
allow_1_msat_fee_overpay: false, sender_custom_tlvs: vec![],
2867+
allow_1_msat_fee_overpay: false, sender_custom_tlvs: vec![], user_custom_data: vec![]
28652868
}
28662869
}
28672870
pub fn skip_last(mut self, skip_last: bool) -> Self {
@@ -2884,12 +2887,17 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
28842887
self.sender_custom_tlvs = sender_custom_tlvs;
28852888
self
28862889
}
2890+
pub fn with_user_custom_data(mut self, user_custom_data: Vec<u8>) -> Self {
2891+
self.user_custom_data = user_custom_data;
2892+
self
2893+
}
28872894
}
28882895

28892896
pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
28902897
let ClaimAlongRouteArgs {
28912898
origin_node, expected_paths, expected_extra_fees, expected_min_htlc_overpay, skip_last,
28922899
payment_preimage: our_payment_preimage, allow_1_msat_fee_overpay, sender_custom_tlvs,
2900+
user_custom_data
28932901
} = args;
28942902
let claim_event = expected_paths[0].last().unwrap().node.get_and_clear_pending_events();
28952903
assert_eq!(claim_event.len(), 1);
@@ -2927,6 +2935,7 @@ pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 {
29272935
assert_eq!(htlcs.len(), expected_paths.len()); // One per path.
29282936
assert_eq!(htlcs.iter().map(|h| h.value_msat).sum::<u64>(), amount_msat);
29292937
assert_eq!(onion_fields.as_ref().unwrap().sender_custom_tlvs, sender_custom_tlvs);
2938+
assert_eq!(onion_fields.as_ref().unwrap().user_custom_data, user_custom_data);
29302939
check_claimed_htlcs_match_route(origin_node, expected_paths, htlcs);
29312940
fwd_amt_msat = amount_msat;
29322941
}

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fn large_payment_metadata() {
5959
payment_metadata: None,
6060
keysend_preimage: None,
6161
sender_custom_tlvs: &Vec::new(),
62+
user_custom_data: &Vec::new(),
6263
sender_intended_htlc_amt_msat: MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
6364
cltv_expiry_height: nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
6465
}.serialized_length();
@@ -75,7 +76,7 @@ fn large_payment_metadata() {
7576
let mut recipient_onion_max_md_size = RecipientOnionFields {
7677
payment_secret: Some(payment_secret),
7778
payment_metadata: Some(payment_metadata.clone()),
78-
sender_custom_tlvs: Vec::new(),
79+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
7980
};
8081
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();
8182
check_added_monitors!(nodes[0], 1);
@@ -123,7 +124,7 @@ fn large_payment_metadata() {
123124
let mut recipient_onion_allows_2_hops = RecipientOnionFields {
124125
payment_secret: Some(payment_secret_2),
125126
payment_metadata: Some(vec![42; max_metadata_len - INTERMED_PAYLOAD_LEN_ESTIMATE]),
126-
sender_custom_tlvs: Vec::new(),
127+
sender_custom_tlvs: Vec::new(), user_custom_data: Vec::new(),
127128
};
128129
let mut route_params_0_2 = route_0_2.route_params.clone().unwrap();
129130
route_params_0_2.payment_params.max_path_length = 2;
@@ -185,7 +186,8 @@ fn one_hop_blinded_path_with_custom_tlv() {
185186
intro_node_blinding_point: Some(blinded_path.blinding_point()),
186187
keysend_preimage: None,
187188
invoice_request: None,
188-
sender_custom_tlvs: &Vec::new()
189+
sender_custom_tlvs: &Vec::new(),
190+
user_custom_data: &Vec::new()
189191
}.serialized_length();
190192
let max_custom_tlv_len = 1300
191193
- crate::util::ser::BigSize(CUSTOM_TLV_TYPE).serialized_length() // custom TLV type

0 commit comments

Comments
 (0)