1use std::{
8 collections::BTreeMap,
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 stats::StatsTaskState, transactions::TransactionTaskState, upgrade::UpgradeTaskState,
20 vid::VidTaskState, 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: BTreeMap::default().into(),
178 pre_commit_relay_map: BTreeMap::default().into(),
179 commit_relay_map: BTreeMap::default().into(),
180 finalize_relay_map: BTreeMap::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 highest_finalized_epoch_view: (None, TYPES::View::new(0)),
187 epoch_height: handle.epoch_height,
188 }
189 }
190}
191
192#[async_trait]
193impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
194 for TransactionTaskState<TYPES, V>
195{
196 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
197 Self {
198 builder_timeout: handle.builder_timeout(),
199 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
200 consensus: OuterConsensus::new(handle.hotshot.consensus()),
201 cur_view: handle.cur_view().await,
202 cur_epoch: handle.cur_epoch().await,
203 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
204 public_key: handle.public_key().clone(),
205 private_key: handle.private_key().clone(),
206 instance_state: handle.hotshot.instance_state(),
207 id: handle.hotshot.id,
208 builder_clients: handle
209 .hotshot
210 .config
211 .builder_urls
212 .iter()
213 .cloned()
214 .map(|url| BuilderClient::new(url, handle.builder_timeout()))
215 .collect(),
216 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
217 epoch_height: handle.epoch_height,
218 }
219 }
220}
221
222#[async_trait]
223impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
224 for QuorumVoteTaskState<TYPES, I, V>
225{
226 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
227 let consensus = handle.hotshot.consensus();
228
229 let consensus_metrics = Arc::clone(&consensus.read().await.metrics);
231
232 Self {
233 public_key: handle.public_key().clone(),
234 private_key: handle.private_key().clone(),
235 state_private_key: handle.state_private_key().clone(),
236 consensus: OuterConsensus::new(consensus),
237 instance_state: handle.hotshot.instance_state(),
238 latest_voted_view: handle.cur_view().await,
239 vote_dependencies: BTreeMap::new(),
240 network: Arc::clone(&handle.hotshot.network),
241 membership: handle.hotshot.membership_coordinator.clone(),
242 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
243 id: handle.hotshot.id,
244 storage: handle.storage.clone(),
245 storage_metrics: handle.storage_metrics(),
246 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
247 epoch_height: handle.hotshot.config.epoch_height,
248 consensus_metrics,
249 first_epoch: None,
250 stake_table_capacity: handle.hotshot.config.stake_table_capacity,
251 da_committees: handle.hotshot.config.da_committees.clone(),
252 }
253 }
254}
255
256#[async_trait]
257impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
258 for QuorumProposalTaskState<TYPES, I, V>
259{
260 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
261 let consensus = handle.hotshot.consensus();
262
263 Self {
264 latest_proposed_view: handle.cur_view().await,
265 cur_epoch: handle.cur_epoch().await,
266 proposal_dependencies: BTreeMap::new(),
267 formed_state_cert: BTreeMap::new(),
268 formed_quorum_certificates: BTreeMap::new(),
269 formed_next_epoch_quorum_certificates: BTreeMap::new(),
270 consensus: OuterConsensus::new(consensus),
271 instance_state: handle.hotshot.instance_state(),
272 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
273 public_key: handle.public_key().clone(),
274 private_key: handle.private_key().clone(),
275 storage: handle.storage.clone(),
276 timeout: handle.hotshot.config.next_view_timeout,
277 id: handle.hotshot.id,
278 formed_upgrade_certificate: None,
279 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
280 epoch_height: handle.hotshot.config.epoch_height,
281 first_epoch: None,
282 }
283 }
284}
285
286#[async_trait]
287impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
288 for QuorumProposalRecvTaskState<TYPES, I, V>
289{
290 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
291 let consensus = handle.hotshot.consensus();
292
293 Self {
294 public_key: handle.public_key().clone(),
295 private_key: handle.private_key().clone(),
296 consensus: OuterConsensus::new(consensus),
297 cur_view: handle.cur_view().await,
298 cur_epoch: handle.cur_epoch().await,
299 membership: handle.hotshot.membership_coordinator.clone(),
300 timeout: handle.hotshot.config.next_view_timeout,
301 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
302 storage: handle.storage.clone(),
303 spawned_tasks: BTreeMap::new(),
304 id: handle.hotshot.id,
305 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
306 epoch_height: handle.hotshot.config.epoch_height,
307 first_epoch: None,
308 }
309 }
310}
311
312#[async_trait]
313impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
314 for ConsensusTaskState<TYPES, I, V>
315{
316 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
317 let consensus = handle.hotshot.consensus();
318
319 Self {
320 public_key: handle.public_key().clone(),
321 private_key: handle.private_key().clone(),
322 instance_state: handle.hotshot.instance_state(),
323 network: Arc::clone(&handle.hotshot.network),
324 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
325 vote_collectors: BTreeMap::default(),
326 epoch_root_vote_collectors: BTreeMap::default(),
327 next_epoch_vote_collectors: BTreeMap::default(),
328 timeout_vote_collectors: BTreeMap::default(),
329 cur_view: handle.cur_view().await,
330 cur_view_time: Utc::now().timestamp(),
331 cur_epoch: handle.cur_epoch().await,
332 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
333 timeout_task: spawn(async {}),
334 timeout: handle.hotshot.config.next_view_timeout,
335 consensus: OuterConsensus::new(consensus),
336 storage: handle.storage.clone(),
337 id: handle.hotshot.id,
338 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
339 epoch_height: handle.hotshot.config.epoch_height,
340 view_start_time: Instant::now(),
341 first_epoch: None,
342 }
343 }
344}
345
346#[async_trait]
347impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
348 for StatsTaskState<TYPES>
349{
350 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
351 StatsTaskState::<TYPES>::new(
352 handle.cur_view().await,
353 handle.cur_epoch().await,
354 handle.public_key().clone(),
355 OuterConsensus::new(handle.hotshot.consensus()),
356 handle.hotshot.membership_coordinator.clone(),
357 )
358 }
359}
360
361#[async_trait]
362impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
363 for RewindTaskState<TYPES>
364{
365 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
366 Self {
367 events: Vec::new(),
368 id: handle.hotshot.id,
369 }
370 }
371}