lightning_signer/util/
clock.rs

1use crate::SendSync;
2use core::time::Duration;
3
4/// A clock provider
5///
6/// On std platforms, use the StandardClock implementation
7pub trait Clock: SendSync {
8    /// A duration since the UNIX epoch
9    fn now(&self) -> Duration;
10
11    #[cfg(feature = "timeless_workaround")]
12    #[allow(missing_docs)]
13    fn set_workaround_time(&self, now: Duration);
14}
15
16#[cfg(feature = "std")]
17mod standard {
18    use super::SendSync;
19    use core::time::Duration;
20    use std::time::SystemTime;
21
22    /// A clock provider using the std::time::SystemTime
23    pub struct StandardClock();
24
25    impl SendSync for StandardClock {}
26
27    impl super::Clock for StandardClock {
28        fn now(&self) -> Duration {
29            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()
30        }
31    }
32}
33
34#[cfg(feature = "std")]
35pub use standard::*;
36
37mod manual {
38    use crate::prelude::*;
39    use alloc::sync::Arc;
40    use core::time::Duration;
41
42    /// A clock provider with manually updated notion of "now"
43    pub struct ManualClock(Arc<Mutex<Duration>>);
44
45    impl SendSync for ManualClock {}
46
47    impl super::Clock for ManualClock {
48        fn now(&self) -> Duration {
49            self.0.lock().unwrap().clone()
50        }
51
52        #[cfg(feature = "timeless_workaround")]
53        fn set_workaround_time(&self, now: Duration) {
54            self.set(now);
55        }
56    }
57
58    impl ManualClock {
59        /// Create a manual clock
60        pub fn new(now: Duration) -> Self {
61            ManualClock(Arc::new(Mutex::new(now)))
62        }
63
64        /// Set the current time as duration since the UNIX epoch
65        pub fn set(&self, now: Duration) {
66            *self.0.lock().unwrap() = now;
67        }
68    }
69}
70
71pub use manual::*;
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use std::thread::sleep;
77    use std::time::SystemTime;
78
79    #[test]
80    fn std_test() {
81        let clock = StandardClock();
82        clock.now();
83    }
84
85    #[test]
86    fn manual_test() {
87        let now1 = now();
88        let clock = ManualClock::new(now1);
89        let dur1 = clock.now();
90        sleep(Duration::from_millis(1));
91        let now2 = now();
92        assert_ne!(now1, now2);
93        clock.set(now2);
94        let dur2 = clock.now();
95        assert_ne!(dur1, dur2);
96    }
97
98    fn now() -> Duration {
99        SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()
100    }
101}