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
113
114
115
116
117
118
119
120
121
122
//! A coarse wall clock read off the per-lane hot path (issue #1792 item 4).
//!
//! The voucher/preimage accept path reads the wall clock twice while it holds
//! the per-lane [`Mutex`](tokio::sync::Mutex): the capability-expiry gate and
//! the `last_voucher_at` liveness stamp. Both tolerate roughly one-second
//! resolution — expiry is an on-chain grant deadline, and the stamp only drives
//! the admin "seconds since last voucher" readout — so paying a
//! `SystemTime::now()` syscall inside that critical section is pure per-proof
//! overhead that lengthens the most contended lock hold on the paid path.
//!
//! [`CoarseClock`] turns each of those two syscalls into a single relaxed
//! [`AtomicU64`] load (still two reads per proof, one load each). A background
//! task ([`CoarseClock::spawn_refresher`]) stamps the current wall clock into
//! the cell on a timer; the hot path just reads it.
//!
//! **Fallback.** Until a refresher runs the cell holds `0`, and every read falls
//! back to a live `SystemTime::now()`. So a clock with no refresher attached
//! (every unit and loopback test, which build a handler without one) reports the
//! exact wall clock on every read — the coarsening is a production-only
//! optimization, not a semantic change. `0` is a
//! safe sentinel: a live millisecond reading is `0` only at the Unix epoch
//! itself, which a running node's clock is not at, so a `0` in the cell means
//! "unrefreshed", not "midnight 1970". Even a stray `0` (a refresher that wrote
//! one, or a clock pinned there) is harmless — reads just route to a live
//! `SystemTime::now()` until the next tick, correct but not coarse.
use Arc;
use ;
use Duration;
/// Live wall clock in milliseconds since the Unix epoch, or `0` if the system
/// clock is before the epoch. The refresher writes this into the cell, and a
/// cell still at its `0` sentinel falls back to it. Mirrors the handler's
/// `unix_millis`; kept local so this module stays a self-contained utility with
/// no dependency back into the handler.
/// A wall clock the paid-delivery hot path can read with a single relaxed atomic
/// load instead of a `SystemTime::now()` syscall (issue #1792 item 4).
///
/// Refreshed on a timer by [`Self::spawn_refresher`]; reads fall back to a live
/// clock until (and if ever) a refresher runs. See the module docs.