1use std::{
8 collections::{BTreeMap, HashMap},
9 sync::{atomic::AtomicBool, Arc},
10 time::Instant,
11};
12
13use async_trait::async_trait;
14use chrono::Utc;
15use hotshot_task_impls::{
16 builder::BuilderClient, consensus::ConsensusTaskState, da::DaTaskState,
17 quorum_proposal::QuorumProposalTaskState, quorum_proposal_recv::QuorumProposalRecvTaskState,
18 quorum_vote::QuorumVoteTaskState, request::NetworkRequestState, rewind::RewindTaskState,
19 transactions::TransactionTaskState, upgrade::UpgradeTaskState, vid::VidTaskState,
20 view_sync::ViewSyncTaskState,
21};
22use hotshot_types::{
23 consensus::OuterConsensus,
24 traits::{
25 consensus_api::ConsensusApi,
26 node_implementation::{ConsensusTime, NodeImplementation, NodeType},
27 },
28};
29use tokio::spawn;
30
31use crate::{types::SystemContextHandle, Versions};
32
33#[async_trait]
35pub trait CreateTaskState<TYPES, I, V>
36where
37 TYPES: NodeType,
38 I: NodeImplementation<TYPES>,
39 V: Versions,
40{
41 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self;
43}
44
45#[async_trait]
46impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
47 for NetworkRequestState<TYPES, I>
48{
49 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
50 Self {
51 network: Arc::clone(&handle.hotshot.network),
52 consensus: OuterConsensus::new(handle.hotshot.consensus()),
53 view: handle.cur_view().await,
54 delay: handle.hotshot.config.data_request_delay,
55 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
56 public_key: handle.public_key().clone(),
57 private_key: handle.private_key().clone(),
58 id: handle.hotshot.id,
59 shutdown_flag: Arc::new(AtomicBool::new(false)),
60 spawned_tasks: BTreeMap::new(),
61 epoch_height: handle.epoch_height,
62 }
63 }
64}
65
66#[async_trait]
67impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
68 for UpgradeTaskState<TYPES, V>
69{
70 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
71 #[cfg(not(feature = "example-upgrade"))]
72 return Self {
73 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
74 cur_view: handle.cur_view().await,
75 cur_epoch: handle.cur_epoch().await,
76 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
77 vote_collectors: BTreeMap::default(),
78 public_key: handle.public_key().clone(),
79 private_key: handle.private_key().clone(),
80 id: handle.hotshot.id,
81 start_proposing_view: handle.hotshot.config.start_proposing_view,
82 stop_proposing_view: handle.hotshot.config.stop_proposing_view,
83 start_voting_view: handle.hotshot.config.start_voting_view,
84 stop_voting_view: handle.hotshot.config.stop_voting_view,
85 start_proposing_time: handle.hotshot.config.start_proposing_time,
86 stop_proposing_time: handle.hotshot.config.stop_proposing_time,
87 start_voting_time: handle.hotshot.config.start_voting_time,
88 stop_voting_time: handle.hotshot.config.stop_voting_time,
89 epoch_start_block: handle.hotshot.config.epoch_start_block,
90 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
91 epoch_height: handle.epoch_height,
92 consensus: OuterConsensus::new(handle.hotshot.consensus()),
93 };
94
95 #[cfg(feature = "example-upgrade")]
96 return Self {
97 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
98 cur_view: handle.cur_view().await,
99 cur_epoch: handle.cur_epoch().await,
100 membership: Arc::clone(&handle.hotshot.memberships),
101 network: Arc::clone(&handle.hotshot.network),
102 vote_collector: None.into(),
103 public_key: handle.public_key().clone(),
104 private_key: handle.private_key().clone(),
105 id: handle.hotshot.id,
106 start_proposing_view: 5,
107 stop_proposing_view: 10,
108 start_voting_view: 0,
109 stop_voting_view: 20,
110 start_proposing_time: 0,
111 stop_proposing_time: u64::MAX,
112 start_voting_time: 0,
113 stop_voting_time: u64::MAX,
114 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
115 };
116 }
117}
118
119#[async_trait]
120impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
121 for VidTaskState<TYPES, I, V>
122{
123 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
124 Self {
125 consensus: OuterConsensus::new(handle.hotshot.consensus()),
126 cur_view: handle.cur_view().await,
127 cur_epoch: handle.cur_epoch().await,
128 network: Arc::clone(&handle.hotshot.network),
129 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
130 public_key: handle.public_key().clone(),
131 private_key: handle.private_key().clone(),
132 id: handle.hotshot.id,
133 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
134 epoch_height: handle.epoch_height,
135 }
136 }
137}
138
139#[async_trait]
140impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
141 for DaTaskState<TYPES, I, V>
142{
143 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
144 Self {
145 consensus: OuterConsensus::new(handle.hotshot.consensus()),
146 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
147 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
148 network: Arc::clone(&handle.hotshot.network),
149 cur_view: handle.cur_view().await,
150 cur_epoch: handle.cur_epoch().await,
151 vote_collectors: BTreeMap::default(),
152 public_key: handle.public_key().clone(),
153 private_key: handle.private_key().clone(),
154 id: handle.hotshot.id,
155 storage: handle.storage.clone(),
156 storage_metrics: handle.storage_metrics(),
157 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
158 }
159 }
160}
161
162#[async_trait]
163impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
164 for ViewSyncTaskState<TYPES, V>
165{
166 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
167 let cur_view = handle.cur_view().await;
168
169 Self {
170 cur_view,
171 next_view: cur_view,
172 cur_epoch: handle.cur_epoch().await,
173 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
174 public_key: handle.public_key().clone(),
175 private_key: handle.private_key().clone(),
176 num_timeouts_tracked: 0,
177 replica_task_map: HashMap::default().into(),
178 pre_commit_relay_map: HashMap::default().into(),
179 commit_relay_map: HashMap::default().into(),
180 finalize_relay_map: HashMap::default().into(),
181 view_sync_timeout: handle.hotshot.config.view_sync_timeout,
182 id: handle.hotshot.id,
183 last_garbage_collected_view: TYPES::View::new(0),
184 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
185 first_epoch: None,
186 }
187 }
188}
189
190#[async_trait]
191impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
192 for TransactionTaskState<TYPES, V>
193{
194 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
195 Self {
196 builder_timeout: handle.builder_timeout(),
197 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
198 consensus: OuterConsensus::new(handle.hotshot.consensus()),
199 cur_view: handle.cur_view().await,
200 cur_epoch: handle.cur_epoch().await,
201 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
202 public_key: handle.public_key().clone(),
203 private_key: handle.private_key().clone(),
204 instance_state: handle.hotshot.instance_state(),
205 id: handle.hotshot.id,
206 builder_clients: handle
207 .hotshot
208 .config
209 .builder_urls
210 .iter()
211 .cloned()
212 .map(BuilderClient::new)
213 .collect(),
214 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
215 epoch_height: handle.epoch_height,
216 }
217 }
218}
219
220#[async_trait]
221impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
222 for QuorumVoteTaskState<TYPES, I, V>
223{
224 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
225 let consensus = handle.hotshot.consensus();
226
227 let consensus_metrics = Arc::clone(&consensus.read().await.metrics);
229
230 Self {
231 public_key: handle.public_key().clone(),
232 private_key: handle.private_key().clone(),
233 state_private_key: handle.state_private_key().clone(),
234 consensus: OuterConsensus::new(consensus),
235 instance_state: handle.hotshot.instance_state(),
236 latest_voted_view: handle.cur_view().await,
237 vote_dependencies: BTreeMap::new(),
238 network: Arc::clone(&handle.hotshot.network),
239 membership: handle.hotshot.membership_coordinator.clone(),
240 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
241 id: handle.hotshot.id,
242 storage: handle.storage.clone(),
243 storage_metrics: handle.storage_metrics(),
244 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
245 epoch_height: handle.hotshot.config.epoch_height,
246 consensus_metrics,
247 first_epoch: None,
248 stake_table_capacity: handle.hotshot.config.stake_table_capacity,
249 }
250 }
251}
252
253#[async_trait]
254impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
255 for QuorumProposalTaskState<TYPES, I, V>
256{
257 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
258 let consensus = handle.hotshot.consensus();
259
260 Self {
261 latest_proposed_view: handle.cur_view().await,
262 cur_epoch: handle.cur_epoch().await,
263 proposal_dependencies: BTreeMap::new(),
264 formed_state_cert: BTreeMap::new(),
265 formed_quorum_certificates: BTreeMap::new(),
266 formed_next_epoch_quorum_certificates: BTreeMap::new(),
267 consensus: OuterConsensus::new(consensus),
268 instance_state: handle.hotshot.instance_state(),
269 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
270 public_key: handle.public_key().clone(),
271 private_key: handle.private_key().clone(),
272 storage: handle.storage.clone(),
273 timeout: handle.hotshot.config.next_view_timeout,
274 id: handle.hotshot.id,
275 formed_upgrade_certificate: None,
276 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
277 epoch_height: handle.hotshot.config.epoch_height,
278 first_epoch: None,
279 }
280 }
281}
282
283#[async_trait]
284impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
285 for QuorumProposalRecvTaskState<TYPES, I, V>
286{
287 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
288 let consensus = handle.hotshot.consensus();
289
290 Self {
291 public_key: handle.public_key().clone(),
292 private_key: handle.private_key().clone(),
293 consensus: OuterConsensus::new(consensus),
294 cur_view: handle.cur_view().await,
295 cur_epoch: handle.cur_epoch().await,
296 membership: handle.hotshot.membership_coordinator.clone(),
297 timeout: handle.hotshot.config.next_view_timeout,
298 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
299 storage: handle.storage.clone(),
300 spawned_tasks: BTreeMap::new(),
301 id: handle.hotshot.id,
302 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
303 epoch_height: handle.hotshot.config.epoch_height,
304 first_epoch: None,
305 }
306 }
307}
308
309#[async_trait]
310impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
311 for ConsensusTaskState<TYPES, I, V>
312{
313 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
314 let consensus = handle.hotshot.consensus();
315
316 Self {
317 public_key: handle.public_key().clone(),
318 private_key: handle.private_key().clone(),
319 instance_state: handle.hotshot.instance_state(),
320 network: Arc::clone(&handle.hotshot.network),
321 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
322 vote_collectors: BTreeMap::default(),
323 epoch_root_vote_collectors: BTreeMap::default(),
324 next_epoch_vote_collectors: BTreeMap::default(),
325 timeout_vote_collectors: BTreeMap::default(),
326 cur_view: handle.cur_view().await,
327 cur_view_time: Utc::now().timestamp(),
328 cur_epoch: handle.cur_epoch().await,
329 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
330 timeout_task: spawn(async {}),
331 timeout: handle.hotshot.config.next_view_timeout,
332 consensus: OuterConsensus::new(consensus),
333 storage: handle.storage.clone(),
334 id: handle.hotshot.id,
335 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
336 epoch_height: handle.hotshot.config.epoch_height,
337 view_start_time: Instant::now(),
338 first_epoch: None,
339 }
340 }
341}
342
343#[async_trait]
344impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
345 for RewindTaskState<TYPES>
346{
347 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
348 Self {
349 events: Vec::new(),
350 id: handle.hotshot.id,
351 }
352 }
353}