1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Time abstraction.
//!
//! `sisyphus` never reads the wall clock itself. Instead, any policy that
//! needs a notion of "how much time has elapsed" (e.g. [`MaxElapsedTime`]) asks
//! the host for it through a [`Clock`]. This is what makes the crate usable
//! inside a WebAssembly engine, a deterministic blockchain state machine, or a
//! bare-metal `no_std` target that has no `std::time::Instant`.
//!
//! [`MaxElapsedTime`]: crate::MaxElapsedTime
use Duration;
/// A source of monotonic time supplied by the host environment.
///
/// Implementors decide what an "instant" is. It can be a real
/// `std::time::Instant`, a `u64` of milliseconds from a virtual clock, a block
/// height, or a logical tick counter. The only requirement is that
/// [`duration_since`] returns the elapsed [`Duration`] between two instants
/// produced by [`now`].
///
/// [`now`]: Clock::now
/// [`duration_since`]: Clock::duration_since
///
/// # Example: a deterministic virtual clock
///
/// ```
/// use core::cell::Cell;
/// use core::time::Duration;
/// use sisyphus::Clock;
///
/// /// A clock the test fully controls, measured in milliseconds.
/// struct VirtualClock {
/// now_ms: Cell<u64>,
/// }
///
/// impl VirtualClock {
/// fn advance(&self, by: Duration) {
/// self.now_ms.set(self.now_ms.get() + by.as_millis() as u64);
/// }
/// }
///
/// impl Clock for VirtualClock {
/// type Instant = u64;
///
/// fn now(&self) -> u64 {
/// self.now_ms.get()
/// }
///
/// fn duration_since(&self, earlier: u64, now: u64) -> Duration {
/// Duration::from_millis(now.saturating_sub(earlier))
/// }
/// }
///
/// let clock = VirtualClock { now_ms: Cell::new(0) };
/// let start = clock.now();
/// clock.advance(Duration::from_millis(250));
/// assert_eq!(clock.duration_since(start, clock.now()), Duration::from_millis(250));
/// ```
/// A monotonic [`Clock`] backed by `std::time::Instant`.
///
/// Only available with the `std` feature. The default build is `no_std` and
/// expects you to bring your own clock.
;