consensus_core/
context.rs1use std::{sync::Arc, time::SystemTime};
6
7use consensus_config::{AuthorityIndex, Committee, Parameters};
8#[cfg(test)]
9use consensus_config::{NetworkKeyPair, ProtocolKeyPair};
10use iota_protocol_config::ProtocolConfig;
11#[cfg(test)]
12use tempfile::TempDir;
13use tokio::time::Instant;
14
15#[cfg(test)]
16use crate::metrics::test_metrics;
17use crate::{block::BlockTimestampMs, metrics::Metrics};
18
19#[derive(Clone)]
22pub(crate) struct Context {
23 pub own_index: AuthorityIndex,
25 pub committee: Committee,
27 pub parameters: Parameters,
29 pub protocol_config: ProtocolConfig,
31 pub metrics: Arc<Metrics>,
33 pub clock: Arc<Clock>,
35}
36
37impl Context {
38 pub(crate) fn new(
39 own_index: AuthorityIndex,
40 committee: Committee,
41 parameters: Parameters,
42 protocol_config: ProtocolConfig,
43 metrics: Arc<Metrics>,
44 clock: Arc<Clock>,
45 ) -> Self {
46 Self {
47 own_index,
48 committee,
49 parameters,
50 protocol_config,
51 metrics,
52 clock,
53 }
54 }
55
56 #[cfg(test)]
58 pub(crate) fn new_for_test(
59 committee_size: usize,
60 ) -> (Self, Vec<(NetworkKeyPair, ProtocolKeyPair)>) {
61 let (committee, keypairs) =
62 consensus_config::local_committee_and_keys(0, vec![1; committee_size]);
63 let metrics = test_metrics();
64 let temp_dir = TempDir::new().unwrap();
65 let clock = Arc::new(Clock::new());
66
67 let context = Context::new(
68 AuthorityIndex::new_for_test(0),
69 committee,
70 Parameters {
71 db_path: temp_dir.into_path(),
72 ..Default::default()
73 },
74 ProtocolConfig::get_for_max_version_UNSAFE(),
75 metrics,
76 clock,
77 );
78 (context, keypairs)
79 }
80
81 #[cfg(test)]
82 pub(crate) fn with_authority_index(mut self, authority: AuthorityIndex) -> Self {
83 self.own_index = authority;
84 self
85 }
86
87 #[cfg(test)]
88 pub(crate) fn with_committee(mut self, committee: Committee) -> Self {
89 self.committee = committee;
90 self
91 }
92
93 #[cfg(test)]
94 pub(crate) fn with_parameters(mut self, parameters: Parameters) -> Self {
95 self.parameters = parameters;
96 self
97 }
98}
99
100pub(crate) struct Clock {
107 initial_instant: Instant,
108 initial_system_time: SystemTime,
109}
110
111impl Clock {
112 pub fn new() -> Self {
113 Self {
114 initial_instant: Instant::now(),
115 initial_system_time: SystemTime::now(),
116 }
117 }
118
119 pub(crate) fn timestamp_utc_ms(&self) -> BlockTimestampMs {
123 let now: Instant = Instant::now();
124 let monotonic_system_time = self
125 .initial_system_time
126 .checked_add(
127 now.checked_duration_since(self.initial_instant)
128 .unwrap_or_else(|| {
129 panic!(
130 "current instant ({:?}) < initial instant ({:?})",
131 now, self.initial_instant
132 )
133 }),
134 )
135 .expect("Computing system time should not overflow");
136 monotonic_system_time
137 .duration_since(SystemTime::UNIX_EPOCH)
138 .unwrap_or_else(|_| {
139 panic!(
140 "system time ({:?}) < UNIX_EPOCH ({:?})",
141 monotonic_system_time,
142 SystemTime::UNIX_EPOCH,
143 )
144 })
145 .as_millis() as BlockTimestampMs
146 }
147}