Skip to content

Commit 7635dea

Browse files
committed
Add _delta suffix to min_final_cltv_expiry
This matches the spec and helps avoid any confusion around naming. We're also then consistent with `cltv_expiry` in an HTLC being the actual block height value for the CLTV and not a delta.
1 parent 64b9e83 commit 7635dea

File tree

7 files changed

+43
-43
lines changed

7 files changed

+43
-43
lines changed

lightning-invoice/src/de.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ impl FromBase32 for TaggedField {
451451
Ok(TaggedField::DescriptionHash(Sha256::from_base32(field_data)?)),
452452
constants::TAG_EXPIRY_TIME =>
453453
Ok(TaggedField::ExpiryTime(ExpiryTime::from_base32(field_data)?)),
454-
constants::TAG_MIN_FINAL_CLTV_EXPIRY =>
454+
constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA =>
455455
Ok(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry::from_base32(field_data)?)),
456456
constants::TAG_FALLBACK =>
457457
Ok(TaggedField::Fallback(Fallback::from_base32(field_data)?)),
@@ -840,7 +840,7 @@ mod test {
840840
}
841841

842842
#[test]
843-
fn test_parse_min_final_cltv_expiry() {
843+
fn test_parse_min_final_cltv_expiry_delta() {
844844
use crate::MinFinalCltvExpiry;
845845
use bech32::FromBase32;
846846

lightning-invoice/src/lib.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,11 @@ pub const DEFAULT_EXPIRY_TIME: u64 = 3600;
154154
/// Default minimum final CLTV expiry as defined by [BOLT 11].
155155
///
156156
/// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
157-
/// provided in [`MIN_FINAL_CLTV_EXPIRY`].
157+
/// provided in [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
158158
///
159159
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
160-
/// [`MIN_FINAL_CLTV_EXPIRY`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY
161-
pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
160+
/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
161+
pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;
162162

163163
/// Builder for `Invoice`s. It's the most convenient and advised way to use this library. It ensures
164164
/// that only a semantically and syntactically correct Invoice can be built using it.
@@ -199,7 +199,7 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
199199
/// .payment_hash(payment_hash)
200200
/// .payment_secret(payment_secret)
201201
/// .current_timestamp()
202-
/// .min_final_cltv_expiry(144)
202+
/// .min_final_cltv_expiry_delta(144)
203203
/// .build_signed(|hash| {
204204
/// Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
205205
/// })
@@ -438,7 +438,7 @@ pub struct PayeePubKey(pub PublicKey);
438438
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
439439
pub struct ExpiryTime(Duration);
440440

441-
/// `min_final_cltv_expiry` to use for the last HTLC in the route
441+
/// `min_final_cltv_expiry_delta` to use for the last HTLC in the route
442442
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
443443
pub struct MinFinalCltvExpiry(pub u64);
444444

@@ -475,7 +475,7 @@ pub mod constants {
475475
pub const TAG_PAYEE_PUB_KEY: u8 = 19;
476476
pub const TAG_DESCRIPTION_HASH: u8 = 23;
477477
pub const TAG_EXPIRY_TIME: u8 = 6;
478-
pub const TAG_MIN_FINAL_CLTV_EXPIRY: u8 = 24;
478+
pub const TAG_MIN_FINAL_CLTV_EXPIRY_DELTA: u8 = 24;
479479
pub const TAG_FALLBACK: u8 = 9;
480480
pub const TAG_PRIVATE_ROUTE: u8 = 3;
481481
pub const TAG_PAYMENT_SECRET: u8 = 16;
@@ -654,9 +654,9 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
654654
}
655655

656656
impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T, tb::False, S> {
657-
/// Sets `min_final_cltv_expiry`.
658-
pub fn min_final_cltv_expiry(mut self, min_final_cltv_expiry: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
659-
self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry)));
657+
/// Sets `min_final_cltv_expiry_delta`.
658+
pub fn min_final_cltv_expiry_delta(mut self, min_final_cltv_expiry_delta: u64) -> InvoiceBuilder<D, H, T, tb::True, S> {
659+
self.tagged_fields.push(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry(min_final_cltv_expiry_delta)));
660660
self.set_flags()
661661
}
662662
}
@@ -925,7 +925,7 @@ impl RawInvoice {
925925
find_extract!(self.known_tagged_fields(), TaggedField::ExpiryTime(ref x), x)
926926
}
927927

