Skip to content

Commit 91db879

Browse files
committed
Add new payment type and metadata bytes
Adds two new payment `Method`s for identifying payments with custom `min_final_cltv_expiry_delta` as payments with LDK or user payment hashes. The `min_final_cltv_expiry_delta` value is packed into the metadata bytes of the payment secret, taking up 12 bits.
1 parent c888a90 commit 91db879

File tree

8 files changed

+125
-36
lines changed

8 files changed

+125
-36
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ fn get_payment_secret_hash(dest: &ChanMan, payment_id: &mut u8) -> Option<(Payme
305305
let mut payment_hash;
306306
for _ in 0..256 {
307307
payment_hash = PaymentHash(Sha256::hash(&[*payment_id; 1]).into_inner());
308-
if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 3600) {
308+
if let Ok(payment_secret) = dest.create_inbound_payment_for_hash(payment_hash, None, 3600, None) {
309309
return Some((payment_secret, payment_hash));
310310
}
311311
*payment_id = payment_id.wrapping_add(1);

fuzz/src/full_stack.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
570570
let payment_hash = PaymentHash(Sha256::from_engine(sha).into_inner());
571571
// Note that this may fail - our hashes may collide and we'll end up trying to
572572
// double-register the same payment_hash.
573-
let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1);
573+
let _ = channelmanager.create_inbound_payment_for_hash(payment_hash, None, 1, None);
574574
},
575575
9 => {
576576
for payment in payments_received.drain(..) {

lightning-invoice/src/utils.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ where
157157
.duration_since(UNIX_EPOCH)
158158
.expect("Time must be > 1970")
159159
.as_secs(),
160+
None,
160161
)
161162
.map_err(|_| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
162163
(payment_hash, payment_secret)
@@ -170,6 +171,7 @@ where
170171
.duration_since(UNIX_EPOCH)
171172
.expect("Time must be > 1970")
172173
.as_secs(),
174+
None,
173175
)
174176
.map_err(|_| SignOrCreationError::CreationError(CreationError::InvalidAmount))?
175177
};
@@ -362,7 +364,7 @@ where
362364
// `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
363365
// supply.
364366
let (payment_hash, payment_secret) = channelmanager
365-
.create_inbound_payment(amt_msat, invoice_expiry_delta_secs)
367+
.create_inbound_payment(amt_msat, invoice_expiry_delta_secs, min_final_cltv_expiry_delta)
366368
.map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
367369
let our_node_pubkey = channelmanager.get_our_node_id();
368370
let channels = channelmanager.list_channels();
@@ -1019,7 +1021,7 @@ mod test {
10191021
create_unannounced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, channelmanager::provided_init_features(), channelmanager::provided_init_features());
10201022

10211023
let payment_amt = 20_000;
1022-
let (payment_hash, _payment_secret) = nodes[1].node.create_inbound_payment(Some(payment_amt), 3600).unwrap();
1024+
let (payment_hash, _payment_secret) = nodes[1].node.create_inbound_payment(Some(payment_amt), 3600, None).unwrap();
10231025
let route_hints = vec![
10241026
nodes[1].node.get_phantom_route_hints(),
10251027
nodes[2].node.get_phantom_route_hints(),

lightning/src/ln/channelmanager.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5649,8 +5649,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
56495649
/// [`PaymentClaimable`]: events::Event::PaymentClaimable
56505650
/// [`PaymentClaimable::payment_preimage`]: events::Event::PaymentClaimable::payment_preimage
56515651
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
5652-
pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<(PaymentHash, PaymentSecret), ()> {
5653-
inbound_payment::create(&self.inbound_payment_key, min_value_msat, invoice_expiry_delta_secs, &self.keys_manager, self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
5652+
pub fn create_inbound_payment(&self, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32,
5653+
min_final_cltv_expiry_delta: Option<u32>) -> Result<(PaymentHash, PaymentSecret), ()> {
5654+
inbound_payment::create(&self.inbound_payment_key, min_value_msat, invoice_expiry_delta_secs,
5655+
&self.keys_manager, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, min_final_cltv_expiry_delta)
56545656
}
56555657

56565658
/// Legacy version of [`create_inbound_payment`]. Use this method if you wish to share
@@ -5712,9 +5714,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
57125714
/// Errors if `min_value_msat` is greater than total bitcoin supply.
57135715
///
57145716
/// [`create_inbound_payment`]: Self::create_inbound_payment
5715-
/// [`PaymentClaimable`]: events::Event::PaymentClaimable
5716-
pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32) -> Result<PaymentSecret, ()> {
5717-
inbound_payment::create_from_hash(&self.inbound_payment_key, min_value_msat, payment_hash, invoice_expiry_delta_secs, self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
5717+
/// [`PaymentReceived`]: events::Event::PaymentReceived
5718+
pub fn create_inbound_payment_for_hash(&self, payment_hash: PaymentHash, min_value_msat: Option<u64>,
5719+
invoice_expiry_delta_secs: u32, min_final_cltv_expiry: Option<u32>) -> Result<PaymentSecret, ()> {
5720+
inbound_payment::create_from_hash(&self.inbound_payment_key, min_value_msat, payment_hash,
5721+
invoice_expiry_delta_secs, self.highest_seen_timestamp.load(Ordering::Acquire) as u64,
5722+
min_final_cltv_expiry)
57185723
}
57195724

57205725
/// Legacy version of [`create_inbound_payment_for_hash`]. Use this method if you wish to share
@@ -8478,7 +8483,7 @@ pub mod bench {
84788483
payment_preimage.0[0..8].copy_from_slice(&payment_count.to_le_bytes());
84798484
payment_count += 1;
84808485
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
8481-
let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
8486+
let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200, None).unwrap();
84828487

84838488
$node_a.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
84848489
let payment_event = SendEvent::from_event($node_a.get_and_clear_pending_msg_events().pop().unwrap());

lightning/src/ln/functional_test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ macro_rules! get_payment_preimage_hash {
13431343
*payment_count += 1;
13441344
let payment_hash = $crate::ln::PaymentHash(
13451345
bitcoin::hashes::sha256::Hash::hash(&payment_preimage.0[..]).into_inner());
1346-
let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, $min_value_msat, 7200).unwrap();
1346+
let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, $min_value_msat, 7200, None).unwrap();
13471347
(payment_preimage, payment_hash, payment_secret)
13481348
}
13491349
}

lightning/src/ln/functional_tests.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ fn test_duplicate_htlc_different_direction_onchain() {
12401240
let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 900_000);
12411241

12421242
let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[0], 800_000);
1243-
let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
1243+
let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200, None).unwrap();
12441244
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[0]]], 800_000, payment_hash, node_a_payment_secret);
12451245

