1use 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: {1}")]
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}