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