Skip to content

Commit 26a44c2

Browse files
committed
f - Remove MAX_EXPIRY_TIME
1 parent 5f050a7 commit 26a44c2

File tree

2 files changed

+15
-53
lines changed

2 files changed

+15
-53
lines changed

lightning-invoice/src/de.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use secp256k1::key::PublicKey;
2424

2525
use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
2626
SemanticError, PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice, constants, SignedRawInvoice,
27-
RawDataPart, CreationError, InvoiceFeatures};
27+
RawDataPart, InvoiceFeatures};
2828

2929
use self::hrp_sm::parse_hrp;
3030

@@ -359,7 +359,6 @@ impl FromBase32 for PositiveTimestamp {
359359
.expect("7*5bit < 64bit, no overflow possible");
360360
match PositiveTimestamp::from_unix_timestamp(timestamp) {
361361
Ok(t) => Ok(t),
362-
Err(CreationError::TimestampOutOfBounds) => Err(ParseError::TimestampOverflow),
363362
Err(_) => unreachable!(),
364363
}
365364
}
@@ -516,7 +515,7 @@ impl FromBase32 for ExpiryTime {
516515

517516
fn from_base32(field_data: &[u5]) -> Result<ExpiryTime, ParseError> {
518517
match parse_int_be::<u64, u5>(field_data, 32)
519-
.and_then(|t| ExpiryTime::from_seconds(t).ok()) // ok, since the only error is out of bounds
518+
.map(|t| ExpiryTime::from_seconds(t))
520519
{
521520
Some(t) => Ok(t),
522521
None => Err(ParseError::IntegerOverflowError),
@@ -646,7 +645,6 @@ pub enum ParseError {
646645
/// Not an error, but used internally to signal that a part of the invoice should be ignored
647646
/// according to BOLT11
648647
Skip,
649-
TimestampOverflow,
650648
}
651649

652650
/// Indicates that something went wrong while parsing or validating the invoice. Parsing errors
@@ -709,9 +707,6 @@ impl Display for ParseError {
709707
ParseError::Skip => {
710708
f.write_str("the tagged field has to be skipped because of an unexpected, but allowed property")
711709
},
712-
ParseError::TimestampOverflow => {
713-
f.write_str("the invoice's timestamp could not be represented as SystemTime")
714-
},
715710
}
716711
}
717712
}
@@ -877,7 +872,7 @@ mod test {
877872
use bech32::FromBase32;
878873

879874
let input = from_bech32("pu".as_bytes());
880-
let expected = Ok(ExpiryTime::from_seconds(60).unwrap());
875+
let expected = Ok(ExpiryTime::from_seconds(60));
881876
assert_eq!(ExpiryTime::from_base32(&input), expected);
882877

883878
let input_too_large = from_bech32("sqqqqqqqqqqqq".as_bytes());

lightning-invoice/src/lib.rs

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,6 @@ const TIMESTAMP_BITS: usize = 35;
9292
/// allowing for adding an expiry without overflowing.
9393
const MAX_TIMESTAMP: u64 = core::u64::MAX >> (64 - TIMESTAMP_BITS);
9494

95-
/// The maximum expiry allowed, represented as a [`Duration`] since the invoice timestamp.
96-
const MAX_EXPIRY_TIME: u64 = core::u64::MAX - MAX_TIMESTAMP;
97-
98-
/// Assert that the maximum expiry represented as a [`Duration`] since the UNIX epoch does not
99-
/// exceed [`u64::MAX`].
100-
const _MAX_EXPIRY_TIMESTAMP: u64 = MAX_TIMESTAMP + MAX_EXPIRY_TIME;
101-
10295
/// Default expiry time as defined by [BOLT 11].
10396
///
10497
/// [BOLT 11]: https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md
@@ -388,10 +381,6 @@ pub struct PayeePubKey(pub PublicKey);
388381

389382
/// Positive duration that defines when (relatively to the timestamp) in the future the invoice
390383
/// expires
391-
///
392-
/// # Invariants
393-
/// The number of seconds this expiry time represents has to be in the range
394-
/// `0...MAX_EXPIRY_TIME` to avoid overflows when adding it to a timestamp.
395384
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
396385
pub struct ExpiryTime(Duration);
397386

@@ -499,10 +488,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
499488

500489
/// Sets the expiry time
501490
pub fn expiry_time(mut self, expiry_time: Duration) -> Self {
502-
match ExpiryTime::from_duration(expiry_time) {
503-
Ok(t) => self.tagged_fields.push(TaggedField::ExpiryTime(t)),
504-
Err(e) => self.error = Some(e),
505-
};
491+
self.tagged_fields.push(TaggedField::ExpiryTime(ExpiryTime::from_duration(expiry_time)));
506492
self
507493
}
508494

@@ -1222,7 +1208,9 @@ impl Invoice {
12221208
/// Returns whether the expiry time would pass at the given point in time.
12231209
/// `at_time` is the timestamp as a duration since the UNIX epoch.
12241210
pub fn would_expire(&self, at_time: Duration) -> bool {
1225-
self.duration_since_epoch() + self.expiry_time() < at_time
1211+
self.duration_since_epoch()
1212+
.checked_add(self.expiry_time())
1213+
.unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) < at_time
12261214
}
12271215

12281216
/// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
@@ -1343,26 +1331,14 @@ impl Deref for PayeePubKey {
13431331
}
13441332

13451333
impl ExpiryTime {
1346-
/// Construct an `ExpiryTime` from seconds. If there exists a `PositiveTimestamp` which would
1347-
/// overflow on adding the `ExpiryTime` to it then this function will return a
1348-
/// `CreationError::ExpiryTimeOutOfBounds`.
1349-
pub fn from_seconds(seconds: u64) -> Result<ExpiryTime, CreationError> {
1350-
if seconds <= MAX_EXPIRY_TIME {
1351-
Ok(ExpiryTime(Duration::from_secs(seconds)))
1352-
} else {
1353-
Err(CreationError::ExpiryTimeOutOfBounds)
1354-
}
1334+
/// Construct an `ExpiryTime` from seconds.
1335+
pub fn from_seconds(seconds: u64) -> ExpiryTime {
1336+
ExpiryTime(Duration::from_secs(seconds))
13551337
}
13561338

1357-
/// Construct an `ExpiryTime` from a `Duration`. If there exists a `PositiveTimestamp` which
1358-
/// would overflow on adding the `ExpiryTime` to it then this function will return a
1359-
/// `CreationError::ExpiryTimeOutOfBounds`.
1360-
pub fn from_duration(duration: Duration) -> Result<ExpiryTime, CreationError> {
1361-
if duration.as_secs() <= MAX_EXPIRY_TIME {
1362-
Ok(ExpiryTime(duration))
1363-
} else {
1364-
Err(CreationError::ExpiryTimeOutOfBounds)
1365-
}
1339+
/// Construct an `ExpiryTime` from a `Duration`.
1340+
pub fn from_duration(duration: Duration) -> ExpiryTime {
1341+
ExpiryTime(duration)
13661342
}
13671343

13681344
/// Returns the expiry time in seconds
@@ -1431,12 +1407,9 @@ pub enum CreationError {
14311407
/// The specified route has too many hops and can't be encoded
14321408
RouteTooLong,
14331409

1434-
/// The unix timestamp of the supplied date is <0 or can't be represented as `SystemTime`
1410+
/// The unix timestamp of the supplied date is less than zero or greater than 35-bits
14351411
TimestampOutOfBounds,
14361412

1437-
/// The supplied expiry time could cause an overflow if added to a `PositiveTimestamp`
1438-
ExpiryTimeOutOfBounds,
1439-
14401413
/// The supplied millisatoshi amount was greater than the total bitcoin supply.
14411414
InvalidAmount,
14421415
}
@@ -1446,8 +1419,7 @@ impl Display for CreationError {
14461419
match self {
14471420
CreationError::DescriptionTooLong => f.write_str("The supplied description string was longer than 639 bytes"),
14481421
CreationError::RouteTooLong => f.write_str("The specified route has too many hops and can't be encoded"),
1449-
CreationError::TimestampOutOfBounds => f.write_str("The unix timestamp of the supplied date is <0 or can't be represented as `SystemTime`"),
1450-
CreationError::ExpiryTimeOutOfBounds => f.write_str("The supplied expiry time could cause an overflow if added to a `PositiveTimestamp`"),
1422+
CreationError::TimestampOutOfBounds => f.write_str("The unix timestamp of the supplied date is less than zero or greater than 35-bits"),
14511423
CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"),
14521424
}
14531425
}
@@ -1543,11 +1515,6 @@ mod test {
15431515
::PositiveTimestamp::from_unix_timestamp(::MAX_TIMESTAMP + 1),
15441516
Err(::CreationError::TimestampOutOfBounds)
15451517
);
1546-
1547-
assert_eq!(
1548-
::ExpiryTime::from_seconds(::MAX_EXPIRY_TIME + 1),
1549-
Err(::CreationError::ExpiryTimeOutOfBounds)
1550-
);
15511518
}
15521519

15531520
#[test]

0 commit comments

Comments
 (0)