@@ -85,17 +85,6 @@ mod sync;
85
85
86
86
pub use de:: { ParseError , ParseOrSemanticError } ;
87
87
88
- /// The maximum timestamp that can be represented as a [`Duration`] since the UNIX epoch while
89
- /// allowing for adding an expiry without overflowing.
90
- const MAX_TIMESTAMP : u64 = core:: i64:: MAX as u64 ;
91
-
92
- /// The maximum expiry allowed, represented as a [`Duration`] since the invoice timestamp.
93
- const MAX_EXPIRY_TIME : u64 = ( core:: i64:: MAX ) as u64 + 1 ;
94
-
95
- /// Assert that the maximum expiry represented as a [`Duration`] since the UNIX epoch does not
96
- /// exceed [`u64::MAX`].
97
- const _MAX_EXPIRY_TIMESTAMP: u64 = MAX_TIMESTAMP + MAX_EXPIRY_TIME ;
98
-
99
88
/// Default expiry time as defined by [BOLT 11].
100
89
///
101
90
/// [BOLT 11]: https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md
@@ -385,10 +374,6 @@ pub struct PayeePubKey(pub PublicKey);
385
374
386
375
/// Positive duration that defines when (relatively to the timestamp) in the future the invoice
387
376
/// expires
388
- ///
389
- /// # Invariants
390
- /// The number of seconds this expiry time represents has to be in the range
391
- /// `0...MAX_EXPIRY_TIME` to avoid overflows when adding it to a timestamp.
392
377
#[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
393
378
pub struct ExpiryTime ( Duration ) ;
394
379
@@ -496,10 +481,7 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
496
481
497
482
/// Sets the expiry time
498
483
pub fn expiry_time ( mut self , expiry_time : Duration ) -> Self {
499
- match ExpiryTime :: from_duration ( expiry_time) {
500
- Ok ( t) => self . tagged_fields . push ( TaggedField :: ExpiryTime ( t) ) ,
501
- Err ( e) => self . error = Some ( e) ,
502
- } ;
484
+ self . tagged_fields . push ( TaggedField :: ExpiryTime ( ExpiryTime :: from_duration ( expiry_time) ) ) ;
503
485
self
504
486
}
505
487
@@ -591,19 +573,15 @@ impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, tb
591
573
592
574
/// Sets the timestamp to a duration since the UNIX epoch.
593
575
pub fn duration_since_epoch ( mut self , time : Duration ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
594
- match PositiveTimestamp :: from_duration_since_epoch ( time) {
595
- Ok ( t) => self . timestamp = Some ( t) ,
596
- Err ( e) => self . error = Some ( e) ,
597
- }
598
-
576
+ self . timestamp = Some ( PositiveTimestamp :: from_duration_since_epoch ( time) ) ;
599
577
self . set_flags ( )
600
578
}
601
579
602
580
/// Sets the timestamp to the current system time.
603
581
#[ cfg( feature = "std" ) ]
604
582
pub fn current_timestamp ( mut self ) -> InvoiceBuilder < D , H , tb:: True , C , S > {
605
583
let now = PositiveTimestamp :: from_system_time ( SystemTime :: now ( ) ) ;
606
- self . timestamp = Some ( now. expect ( "for the foreseeable future this shouldn't happen" ) ) ;
584
+ self . timestamp = Some ( now. expect ( "this shouldn't happen after the UNIX epoch " ) ) ;
607
585
self . set_flags ( )
608
586
}
609
587
}
@@ -946,35 +924,24 @@ impl PositiveTimestamp {
946
924
/// Creates a `PositiveTimestamp` from a unix timestamp in the range `0...MAX_TIMESTAMP`.
947
925
///
948
926
/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
949
- pub fn from_unix_timestamp ( unix_seconds : u64 ) -> Result < Self , CreationError > {
950
- if unix_seconds > MAX_TIMESTAMP {
951
- Err ( CreationError :: TimestampOutOfBounds )
952
- } else {
953
- Ok ( PositiveTimestamp ( Duration :: from_secs ( unix_seconds) ) )
954
- }
927
+ pub fn from_unix_timestamp ( unix_seconds : u64 ) -> Self {
928
+ PositiveTimestamp ( Duration :: from_secs ( unix_seconds) )
955
929
}
956
930
957
- /// Creates a `PositiveTimestamp` from a [`SystemTime`] with a corresponding unix timestamp in
958
- /// the range `0...MAX_TIMESTAMP`.
931
+ /// Creates a `PositiveTimestamp` from a [`SystemTime`] with a corresponding unix timestamp.
959
932
///
960
- /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
933
+ /// Returns a [`CreationError::TimestampOutOfBounds`] if `time` is before
934
+ /// [`SystemTime::UNIX_EPOCH`].
961
935
#[ cfg( feature = "std" ) ]
962
936
pub fn from_system_time ( time : SystemTime ) -> Result < Self , CreationError > {
963
937
time. duration_since ( SystemTime :: UNIX_EPOCH )
964
938
. map ( Self :: from_duration_since_epoch)
965
- . unwrap_or ( Err ( CreationError :: TimestampOutOfBounds ) )
939
+ . map_err ( |_| CreationError :: TimestampOutOfBounds )
966
940
}
967
941
968
- /// Creates a `PositiveTimestamp` from a [`Duration`] since the UNIX epoch in the range
969
- /// `0...MAX_TIMESTAMP`.
970
- ///
971
- /// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
972
- pub fn from_duration_since_epoch ( duration : Duration ) -> Result < Self , CreationError > {
973
- if duration. as_secs ( ) <= MAX_TIMESTAMP {
974
- Ok ( PositiveTimestamp ( duration) )
975
- } else {
976
- Err ( CreationError :: TimestampOutOfBounds )
977
- }
942
+ /// Creates a `PositiveTimestamp` from a [`Duration`] since the UNIX epoch.
943
+ pub fn from_duration_since_epoch ( duration : Duration ) -> Self {
944
+ PositiveTimestamp ( duration)
978
945
}
979
946
980
947
/// Returns the UNIX timestamp representing the stored time
@@ -1219,7 +1186,7 @@ impl Invoice {
1219
1186
/// Returns whether the expiry time would pass at the given point in time.
1220
1187
/// `at_time` is the timestamp as a duration since the UNIX epoch.
1221
1188
pub fn would_expire ( & self , at_time : Duration ) -> bool {
1222
- self . duration_since_epoch ( ) + self . expiry_time ( ) < at_time
1189
+ self . duration_since_epoch ( ) . saturating_add ( self . expiry_time ( ) ) < at_time
1223
1190
}
1224
1191
1225
1192
/// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
@@ -1340,26 +1307,14 @@ impl Deref for PayeePubKey {
1340
1307
}
1341
1308
1342
1309
impl ExpiryTime {
1343
- /// Construct an `ExpiryTime` from seconds. If there exists a `PositiveTimestamp` which would
1344
- /// overflow on adding the `ExpiryTime` to it then this function will return a
1345
- /// `CreationError::ExpiryTimeOutOfBounds`.
1346
- pub fn from_seconds ( seconds : u64 ) -> Result < ExpiryTime , CreationError > {
1347
- if seconds <= MAX_EXPIRY_TIME {
1348
- Ok ( ExpiryTime ( Duration :: from_secs ( seconds) ) )
1349
- } else {
1350
- Err ( CreationError :: ExpiryTimeOutOfBounds )
1351
- }
1310
+ /// Construct an `ExpiryTime` from seconds.
1311
+ pub fn from_seconds ( seconds : u64 ) -> ExpiryTime {
1312
+ ExpiryTime ( Duration :: from_secs ( seconds) )
1352
1313
}
1353
1314
1354
- /// Construct an `ExpiryTime` from a `Duration`. If there exists a `PositiveTimestamp` which
1355
- /// would overflow on adding the `ExpiryTime` to it then this function will return a
1356
- /// `CreationError::ExpiryTimeOutOfBounds`.
1357
- pub fn from_duration ( duration : Duration ) -> Result < ExpiryTime , CreationError > {
1358
- if duration. as_secs ( ) <= MAX_EXPIRY_TIME {
1359
- Ok ( ExpiryTime ( duration) )
1360
- } else {
1361
- Err ( CreationError :: ExpiryTimeOutOfBounds )
1362
- }
1315
+ /// Construct an `ExpiryTime` from a `Duration`.
1316
+ pub fn from_duration ( duration : Duration ) -> ExpiryTime {
1317
+ ExpiryTime ( duration)
1363
1318
}
1364
1319
1365
1320
/// Returns the expiry time in seconds
@@ -1428,12 +1383,9 @@ pub enum CreationError {
1428
1383
/// The specified route has too many hops and can't be encoded
1429
1384
RouteTooLong ,
1430
1385
1431
- /// The unix timestamp of the supplied date is <0 or can't be represented as `SystemTime`
1386
+ /// The unix timestamp of the supplied date is less than zero
1432
1387
TimestampOutOfBounds ,
1433
1388
1434
- /// The supplied expiry time could cause an overflow if added to a `PositiveTimestamp`
1435
- ExpiryTimeOutOfBounds ,
1436
-
1437
1389
/// The supplied millisatoshi amount was greater than the total bitcoin supply.
1438
1390
InvalidAmount ,
1439
1391
}
@@ -1443,8 +1395,7 @@ impl Display for CreationError {
1443
1395
match self {
1444
1396
CreationError :: DescriptionTooLong => f. write_str ( "The supplied description string was longer than 639 bytes" ) ,
1445
1397
CreationError :: RouteTooLong => f. write_str ( "The specified route has too many hops and can't be encoded" ) ,
1446
- CreationError :: TimestampOutOfBounds => f. write_str ( "The unix timestamp of the supplied date is <0 or can't be represented as `SystemTime`" ) ,
1447
- CreationError :: ExpiryTimeOutOfBounds => f. write_str ( "The supplied expiry time could cause an overflow if added to a `PositiveTimestamp`" ) ,
1398
+ CreationError :: TimestampOutOfBounds => f. write_str ( "The unix timestamp of the supplied date is less than zero" ) ,
1448
1399
CreationError :: InvalidAmount => f. write_str ( "The supplied millisatoshi amount was greater than the total bitcoin supply" ) ,
1449
1400
}
1450
1401
}
@@ -1534,19 +1485,6 @@ mod test {
1534
1485
use bitcoin_hashes:: hex:: FromHex ;
1535
1486
use bitcoin_hashes:: sha256;
1536
1487
1537
- #[ test]
1538
- fn test_system_time_bounds_assumptions ( ) {
1539
- assert_eq ! (
1540
- :: PositiveTimestamp :: from_unix_timestamp( :: MAX_TIMESTAMP + 1 ) ,
1541
- Err ( :: CreationError :: TimestampOutOfBounds )
1542
- ) ;
1543
-
1544
- assert_eq ! (
1545
- :: ExpiryTime :: from_seconds( :: MAX_EXPIRY_TIME + 1 ) ,
1546
- Err ( :: CreationError :: ExpiryTimeOutOfBounds )
1547
- ) ;
1548
- }
1549
-
1550
1488
#[ test]
1551
1489
fn test_calc_invoice_hash ( ) {
1552
1490
use :: { RawInvoice , RawHrp , RawDataPart , Currency , PositiveTimestamp } ;
@@ -1559,7 +1497,7 @@ mod test {
1559
1497
si_prefix : None ,
1560
1498
} ,
1561
1499
data : RawDataPart {
1562
- timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) . unwrap ( ) ,
1500
+ timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) ,
1563
1501
tagged_fields : vec ! [
1564
1502
PaymentHash ( :: Sha256 ( sha256:: Hash :: from_hex(
1565
1503
"0001020304050607080900010203040506070809000102030405060708090102"
@@ -1597,7 +1535,7 @@ mod test {
1597
1535
si_prefix : None ,
1598
1536
} ,
1599
1537
data : RawDataPart {
1600
- timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) . unwrap ( ) ,
1538
+ timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) ,
1601
1539
tagged_fields : vec ! [
1602
1540
PaymentHash ( Sha256 ( sha256:: Hash :: from_hex(
1603
1541
"0001020304050607080900010203040506070809000102030405060708090102"
@@ -1667,7 +1605,7 @@ mod test {
1667
1605
si_prefix : None ,
1668
1606
} ,
1669
1607
data : RawDataPart {
1670
- timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) . unwrap ( ) ,
1608
+ timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) ,
1671
1609
tagged_fields : vec ! [
1672
1610
PaymentHash ( Sha256 ( sha256:: Hash :: from_hex(
1673
1611
"0001020304050607080900010203040506070809000102030405060708090102"
0 commit comments