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::traits::node_implementation::NodeType;
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<TYPES: NodeType> {
21    /// success
22    Ok,
23    /// failure
24    Failed,
25    /// safety violation
26    Err(OverallSafetyTaskErr<TYPES>),
27    /// in progress
28    InProgress,
29}
30
31/// possible errors
32#[derive(Error, Debug, Clone)]
33pub enum OverallSafetyTaskErr<TYPES: NodeType> {
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<TYPES::View>),
48
49    #[error(
50        "Inconsistent failed views: expected: {expected_failed_views:?}, actual: \
51         {actual_failed_views:?}"
52    )]
53    InconsistentFailedViews {
54        expected_failed_views: Vec<TYPES::View>,
55        actual_failed_views: HashSet<TYPES::View>,
56    },
57    #[error(
58        "Not enough round results: results_count: {results_count}, views_count: {views_count}"
59    )]
60    NotEnoughRoundResults {
61        results_count: usize,
62        views_count: usize,
63    },
64
65    #[error("View timed out")]
66    ViewTimeout,
67}
68
69/// cross node safety properties
70#[derive(Clone, Debug)]
71pub struct OverallSafetyPropertiesDescription {
72    /// required number of successful views
73    pub num_successful_views: usize,
74    /// whether or not to check the leaf
75    pub check_leaf: bool,
76    /// whether or not to check the block
77    pub check_block: bool,
78    /// whether or not to check that we have threshold amounts of transactions each block
79    /// if 0: don't check
80    /// if n > 0, check that at least n transactions are decided upon if such information
81    /// is available
82    pub transaction_threshold: u64,
83    /// pass in the views that we expect to fail.
84    ///
85    /// the test should fail if any view on this list succeeds.
86    pub expected_view_failures: Vec<u64>,
87    /// pass in the views that may or may not fail.
88    pub possible_view_failures: Vec<u64>,
89    /// how long to wait between external events before timing out the test
90    pub decide_timeout: Duration,
91}
92
93impl Default for OverallSafetyPropertiesDescription {
94    fn default() -> Self {
95        Self {
96            num_successful_views: 50,
97            check_leaf: false,
98            check_block: true,
99            transaction_threshold: 0,
100            expected_view_failures: vec![],
101            possible_view_failures: vec![],
102            decide_timeout: Duration::from_secs(60),
103        }
104    }
105}