12461246
// Provide preimage to node 0 by claiming payment
@@ -4727,7 +4727,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
47274727

47284728
let (our_payment_preimage, duplicate_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 900_000);
47294729

4730-
let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200).unwrap();
4730+
let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200, None).unwrap();
47314731
// We reduce the final CLTV here by a somewhat arbitrary constant to keep it under the one-byte
47324732
// script push size limit so that the below script length checks match
47334733
// ACCEPTED_HTLC_SCRIPT_WEIGHT.
@@ -4945,30 +4945,30 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
49454945
let (_, payment_hash_2, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
49464946
let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], ds_dust_limit*1000);
49474947
// 2nd HTLC:
4948-
send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
4948+
send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200, None).unwrap()); // not added < dust limit + HTLC tx fee
49494949
// 3rd HTLC:
4950-
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_2, nodes[5].node.create_inbound_payment_for_hash(payment_hash_2, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
4950+
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_2, nodes[5].node.create_inbound_payment_for_hash(payment_hash_2, None, 7200, None).unwrap()); // not added < dust limit + HTLC tx fee
49514951
// 4th HTLC:
49524952
let (_, payment_hash_3, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
49534953
// 5th HTLC:
49544954
let (_, payment_hash_4, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
49554955
let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], 1000000);
49564956
// 6th HTLC:
4957-
send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200).unwrap());
4957+
send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200, None).unwrap());
49584958
// 7th HTLC:
4959-
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_4, nodes[5].node.create_inbound_payment_for_hash(payment_hash_4, None, 7200).unwrap());
4959+
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_4, nodes[5].node.create_inbound_payment_for_hash(payment_hash_4, None, 7200, None).unwrap());
49604960

49614961
// 8th HTLC:
49624962
let (_, payment_hash_5, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
49634963
// 9th HTLC:
49644964
let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], ds_dust_limit*1000);
4965-
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200).unwrap()); // not added < dust limit + HTLC tx fee
4965+
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200, None).unwrap()); // not added < dust limit + HTLC tx fee
49664966

49674967
// 10th HTLC:
49684968
let (_, payment_hash_6, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
49694969
// 11th HTLC:
49704970
let (route, _, _, _) = get_route_and_payment_hash!(nodes[1], nodes[5], 1000000);
4971-
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200).unwrap());
4971+
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200, None).unwrap());
49724972

49734973
// Double-check that six of the new HTLC were added
49744974
// We now have six HTLCs pending over the dust limit and six HTLCs under the dust limit (ie,
@@ -6936,7 +6936,7 @@ fn test_check_htlc_underpaying() {
69366936
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(channelmanager::provided_invoice_features());
69376937
let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer, &random_seed_bytes).unwrap();
69386938
let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]);
6939-
let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200).unwrap();
6939+
let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200, None).unwrap();
69406940
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
69416941
check_added_monitors!(nodes[0], 1);
69426942

@@ -7939,7 +7939,7 @@ fn test_preimage_storage() {
79397939
create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
79407940

79417941
{
7942-
let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 7200).unwrap();
7942+
let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 7200, None).unwrap();
79437943
let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
79447944
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
79457945
check_added_monitors!(nodes[0], 1);
@@ -8045,7 +8045,7 @@ fn test_bad_secret_hash() {
80458045

80468046
let random_payment_hash = PaymentHash([42; 32]);
80478047
let random_payment_secret = PaymentSecret([43; 32]);
8048-
let (our_payment_hash, our_payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 2).unwrap();
8048+
let (our_payment_hash, our_payment_secret) = nodes[1].node.create_inbound_payment(Some(100_000), 2, None).unwrap();
80498049
let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
80508050

80518051
// All the below cases should end up being handled exactly identically, so we macro the

0 commit comments

Comments
 (0)