X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Ftime.rs;h=bedeab1d4890ac78c0dbda3f2506e8a28ee9f07d;hb=d9b9854e87b81e43bcd33ae7bc059cf40af5b5e1;hp=f450dc2c3015ae4da00faa2d609d01542753b85d;hpb=82474d356403d6b91c6b8ad1937e942f53f809e8;p=rust-lightning diff --git a/lightning/src/util/time.rs b/lightning/src/util/time.rs index f450dc2c..bedeab1d 100644 --- a/lightning/src/util/time.rs +++ b/lightning/src/util/time.rs @@ -16,16 +16,8 @@ pub trait Time: Copy + Sub where Self: Sized { /// Returns an instance corresponding to the current moment. fn now() -> Self; - /// Returns the amount of time elapsed since `self` was created. - fn elapsed(&self) -> Duration; - /// Returns the amount of time passed between `earlier` and `self`. fn duration_since(&self, earlier: Self) -> Duration; - - /// Returns the amount of time passed since the beginning of [`Time`]. - /// - /// Used during (de-)serialization. - fn duration_since_epoch() -> Duration; } /// A state in which time has no meaning. @@ -40,14 +32,6 @@ impl Time for Eternity { fn duration_since(&self, _earlier: Self) -> Duration { Duration::from_secs(0) } - - fn duration_since_epoch() -> Duration { - Duration::from_secs(0) - } - - fn elapsed(&self) -> Duration { - Duration::from_secs(0) - } } impl Sub for Eternity { @@ -58,10 +42,20 @@ impl Sub for Eternity { } } -#[cfg(not(feature = "no-std"))] -impl Time for std::time::Instant { +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg(feature = "std")] +pub struct MonotonicTime(std::time::Instant); + +/// The amount of time to shift `Instant` forward to prevent overflow when subtracting a `Duration` +/// from `Instant::now` on some operating systems (e.g., iOS representing `Instance` as `u64`). +#[cfg(feature = "std")] +const SHIFT: Duration = Duration::from_secs(10 * 365 * 24 * 60 * 60); // 10 years. + +#[cfg(feature = "std")] +impl Time for MonotonicTime { fn now() -> Self { - std::time::Instant::now() + let instant = std::time::Instant::now().checked_add(SHIFT).expect("Overflow on MonotonicTime instantiation"); + Self(instant) } fn duration_since(&self, earlier: Self) -> Duration { @@ -70,15 +64,17 @@ impl Time for std::time::Instant { // clocks" that go backwards in practice (likely relatively ancient kernels/etc). Thus, we // manually check for time going backwards here and return a duration of zero in that case. let now = Self::now(); - if now > earlier { now - earlier } else { Duration::from_secs(0) } + if now.0 > earlier.0 { now.0 - earlier.0 } else { Duration::from_secs(0) } } +} - fn duration_since_epoch() -> Duration { - use std::time::SystemTime; - SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap() - } - fn elapsed(&self) -> Duration { - std::time::Instant::elapsed(self) +#[cfg(feature = "std")] +impl Sub for MonotonicTime { + type Output = Self; + + fn sub(self, other: Duration) -> Self { + let instant = self.0.checked_sub(other).expect("MonotonicTime is not supposed to go backward futher than 10 years"); + Self(instant) } } @@ -106,20 +102,12 @@ pub mod tests { impl Time for SinceEpoch { fn now() -> Self { - Self(Self::duration_since_epoch()) + Self(Self::ELAPSED.with(|elapsed| elapsed.get())) } fn duration_since(&self, earlier: Self) -> Duration { self.0 - earlier.0 } - - fn duration_since_epoch() -> Duration { - Self::ELAPSED.with(|elapsed| elapsed.get()) - } - - fn elapsed(&self) -> Duration { - Self::duration_since_epoch() - self.0 - } } impl Sub for SinceEpoch { @@ -133,25 +121,20 @@ pub mod tests { #[test] fn time_passes_when_advanced() { let now = SinceEpoch::now(); - assert_eq!(now.elapsed(), Duration::from_secs(0)); SinceEpoch::advance(Duration::from_secs(1)); SinceEpoch::advance(Duration::from_secs(1)); - let elapsed = now.elapsed(); let later = SinceEpoch::now(); - assert_eq!(elapsed, Duration::from_secs(2)); - assert_eq!(later - elapsed, now); + assert_eq!(now.0 + Duration::from_secs(2), later.0); } #[test] fn time_never_passes_in_an_eternity() { let now = Eternity::now(); - let elapsed = now.elapsed(); let later = Eternity::now(); - assert_eq!(now.elapsed(), Duration::from_secs(0)); - assert_eq!(later - elapsed, now); + assert_eq!(later, now); } }