928-
pub fn min_final_cltv_expiry(&self) -> Option<&MinFinalCltvExpiry> {
928+
pub fn min_final_cltv_expiry_delta(&self) -> Option<&MinFinalCltvExpiry> {
929929
find_extract!(self.known_tagged_fields(), TaggedField::MinFinalCltvExpiry(ref x), x)
930930
}
931931

@@ -1239,12 +1239,12 @@ impl Invoice {
12391239
.unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) < at_time
12401240
}
12411241

1242-
/// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
1243-
/// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY`].
1244-
pub fn min_final_cltv_expiry(&self) -> u64 {
1245-
self.signed_invoice.min_final_cltv_expiry()
1242+
/// Returns the invoice's `min_final_cltv_expiry_delta` time, if present, otherwise
1243+
/// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA`].
1244+
pub fn min_final_cltv_expiry_delta(&self) -> u64 {
1245+
self.signed_invoice.min_final_cltv_expiry_delta()
12461246
.map(|x| x.0)
1247-
.unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY)
1247+
.unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA)
12481248
}
12491249

12501250
/// Returns a list of all fallback addresses
@@ -1297,7 +1297,7 @@ impl TaggedField {
12971297
TaggedField::PayeePubKey(_) => constants::TAG_PAYEE_PUB_KEY,
12981298
TaggedField::DescriptionHash(_) => constants::TAG_DESCRIPTION_HASH,
12991299
TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
1300-
TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY,
1300+
TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA,
13011301
TaggedField::Fallback(_) => constants::TAG_FALLBACK,
13021302
TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
13031303
TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
@@ -1800,7 +1800,7 @@ mod test {
18001800
let builder = InvoiceBuilder::new(Currency::Bitcoin)
18011801
.payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
18021802
.duration_since_epoch(Duration::from_secs(1234567))
1803-
.min_final_cltv_expiry(144);
1803+
.min_final_cltv_expiry_delta(144);
18041804

18051805
let too_long_string = String::from_iter(
18061806
(0..1024).map(|_| '?')
@@ -1918,7 +1918,7 @@ mod test {
19181918
.duration_since_epoch(Duration::from_secs(1234567))
19191919
.payee_pub_key(public_key.clone())
19201920
.expiry_time(Duration::from_secs(54321))
1921-
.min_final_cltv_expiry(144)
1921+
.min_final_cltv_expiry_delta(144)
19221922
.fallback(Fallback::PubKeyHash([0;20]))
19231923
.private_route(route_1.clone())
19241924
.private_route(route_2.clone())
@@ -1944,7 +1944,7 @@ mod test {
19441944
);
19451945
assert_eq!(invoice.payee_pub_key(), Some(&public_key));
19461946
assert_eq!(invoice.expiry_time(), Duration::from_secs(54321));
1947-
assert_eq!(invoice.min_final_cltv_expiry(), 144);
1947+
assert_eq!(invoice.min_final_cltv_expiry_delta(), 144);
19481948
assert_eq!(invoice.fallbacks(), vec![&Fallback::PubKeyHash([0;20])]);
19491949
assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
19501950
assert_eq!(
@@ -1985,7 +1985,7 @@ mod test {
19851985
.unwrap();
19861986
let invoice = Invoice::from_signed(signed_invoice).unwrap();
19871987

1988-
assert_eq!(invoice.min_final_cltv_expiry(), DEFAULT_MIN_FINAL_CLTV_EXPIRY);
1988+
assert_eq!(invoice.min_final_cltv_expiry_delta(), DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA);
19891989
assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME));
19901990
assert!(!invoice.would_expire(Duration::from_secs(1234568)));
19911991
}

lightning-invoice/src/payment.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ where
455455
let route_params = RouteParameters {
456456
payment_params,
457457
final_value_msat: invoice.amount_milli_satoshis().or(amount_msats).unwrap(),
458-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
458+
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
459459
};
460460

461461
let send_payment = |route: &Route| {
@@ -787,7 +787,7 @@ mod tests {
787787
.payment_hash(payment_hash)
788788
.payment_secret(PaymentSecret([0; 32]))
789789
.duration_since_epoch(duration_since_epoch())
790-
.min_final_cltv_expiry(144)
790+
.min_final_cltv_expiry_delta(144)
791791
.amount_milli_satoshis(128)
792792
.build_signed(|hash| {
793793
Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
@@ -813,7 +813,7 @@ mod tests {
813813
.payment_hash(payment_hash)
814814
.payment_secret(PaymentSecret([0; 32]))
815815
.duration_since_epoch(duration_since_epoch())
816-
.min_final_cltv_expiry(144)
816+
.min_final_cltv_expiry_delta(144)
817817
.build_signed(|hash| {
818818
Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
819819
})
@@ -832,7 +832,7 @@ mod tests {
832832
.payment_hash(payment_hash)
833833
.payment_secret(PaymentSecret([0; 32]))
834834
.duration_since_epoch(duration)
835-
.min_final_cltv_expiry(144)
835+
.min_final_cltv_expiry_delta(144)
836836
.amount_milli_satoshis(128)
837837
.build_signed(|hash| {
838838
Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
@@ -1688,7 +1688,7 @@ mod tests {
16881688
RouteParameters {
16891689
payment_params,
16901690
final_value_msat,
1691-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
1691+
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
16921692
}
16931693
}
16941694
}

lightning-invoice/src/ser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ impl ToBase32 for TaggedField {
435435
write_tagged_field(writer, constants::TAG_EXPIRY_TIME, duration)
436436
},
437437
TaggedField::MinFinalCltvExpiry(ref expiry) => {
438-
write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY, expiry)
438+
write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY_DELTA, expiry)
439439
},
440440
TaggedField::Fallback(ref fallback_address) => {
441441
write_tagged_field(writer, constants::TAG_FALLBACK, fallback_address)

lightning-invoice/src/utils.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use lightning::chain;
1010
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
1111
use lightning::chain::keysinterface::{Recipient, KeysInterface};
1212
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
13-
use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY};
13+
use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY_DELTA};
1414
#[cfg(feature = "std")]
1515
use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA};
1616
use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey};
@@ -179,7 +179,7 @@ where
179179
.current_timestamp()
180180
.payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
181181
.payment_secret(payment_secret)
182-
.min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
182+
.min_final_cltv_expiry_delta(MIN_FINAL_CLTV_EXPIRY_DELTA.into())
183183
.expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
184184
if let Some(amt) = amt_msat {
185185
invoice = invoice.amount_milli_satoshis(amt);
@@ -370,7 +370,7 @@ where
370370
.payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
371371
.payment_secret(payment_secret)
372372
.basic_mpp()
373-
.min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
373+
.min_final_cltv_expiry_delta(MIN_FINAL_CLTV_EXPIRY_DELTA.into())
374374
.expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
375375
if let Some(amt) = amt_msat {
376376
invoice = invoice.amount_milli_satoshis(amt);
@@ -688,7 +688,7 @@ mod test {
688688
use bitcoin_hashes::sha256::Hash as Sha256;
689689
use lightning::chain::keysinterface::PhantomKeysManager;
690690
use lightning::ln::{PaymentPreimage, PaymentHash};
691-
use lightning::ln::channelmanager::{self, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY, PaymentId};
691+
use lightning::ln::channelmanager::{self, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId};
692692
use lightning::ln::functional_test_utils::*;
693693
use lightning::ln::msgs::ChannelMessageHandler;
694694
use lightning::routing::router::{PaymentParameters, RouteParameters, find_route};
@@ -712,7 +712,7 @@ mod test {
712712
Some(10_000), "test".to_string(), Duration::from_secs(1234567),
713713
non_default_invoice_expiry_secs).unwrap();
714714
assert_eq!(invoice.amount_pico_btc(), Some(100_000));
715-
assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
715+
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
716716
assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
717717
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
718718

@@ -732,7 +732,7 @@ mod test {
732732
let route_params = RouteParameters {
733733
payment_params,
734734
final_value_msat: invoice.amount_milli_satoshis().unwrap(),
735-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
735+
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
736736
};
737737
let first_hops = nodes[0].node.list_usable_channels();
738738
let network_graph = &node_cfgs[0].network_graph;
@@ -778,7 +778,7 @@ mod test {
778778
Some(10_000), description_hash, Duration::from_secs(1234567), 3600
779779
).unwrap();
780780
assert_eq!(invoice.amount_pico_btc(), Some(100_000));
781-
assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
781+
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
782782
assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Testing description_hash".as_bytes()))));
783783
}
784784

@@ -1028,7 +1028,7 @@ mod test {
10281028
nodes[1].node.get_payment_preimage(payment_hash, payment_secret).unwrap()
10291029
};
10301030

1031-
assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
1031+
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
10321032
assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
10331033
assert_eq!(invoice.route_hints().len(), 2);
10341034
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
@@ -1040,7 +1040,7 @@ mod test {
10401040
let params = RouteParameters {
10411041
payment_params,
10421042
final_value_msat: invoice.amount_milli_satoshis().unwrap(),
1043-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
1043+
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
10441044
};
10451045
let first_hops = nodes[0].node.list_usable_channels();
10461046
let network_graph = &node_cfgs[0].network_graph;
@@ -1161,7 +1161,7 @@ mod test {
11611161
)
11621162
.unwrap();
11631163
assert_eq!(invoice.amount_pico_btc(), Some(200_000));
1164-
assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
1164+
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
11651165
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
11661166
assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Description hash phantom invoice".as_bytes()))));
11671167
}

lightning-invoice/tests/ser_de.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ fn get_test_tuples() -> Vec<(String, SignedRawInvoice, bool, bool)> {
246246
"462264ede7e14047e9b249da94fefc47f41f7d02ee9b091815a5506bc8abf75f"
247247
).unwrap())
248248
.expiry_time(Duration::from_secs(604800))
249-
.min_final_cltv_expiry(10)
249+
.min_final_cltv_expiry_delta(10)
250250
.description("Blockstream Store: 88.85 USD for Blockstream Ledger Nano S x 1, \"Back In My Day\" Sticker x 2, \"I Got Lightning Working\" Sticker x 2 and 1 more items".to_owned())
251251
.private_route(RouteHint(vec![RouteHintHop {
252252
src_node_id: PublicKey::from_slice(&hex::decode(

lightning/src/ln/channelmanager.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -950,12 +950,12 @@ pub const MIN_CLTV_EXPIRY_DELTA: u16 = 6*7;
950950
pub(super) const CLTV_FAR_FAR_AWAY: u32 = 14 * 24 * 6;
951951

952952
/// Minimum CLTV difference between the current block height and received inbound payments.
953-
/// Invoices generated for payment to us must set their `min_final_cltv_expiry` field to at least
953+
/// Invoices generated for payment to us must set their `min_final_cltv_expiry_delta` field to at least
954954
/// this value.
955955
// Note that we fail if exactly HTLC_FAIL_BACK_BUFFER + 1 was used, so we need to add one for
956956
// any payments to succeed. Further, we don't want payments to fail if a block was found while
957957
// a payment was being routed, so we add an extra block to be safe.
958-
pub const MIN_FINAL_CLTV_EXPIRY: u32 = HTLC_FAIL_BACK_BUFFER + 3;
958+
pub const MIN_FINAL_CLTV_EXPIRY_DELTA: u32 = HTLC_FAIL_BACK_BUFFER + 3;
959959

960960
// Check that our CLTV_EXPIRY is at least CLTV_CLAIM_BUFFER + ANTI_REORG_DELAY + LATENCY_GRACE_PERIOD_BLOCKS,
961961
// ie that if the next-hop peer fails the HTLC within
@@ -5612,8 +5612,8 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
56125612
/// If you need exact expiry semantics, you should enforce them upon receipt of
56135613
/// [`PaymentReceived`].
56145614
///
5615-
/// Note that invoices generated for inbound payments should have their `min_final_cltv_expiry`
5616-
/// set to at least [`MIN_FINAL_CLTV_EXPIRY`].
5615+
/// Note that invoices generated for inbound payments should have their `min_final_cltv_expiry_delta`
5616+
/// set to at least [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
56175617
///
56185618
/// Note that a malicious eavesdropper can intuit whether an inbound payment was created by
56195619
/// `create_inbound_payment` or `create_inbound_payment_for_hash` based on runtime.

0 commit comments

Comments
 (0)