round_based/echo_broadcast/
error.rs

1/// An error in echo-broadcast sub-protocol
2///
3/// It may indicate that reliability check was not successful, or some other error, for instance, that
4/// a round that requires reliable broadcast behaves unexpectedly (e.g. if we received two messages
5/// from the same party and the main round didn't return an error).
6#[derive(thiserror::Error, Debug)]
7#[error(transparent)]
8pub struct EchoError(#[from] Reason);
9
10impl EchoError {
11    /// Indicates that an error was caused by failed reliability check
12    pub fn reliability_check_failed(&self) -> bool {
13        matches!(self.0, Reason::MismatchedHash)
14    }
15}
16
17#[derive(thiserror::Error, Debug)]
18pub(super) enum Reason {
19    #[error(
20        "round store received two msgs from same party and \
21        didn't return an error"
22    )]
23    StoreReceivedTwoMsgsFromSameParty,
24    #[error("received a msg from principal protocol when round is over")]
25    ReceivedMainMsgWhenRoundOver,
26    #[error("unknown sender i={i} (n={n})")]
27    UnknownSender { i: u16, n: usize },
28    #[error("local party index is out of bounds, probably indicates a bug")]
29    OwnIndexOutOfBounds { i: u16, n: usize },
30    #[error("principal round is finished, but store doesn't output")]
31    MainRoundFinishedButStoreDoesntOutput,
32
33    #[error("handle incoming echo msg")]
34    HandleEcho(#[source] crate::round::RoundInputError),
35
36    #[error("reliability check error: messages were not reliably broadcasted")]
37    MismatchedHash,
38
39    #[error("impossible state (it's a bug)")]
40    StateGone,
41
42    #[error("main round is in unexpected state (it's a bug)")]
43    UnexpectedMainRoundState,
44
45    #[error("clone error msg: RoundMsg implementation is incorrect")]
46    RoundMsgClone,
47
48    #[error(
49        "protocol attempts to send a broadcast msg twice within the same round, it's unsupported"
50    )]
51    SendTwice,
52
53    #[error("cannot convert a sent round msg back from proto msg (it's a bug)")]
54    SentMsgFromProto,
55
56    #[error(
57        "sent a message that doesn't require reliable broadcast in reliable broadcast \
58        round (round: {round}, dest: {dest:?})"
59    )]
60    SentNonReliableMsgInReliableRound {
61        dest: crate::MessageDestination,
62        round: u16,
63    },
64
65    #[error(
66        "sent a reliable broadcast message in a regular round that doesn't require \
67        reliable broadcast: you might have forgotten to register a reliable broadcast \
68        round, or round store doesn't expose a property required to identify a reliable \
69        broadcast round (round: {round})"
70    )]
71    SentReliableMsgInNonReliableRound { round: u16 },
72}
73
74/// An error originated either from main protocol or echo-broadcast sub-protocol
75#[derive(thiserror::Error, Debug)]
76pub enum Error<E> {
77    /// Error originated from main protocol
78    #[error("error originated in principal protocol")]
79    Main(#[source] E),
80    /// Error originated from echo-broadcast sub-protocol
81    #[error("echo broadcast")]
82    Echo(#[from] EchoError),
83}
84
85impl<E> From<Reason> for Error<E> {
86    fn from(value: Reason) -> Self {
87        Error::Echo(value.into())
88    }
89}
90
91/// An error returned in round completion
92#[derive(thiserror::Error, Debug)]
93pub enum CompleteRoundError<CompleteErr, SendErr> {
94    /// Error occurred while handling received message(s)
95    #[error(transparent)]
96    CompleteRound(CompleteErr),
97    /// Error occurred while sending a message to another party
98    ///
99    /// The only message we send during round completion is echo message
100    #[error(transparent)]
101    Send(SendErr),
102    /// Echo broadcast sub-protocol error
103    #[error(transparent)]
104    Echo(EchoError),
105}
106
107impl<A, B> From<Reason> for CompleteRoundError<A, B> {
108    fn from(err: Reason) -> Self {
109        CompleteRoundError::Echo(err.into())
110    }
111}
112
113impl<A, B> From<EchoError> for CompleteRoundError<A, B> {
114    fn from(err: EchoError) -> Self {
115        err.0.into()
116    }
117}