1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
// This file is part of the HotShot repository.

// You should have received a copy of the MIT License
// along with the HotShot repository. If not, see <https://mit-license.org/>.

//! Error type for `HotShot`
//!
//! This module provides [`HotShotError`], which is an enum representing possible faults that can
//! occur while interacting with this crate.

use committable::Commitment;
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::{data::Leaf, traits::node_implementation::NodeType};
#[cfg(not(any(async_executor_impl = "async-std", async_executor_impl = "tokio")))]
compile_error! {"Either config option \"async-std\" or \"tokio\" must be enabled for this crate."}

/// Error type for `HotShot`
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum HotShotError<TYPES: NodeType> {
    /// The consensus state machine is in an invalid state
    #[error("Invalid state: {0}")]
    InvalidState(String),

    /// Leaf was not present in storage
    #[error("Missing leaf with commitment: {0}")]
    MissingLeaf(Commitment<Leaf<TYPES>>),

    /// Failed to serialize data
    #[error("Failed to serialize: {0}")]
    FailedToSerialize(String),

    /// Failed to deserialize data
    #[error("Failed to deserialize: {0}")]
    FailedToDeserialize(String),

    /// The view timed out
    #[error("View {view_number} timed out: {state:?}")]
    ViewTimedOut {
        /// The view number that timed out
        view_number: TYPES::View,
        /// The state that the round was in when it timed out
        state: RoundTimedoutState,
    },
}

/// Contains information about what the state of the hotshot-consensus was when a round timed out
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum RoundTimedoutState {
    /// Leader is in a Prepare phase and is waiting for a HighQC
    LeaderWaitingForHighQC,
    /// Leader is in a Prepare phase and timed out before the round min time is reached
    LeaderMinRoundTimeNotReached,
    /// Leader is waiting for prepare votes
    LeaderWaitingForPrepareVotes,
    /// Leader is waiting for precommit votes
    LeaderWaitingForPreCommitVotes,
    /// Leader is waiting for commit votes
    LeaderWaitingForCommitVotes,

    /// Replica is waiting for a prepare message
    ReplicaWaitingForPrepare,
    /// Replica is waiting for a pre-commit message
    ReplicaWaitingForPreCommit,
    /// Replica is waiting for a commit message
    ReplicaWaitingForCommit,
    /// Replica is waiting for a decide message
    ReplicaWaitingForDecide,

    /// HotShot-testing tried to collect round events, but it timed out
    TestCollectRoundEventsTimedOut,
}