solana_clock/lib.rs
1//! Information about the network's clock, ticks, slots, etc.
2//!
3//! Time in Solana is marked primarily by _slots_, which occur approximately every
4//! 400 milliseconds, and are numbered sequentially. For every slot, a leader is
5//! chosen from the validator set, and that leader is expected to produce a new
6//! block, though sometimes leaders may fail to do so. Blocks can be identified
7//! by their slot number, and some slots do not contain a block.
8//!
9//! An approximation of the passage of real-world time can be calculated by
10//! multiplying a number of slots by [`DEFAULT_MS_PER_SLOT`], which is a constant target
11//! time for the network to produce slots. Note though that this method suffers
12//! a variable amount of drift, as the network does not produce slots at exactly
13//! the target rate, and the greater number of slots being calculated for, the
14//! greater the drift. Epochs cannot be used this way as they contain variable
15//! numbers of slots.
16//!
17//! The network's current view of the real-world time can always be accessed via
18//! [`Clock::unix_timestamp`], which is produced by an [oracle derived from the
19//! validator set][oracle].
20//!
21//! [oracle]: https://docs.solanalabs.com/implemented-proposals/validator-timestamp-oracle
22#![no_std]
23#![cfg_attr(docsrs, feature(doc_auto_cfg))]
24
25#[cfg(feature = "sysvar")]
26pub mod sysvar;
27
28#[cfg(feature = "serde")]
29use serde_derive::{Deserialize, Serialize};
30use solana_sdk_macro::CloneZeroed;
31
32/// The default tick rate that the cluster attempts to achieve (160 per second).
33///
34/// Note that the actual tick rate at any given time should be expected to drift.
35pub const DEFAULT_TICKS_PER_SECOND: u64 = 160;
36
37#[cfg(test)]
38static_assertions::const_assert_eq!(MS_PER_TICK, 6);
39
40/// The number of milliseconds per tick (6).
41pub const MS_PER_TICK: u64 = 1000 / DEFAULT_TICKS_PER_SECOND;
42
43// At 160 ticks/s, 64 ticks per slot implies that leader rotation and voting will happen
44// every 400 ms. A fast voting cadence ensures faster finality and convergence
45pub const DEFAULT_TICKS_PER_SLOT: u64 = 64;
46
47// GCP n1-standard hardware and also a xeon e5-2520 v4 are about this rate of hashes/s
48pub const DEFAULT_HASHES_PER_SECOND: u64 = 2_000_000;
49
50// Empirical sampling of mainnet validator hash rate showed the following stake
51// percentages can exceed the designated hash rates as of July 2023:
52// 97.6%
53pub const UPDATED_HASHES_PER_SECOND_2: u64 = 2_800_000;
54// 96.2%
55pub const UPDATED_HASHES_PER_SECOND_3: u64 = 4_400_000;
56// 96.2%
57pub const UPDATED_HASHES_PER_SECOND_4: u64 = 7_600_000;
58// 96.2%
59pub const UPDATED_HASHES_PER_SECOND_5: u64 = 9_200_000;
60// 96.2%
61pub const UPDATED_HASHES_PER_SECOND_6: u64 = 10_000_000;
62
63#[cfg(test)]
64static_assertions::const_assert_eq!(DEFAULT_HASHES_PER_TICK, 12_500);
65pub const DEFAULT_HASHES_PER_TICK: u64 = DEFAULT_HASHES_PER_SECOND / DEFAULT_TICKS_PER_SECOND;
66
67#[cfg(test)]
68static_assertions::const_assert_eq!(UPDATED_HASHES_PER_TICK2, 17_500);
69pub const UPDATED_HASHES_PER_TICK2: u64 = UPDATED_HASHES_PER_SECOND_2 / DEFAULT_TICKS_PER_SECOND;
70
71#[cfg(test)]
72static_assertions::const_assert_eq!(UPDATED_HASHES_PER_TICK3, 27_500);
73pub const UPDATED_HASHES_PER_TICK3: u64 = UPDATED_HASHES_PER_SECOND_3 / DEFAULT_TICKS_PER_SECOND;
74
75#[cfg(test)]
76static_assertions::const_assert_eq!(UPDATED_HASHES_PER_TICK4, 47_500);
77pub const UPDATED_HASHES_PER_TICK4: u64 = UPDATED_HASHES_PER_SECOND_4 / DEFAULT_TICKS_PER_SECOND;
78
79#[cfg(test)]
80static_assertions::const_assert_eq!(UPDATED_HASHES_PER_TICK5, 57_500);
81pub const UPDATED_HASHES_PER_TICK5: u64 = UPDATED_HASHES_PER_SECOND_5 / DEFAULT_TICKS_PER_SECOND;
82
83#[cfg(test)]
84static_assertions::const_assert_eq!(UPDATED_HASHES_PER_TICK6, 62_500);
85pub const UPDATED_HASHES_PER_TICK6: u64 = UPDATED_HASHES_PER_SECOND_6 / DEFAULT_TICKS_PER_SECOND;
86
87// 1 Dev Epoch = 400 ms * 8192 ~= 55 minutes
88pub const DEFAULT_DEV_SLOTS_PER_EPOCH: u64 = 8192;
89
90#[cfg(test)]
91static_assertions::const_assert_eq!(SECONDS_PER_DAY, 86_400);
92pub const SECONDS_PER_DAY: u64 = 24 * 60 * 60;
93
94#[cfg(test)]
95static_assertions::const_assert_eq!(TICKS_PER_DAY, 13_824_000);
96pub const TICKS_PER_DAY: u64 = DEFAULT_TICKS_PER_SECOND * SECONDS_PER_DAY;
97
98#[cfg(test)]
99static_assertions::const_assert_eq!(DEFAULT_SLOTS_PER_EPOCH, 432_000);
100
101/// The number of slots per epoch after initial network warmup.
102///
103/// 1 Epoch ~= 2 days.
104pub const DEFAULT_SLOTS_PER_EPOCH: u64 = 2 * TICKS_PER_DAY / DEFAULT_TICKS_PER_SLOT;
105
106// leader schedule is governed by this
107pub const NUM_CONSECUTIVE_LEADER_SLOTS: u64 = 4;
108
109#[cfg(test)]
110static_assertions::const_assert_eq!(DEFAULT_MS_PER_SLOT, 400);
111/// The expected duration of a slot (400 milliseconds).
112pub const DEFAULT_MS_PER_SLOT: u64 = 1_000 * DEFAULT_TICKS_PER_SLOT / DEFAULT_TICKS_PER_SECOND;
113pub const DEFAULT_S_PER_SLOT: f64 = DEFAULT_TICKS_PER_SLOT as f64 / DEFAULT_TICKS_PER_SECOND as f64;
114
115/// The time window of recent block hash values over which the bank will track
116/// signatures.
117///
118/// Once the bank discards a block hash, it will reject any transactions that
119/// use that `recent_blockhash` in a transaction. Lowering this value reduces
120/// memory consumption, but requires a client to update its `recent_blockhash`
121/// more frequently. Raising the value lengthens the time a client must wait to
122/// be certain a missing transaction will not be processed by the network.
123pub const MAX_HASH_AGE_IN_SECONDS: usize = 120;
124
125#[cfg(test)]
126static_assertions::const_assert_eq!(MAX_RECENT_BLOCKHASHES, 300);
127// Number of maximum recent blockhashes (one blockhash per non-skipped slot)
128pub const MAX_RECENT_BLOCKHASHES: usize =
129 MAX_HASH_AGE_IN_SECONDS * DEFAULT_TICKS_PER_SECOND as usize / DEFAULT_TICKS_PER_SLOT as usize;
130
131#[cfg(test)]
132static_assertions::const_assert_eq!(MAX_PROCESSING_AGE, 150);
133// The maximum age of a blockhash that will be accepted by the leader
134pub const MAX_PROCESSING_AGE: usize = MAX_RECENT_BLOCKHASHES / 2;
135
136/// This is maximum time consumed in forwarding a transaction from one node to next, before
137/// it can be processed in the target node
138pub const MAX_TRANSACTION_FORWARDING_DELAY_GPU: usize = 2;
139
140/// More delay is expected if CUDA is not enabled (as signature verification takes longer)
141pub const MAX_TRANSACTION_FORWARDING_DELAY: usize = 6;
142
143/// Transaction forwarding, which leader to forward to and how long to hold
144pub const FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET: u64 = 2;
145pub const HOLD_TRANSACTIONS_SLOT_OFFSET: u64 = 20;
146
147/// The unit of time given to a leader for encoding a block.
148///
149/// It is some some number of _ticks_ long.
150pub type Slot = u64;
151
152/// Uniquely distinguishes every version of a slot.
153///
154/// The `BankId` is unique even if the slot number of two different slots is the
155/// same. This can happen in the case of e.g. duplicate slots.
156pub type BankId = u64;
157
158/// The unit of time a given leader schedule is honored.
159///
160/// It lasts for some number of [`Slot`]s.
161pub type Epoch = u64;
162
163pub const GENESIS_EPOCH: Epoch = 0;
164// must be sync with Account::rent_epoch::default()
165pub const INITIAL_RENT_EPOCH: Epoch = 0;
166
167/// An index to the slots of a epoch.
168pub type SlotIndex = u64;
169
170/// The number of slots in a epoch.
171pub type SlotCount = u64;
172
173/// An approximate measure of real-world time.
174///
175/// Expressed as Unix time (i.e. seconds since the Unix epoch).
176pub type UnixTimestamp = i64;
177
178/// A representation of network time.
179///
180/// All members of `Clock` start from 0 upon network boot.
181#[repr(C)]
182#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
183#[derive(Debug, CloneZeroed, Default, PartialEq, Eq)]
184pub struct Clock {
185 /// The current `Slot`.
186 pub slot: Slot,
187 /// The timestamp of the first `Slot` in this `Epoch`.
188 pub epoch_start_timestamp: UnixTimestamp,
189 /// The current `Epoch`.
190 pub epoch: Epoch,
191 /// The future `Epoch` for which the leader schedule has
192 /// most recently been calculated.
193 pub leader_schedule_epoch: Epoch,
194 /// The approximate real world time of the current slot.
195 ///
196 /// This value was originally computed from genesis creation time and
197 /// network time in slots, incurring a lot of drift. Following activation of
198 /// the [`timestamp_correction` and `timestamp_bounding`][tsc] features it
199 /// is calculated using a [validator timestamp oracle][oracle].
200 ///
201 /// [tsc]: https://docs.solanalabs.com/implemented-proposals/bank-timestamp-correction
202 /// [oracle]: https://docs.solanalabs.com/implemented-proposals/validator-timestamp-oracle
203 pub unix_timestamp: UnixTimestamp,
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_clone() {
212 let clock = Clock {
213 slot: 1,
214 epoch_start_timestamp: 2,
215 epoch: 3,
216 leader_schedule_epoch: 4,
217 unix_timestamp: 5,
218 };
219 let cloned_clock = clock.clone();
220 assert_eq!(cloned_clock, clock);
221 }
222}