ckb_systemtime/
lib.rs

1//! ckb_systemtime provide real system timestamp, and faketime when `enable_faketime` feature is enabled.
2mod test_faketime;
3mod test_realtime;
4
5#[cfg(feature = "enable_faketime")]
6use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
7#[cfg(not(target_family = "wasm"))]
8pub use std::time::{Duration, Instant, SystemTime};
9#[cfg(all(target_family = "wasm", target_os = "unknown"))]
10pub use web_time::{Duration, Instant, SystemTime};
11
12// Store faketime timestamp here
13#[cfg(feature = "enable_faketime")]
14static FAKETIME: AtomicU64 = AtomicU64::new(0);
15
16// Indicate whether faketime is enabled
17#[cfg(feature = "enable_faketime")]
18static FAKETIME_ENABLED: AtomicBool = AtomicBool::new(false);
19
20// Get real system's timestamp in millis
21fn system_time_as_millis() -> u64 {
22    let duration = SystemTime::now()
23        .duration_since(SystemTime::UNIX_EPOCH)
24        .expect("SystemTime before UNIX EPOCH!");
25    duration.as_secs() * 1000 + u64::from(duration.subsec_millis())
26}
27
28/// Get system's timestamp in millis
29#[cfg(not(feature = "enable_faketime"))]
30pub fn unix_time_as_millis() -> u64 {
31    system_time_as_millis()
32}
33
34/// Return FaketimeGuard to set/disable faketime
35#[cfg(feature = "enable_faketime")]
36pub fn faketime() -> FaketimeGuard {
37    FaketimeGuard {}
38}
39
40/// Get fake timestamp in millis, only available when `enable_faketime` feature is enabled
41#[cfg(feature = "enable_faketime")]
42pub fn unix_time_as_millis() -> u64 {
43    if FAKETIME_ENABLED.load(Ordering::SeqCst) {
44        return FAKETIME.load(Ordering::SeqCst);
45    }
46    system_time_as_millis()
47}
48
49/// Get system's unix_time
50pub fn unix_time() -> Duration {
51    Duration::from_millis(unix_time_as_millis())
52}
53
54/// FaketimeGuard is used to set/disable faketime,
55/// and will disable faketime when dropped
56#[cfg(feature = "enable_faketime")]
57pub struct FaketimeGuard {}
58
59#[cfg(feature = "enable_faketime")]
60impl FaketimeGuard {
61    /// Set faketime
62    #[cfg(feature = "enable_faketime")]
63    pub fn set_faketime(&self, time: u64) {
64        FAKETIME.store(time, Ordering::Release);
65        FAKETIME_ENABLED.store(true, Ordering::SeqCst);
66    }
67
68    /// Disable faketime
69    #[cfg(feature = "enable_faketime")]
70    pub fn disable_faketime(&self) {
71        FAKETIME_ENABLED.store(false, Ordering::Release);
72    }
73}
74
75#[cfg(feature = "enable_faketime")]
76impl Drop for FaketimeGuard {
77    fn drop(&mut self) {
78        self.disable_faketime()
79    }
80}