hotshot_testing/
view_sync_task.rs1use std::{collections::HashSet, marker::PhantomData, sync::Arc};
8
9use async_trait::async_trait;
10use hotshot_task_impls::events::HotShotEvent;
11use hotshot_types::traits::node_implementation::{NodeType, TestableNodeImplementation};
12use hotshot_utils::anytrace::*;
13use thiserror::Error;
14
15use crate::test_task::{TestResult, TestTaskState};
16
17#[derive(Error, Debug, Clone)]
19pub enum ViewSyncTaskError {
20 #[error("{} nodes hit view sync", hit_view_sync.len())]
21 HitViewSync { hit_view_sync: HashSet<usize> },
22}
23
24pub struct ViewSyncTask<TYPES: NodeType, I: TestableNodeImplementation<TYPES>> {
26 pub(crate) hit_view_sync: HashSet<usize>,
28 pub(crate) description: ViewSyncTaskDescription,
30 pub(crate) _pd: PhantomData<(TYPES, I)>,
32}
33
34#[async_trait]
35impl<TYPES: NodeType, I: TestableNodeImplementation<TYPES>> TestTaskState
36 for ViewSyncTask<TYPES, I>
37{
38 type Event = Arc<HotShotEvent<TYPES>>;
39 type Error = Error;
40
41 async fn handle_event(&mut self, (event, id): (Self::Event, usize)) -> Result<()> {
43 match event.as_ref() {
44 HotShotEvent::ViewSyncTimeout(..)
46 | HotShotEvent::ViewSyncPreCommitVoteRecv(_)
47 | HotShotEvent::ViewSyncCommitVoteRecv(_)
48 | HotShotEvent::ViewSyncFinalizeVoteRecv(_)
49 | HotShotEvent::ViewSyncPreCommitVoteSend(_)
50 | HotShotEvent::ViewSyncCommitVoteSend(_)
51 | HotShotEvent::ViewSyncFinalizeVoteSend(_)
52 | HotShotEvent::ViewSyncPreCommitCertificateRecv(_)
53 | HotShotEvent::ViewSyncCommitCertificateRecv(_)
54 | HotShotEvent::ViewSyncFinalizeCertificateRecv(_)
55 | HotShotEvent::ViewSyncPreCommitCertificateSend(..)
56 | HotShotEvent::ViewSyncCommitCertificateSend(..)
57 | HotShotEvent::ViewSyncFinalizeCertificateSend(..)
58 | HotShotEvent::ViewSyncTrigger(_) => {
59 self.hit_view_sync.insert(id);
60 },
61 _ => (),
62 }
63
64 Ok(())
65 }
66
67 async fn check(&self) -> TestResult {
68 match self.description.clone() {
69 ViewSyncTaskDescription::Threshold(min, max) => {
70 let num_hits = self.hit_view_sync.len();
71 if min <= num_hits && num_hits <= max {
72 TestResult::Pass
73 } else {
74 TestResult::Fail(Box::new(ViewSyncTaskError::HitViewSync {
75 hit_view_sync: self.hit_view_sync.clone(),
76 }))
77 }
78 },
79 }
80 }
81}
82
83#[derive(Clone, Debug, Copy)]
85pub enum ShouldHitViewSync {
86 Yes,
88 No,
90 Ignore,
92}
93
94#[derive(Clone, Debug)]
96pub enum ViewSyncTaskDescription {
97 Threshold(usize, usize),
99}