hotshot_testing/
overall_safety_task.rs

1// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
2// This file is part of the HotShot repository.
3
4// You should have received a copy of the MIT License
5// along with the HotShot repository. If not, see <https://mit-license.org/>.
6
7use std::{
8    collections::{HashMap, HashSet},
9    time::Duration,
10};
11
12use hotshot_types::data::ViewNumber;
13use thiserror::Error;
14
15/// convenience type alias for state and block
16pub type StateAndBlock<S, B> = (Vec<S>, Vec<B>);
17
18/// the status of a view
19#[derive(Debug, Clone)]
20pub enum ViewStatus {
21    /// success
22    Ok,
23    /// failure
24    Failed,
25    /// safety violation
26    Err(OverallSafetyTaskErr),
27    /// in progress
28    InProgress,
29}
30
31/// possible errors
32#[derive(Error, Debug, Clone)]
33pub enum OverallSafetyTaskErr {
34    #[error("Mismatched leaf")]
35    MismatchedLeaf,
36
37    #[error("Inconsistent blocks")]
38    InconsistentBlocks,
39
40    #[error("Inconsistent number of transactions: {map:?}")]
41    InconsistentTxnsNum { map: HashMap<u64, usize> },
42
43    #[error("Not enough decides: got: {got}, expected: {expected}")]
44    NotEnoughDecides { got: usize, expected: usize },
45
46    #[error("Too many view failures: {0:?}")]
47    TooManyFailures(HashSet<ViewNumber>),
48
49    #[error(
50        "Inconsistent failed views: expected: {expected_failed_views:?}, actual: \
51         {actual_failed_views:?}"
52    )]
53    InconsistentFailedViews {
54        expected_failed_views: Vec<ViewNumber>,
55        actual_failed_views: HashSet<ViewNumber>,
56    },
57    #[error("Not enough round results: results_count: {results_count}, views_count: {views_count}")]
58    NotEnoughRoundResults {
59        results_count: usize,
60        views_count: usize,
61    },
62
63    #[error("View timed out")]
64    ViewTimeout,
65}
66
67/// cross node safety properties
68#[derive(Clone, Debug)]
69pub struct OverallSafetyPropertiesDescription {
70    /// required number of successful views
71    pub num_successful_views: usize,
72    /// whether or not to check the leaf
73    pub check_leaf: bool,
74    /// whether or not to check the block
75    pub check_block: bool,
76    /// whether or not to check that we have threshold amounts of transactions each block
77    /// if 0: don't check
78    /// if n > 0, check that at least n transactions are decided upon if such information
79    /// is available
80    pub transaction_threshold: u64,
81    /// pass in the views that we expect to fail.
82    ///
83    /// the test should fail if any view on this list succeeds.
84    pub expected_view_failures: Vec<u64>,
85    /// pass in the views that may or may not fail.
86    pub possible_view_failures: Vec<u64>,
87    /// how long to wait between external events before timing out the test
88    pub decide_timeout: Duration,
89}
90
91impl Default for OverallSafetyPropertiesDescription {
92    fn default() -> Self {
93        Self {
94            num_successful_views: 50,
95            check_leaf: false,
96            check_block: true,
97            transaction_threshold: 0,
98            expected_view_failures: vec![],
99            possible_view_failures: vec![],
100            decide_timeout: Duration::from_secs(60),
101        }
102    }
103}