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(BuilderClient::new)
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 }
252 }
253}
254
255#[async_trait]
256impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
257 for QuorumProposalTaskState<TYPES, I, V>
258{
259 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
260 let consensus = handle.hotshot.consensus();
261
262 Self {
263 latest_proposed_view: handle.cur_view().await,
264 cur_epoch: handle.cur_epoch().await,
265 proposal_dependencies: BTreeMap::new(),
266 formed_state_cert: BTreeMap::new(),
267 formed_quorum_certificates: BTreeMap::new(),
268 formed_next_epoch_quorum_certificates: BTreeMap::new(),
269 consensus: OuterConsensus::new(consensus),
270 instance_state: handle.hotshot.instance_state(),
271 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
272 public_key: handle.public_key().clone(),
273 private_key: handle.private_key().clone(),
274 storage: handle.storage.clone(),
275 timeout: handle.hotshot.config.next_view_timeout,
276 id: handle.hotshot.id,
277 formed_upgrade_certificate: None,
278 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
279 epoch_height: handle.hotshot.config.epoch_height,
280 first_epoch: None,
281 }
282 }
283}
284
285#[async_trait]
286impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
287 for QuorumProposalRecvTaskState<TYPES, I, V>
288{
289 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
290 let consensus = handle.hotshot.consensus();
291
292 Self {
293 public_key: handle.public_key().clone(),
294 private_key: handle.private_key().clone(),
295 consensus: OuterConsensus::new(consensus),
296 cur_view: handle.cur_view().await,
297 cur_epoch: handle.cur_epoch().await,
298 membership: handle.hotshot.membership_coordinator.clone(),
299 timeout: handle.hotshot.config.next_view_timeout,
300 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
301 storage: handle.storage.clone(),
302 spawned_tasks: BTreeMap::new(),
303 id: handle.hotshot.id,
304 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
305 epoch_height: handle.hotshot.config.epoch_height,
306 first_epoch: None,
307 }
308 }
309}
310
311#[async_trait]
312impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
313 for ConsensusTaskState<TYPES, I, V>
314{
315 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
316 let consensus = handle.hotshot.consensus();
317
318 Self {
319 public_key: handle.public_key().clone(),
320 private_key: handle.private_key().clone(),
321 instance_state: handle.hotshot.instance_state(),
322 network: Arc::clone(&handle.hotshot.network),
323 membership_coordinator: handle.hotshot.membership_coordinator.clone(),
324 vote_collectors: BTreeMap::default(),
325 epoch_root_vote_collectors: BTreeMap::default(),
326 next_epoch_vote_collectors: BTreeMap::default(),
327 timeout_vote_collectors: BTreeMap::default(),
328 cur_view: handle.cur_view().await,
329 cur_view_time: Utc::now().timestamp(),
330 cur_epoch: handle.cur_epoch().await,
331 output_event_stream: handle.hotshot.external_event_stream.0.clone(),
332 timeout_task: spawn(async {}),
333 timeout: handle.hotshot.config.next_view_timeout,
334 consensus: OuterConsensus::new(consensus),
335 storage: handle.storage.clone(),
336 id: handle.hotshot.id,
337 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
338 epoch_height: handle.hotshot.config.epoch_height,
339 view_start_time: Instant::now(),
340 first_epoch: None,
341 }
342 }
343}
344
345#[async_trait]
346impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
347 for StatsTaskState<TYPES>
348{
349 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
350 StatsTaskState::<TYPES>::new(
351 handle.cur_view().await,
352 handle.cur_epoch().await,
353 handle.public_key().clone(),
354 OuterConsensus::new(handle.hotshot.consensus()),
355 handle.hotshot.membership_coordinator.clone(),
356 )
357 }
358}
359
360#[async_trait]
361impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> CreateTaskState<TYPES, I, V>
362 for RewindTaskState<TYPES>
363{
364 async fn create_from(handle: &SystemContextHandle<TYPES, I, V>) -> Self {
365 Self {
366 events: Vec::new(),
367 id: handle.hotshot.id,
368 }
369 }
370}