dusk_consensus/
errors.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use std::io;
8
9use dusk_core::signatures::bls::Error as BlsSigError;
10use node_data::bls::PublicKeyBytes;
11use node_data::ledger::{Hash, InvalidFault};
12use node_data::message::payload::{RatificationResult, Vote};
13use node_data::StepName;
14use thiserror::Error;
15
16#[derive(Debug, Clone, Copy, Error)]
17pub enum StepSigError {
18    #[error("Failed to reach a quorum")]
19    VoteSetTooSmall,
20    #[error("Verification error {0}")]
21    VerificationFailed(BlsSigError),
22    #[error("Invalid Type")]
23    InvalidType,
24}
25
26impl From<BlsSigError> for StepSigError {
27    fn from(inner: BlsSigError) -> Self {
28        Self::VerificationFailed(inner)
29    }
30}
31
32#[derive(Debug, Clone)]
33pub enum ConsensusError {
34    InvalidBlock,
35    InvalidBlockHash,
36    InvalidBlockSize(usize),
37    InvalidSignature(BlsSigError),
38    InvalidMsgType,
39    InvalidValidationStepVotes(StepSigError),
40    InvalidPrevBlockHash(Hash),
41    InvalidQuorumType,
42    InvalidVote(Vote),
43    InvalidMsgIteration(u8),
44    FutureEvent,
45    PastEvent,
46    NotCommitteeMember,
47    CommitteeNotGenerated,
48    NotImplemented,
49    NotReady,
50    ChildTaskTerminated,
51    Canceled(u64),
52    VoteAlreadyCollected,
53    VoteMismatch(Vote, Vote),
54    TooManyTransactions(usize),
55    TooManyFaults(usize),
56    UnknownBlockSize,
57}
58
59impl From<StepSigError> for ConsensusError {
60    fn from(e: StepSigError) -> Self {
61        Self::InvalidValidationStepVotes(e)
62    }
63}
64impl From<BlsSigError> for ConsensusError {
65    fn from(e: BlsSigError) -> Self {
66        Self::InvalidSignature(e)
67    }
68}
69
70#[derive(Debug, Error)]
71pub enum OperationError {
72    #[error("failed to call VST {0}")]
73    InvalidVST(VstError),
74    #[error("failed to call EST {0}")]
75    InvalidEST(anyhow::Error),
76    #[error("failed to verify header {0}")]
77    InvalidHeader(HeaderError),
78    #[error("Unable to update metrics {0}")]
79    MetricsUpdate(anyhow::Error),
80    #[error("Invalid Iteration Info {0}")]
81    InvalidIterationInfo(io::Error),
82    #[error("Invalid Faults {0}")]
83    InvalidFaults(InvalidFault),
84}
85
86#[derive(Debug, Error)]
87pub enum HeaderError {
88    #[error("unsupported block version")]
89    UnsupportedVersion,
90    #[error("empty block hash")]
91    EmptyHash,
92    #[error("invalid block height block_height: {0}, curr_height: {0}")]
93    MismatchHeight(u64, u64),
94    #[error("block time is less than minimum block time")]
95    BlockTimeLess,
96    #[error("block timestamp {0} is higher than local time")]
97    BlockTimeHigher(u64),
98    #[error("invalid previous block hash")]
99    PrevBlockHash,
100    #[error("block already exists")]
101    BlockExists,
102    #[error("invalid block signature: {0}")]
103    InvalidBlockSignature(String),
104    #[error("invalid seed: {0}")]
105    InvalidSeed(String),
106
107    #[error("Invalid Attestation: {0}")]
108    InvalidAttestation(AttestationError),
109    #[error("Invalid Failed Iterations: {0}")]
110    InvalidFailedIterations(FailedIterationError),
111
112    #[error("Generic error in header verification: {0}")]
113    Generic(&'static str),
114
115    #[error("Storage error '{0}' in header verification: {1}")]
116    Storage(&'static str, anyhow::Error),
117}
118
119#[derive(Debug, Error)]
120pub enum VstError {
121    #[error(
122        "mismatch, event_bloom: {}, candidate_event_bloom: {}",
123        hex::encode(.0.as_ref()),
124        hex::encode(.1.as_ref())
125    )]
126    MismatchEventBloom(Box<[u8; 256]>, Box<[u8; 256]>),
127    #[error(
128        "mismatch, state_hash: {}, candidate_state_hash: {}",
129        hex::encode(.0),
130        hex::encode(.1)
131    )]
132    MismatchStateHash([u8; 32], [u8; 32]),
133    #[error("Chain tip different from the expected one")]
134    TipChanged,
135    #[error("Invalid slash from block: {0}")]
136    InvalidSlash(io::Error),
137    #[error("Invalid generator: {0:?}")]
138    InvalidGenerator(dusk_bytes::Error),
139    #[error("Generic error in vst: {0}")]
140    Generic(String),
141}
142
143impl VstError {
144    pub fn must_vote(&self) -> bool {
145        !matches!(self, Self::TipChanged)
146    }
147}
148
149impl HeaderError {
150    pub fn must_vote(&self) -> bool {
151        match self {
152            HeaderError::MismatchHeight(_, _) => false,
153            HeaderError::BlockTimeHigher(_) => false,
154            HeaderError::PrevBlockHash => false,
155            HeaderError::BlockExists => false,
156            HeaderError::InvalidBlockSignature(_) => false,
157            HeaderError::Storage(..) => false,
158
159            HeaderError::BlockTimeLess => true,
160            HeaderError::UnsupportedVersion => true,
161            HeaderError::EmptyHash => true,
162            HeaderError::InvalidSeed(_) => true,
163            HeaderError::InvalidAttestation(_) => true,
164            HeaderError::InvalidFailedIterations(_) => true,
165
166            HeaderError::Generic(..) => false,
167        }
168    }
169}
170
171#[derive(Debug, Clone, Copy, Error)]
172pub enum AttestationError {
173    #[error("Invalid votes for {0:?}: {1:?}")]
174    InvalidVotes(StepName, StepSigError),
175    #[error("Expected block hash: {0:?}, Got: {1:?}")]
176    InvalidHash(Hash, Hash),
177    #[error("Result: {0:?}, Expected: {1:?}")]
178    InvalidResult(RatificationResult, RatificationResult),
179}
180
181#[derive(Debug, Clone, Copy, Error)]
182pub enum FailedIterationError {
183    #[error("Too many {0}")]
184    TooMany(usize),
185    #[error("Invalid generator. Expected {0:?}")]
186    InvalidGenerator(PublicKeyBytes),
187    #[error("Invalid attestation: {0}")]
188    InvalidAttestation(AttestationError),
189}
190
191impl From<AttestationError> for HeaderError {
192    fn from(value: AttestationError) -> Self {
193        Self::InvalidAttestation(value)
194    }
195}
196
197impl From<AttestationError> for FailedIterationError {
198    fn from(value: AttestationError) -> Self {
199        Self::InvalidAttestation(value)
200    }
201}
202
203impl From<FailedIterationError> for HeaderError {
204    fn from(value: FailedIterationError) -> Self {
205        Self::InvalidFailedIterations(value)
206    }
207}
208
209impl From<io::Error> for OperationError {
210    fn from(value: io::Error) -> Self {
211        Self::InvalidIterationInfo(value)
212    }
213}
214
215impl From<InvalidFault> for OperationError {
216    fn from(value: InvalidFault) -> Self {
217        Self::InvalidFaults(value)
218    }
219}