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