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("VST failed: {0}")]
73 FailedVST(StateTransitionError),
74 #[error("EST failed: {0}")]
75 FailedEST(StateTransitionError),
76 #[error("Invalid 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 #[error("Block creation failed: {0}")]
85 BlockCreation(String),
86}
87
88#[derive(Debug, Error)]
89pub enum HeaderError {
90 #[error("unsupported block version")]
91 UnsupportedVersion,
92 #[error("empty block hash")]
93 EmptyHash,
94 #[error("invalid block height block_height: {0}, curr_height: {1}")]
95 MismatchHeight(u64, u64),
96 #[error("block time is less than minimum block time")]
97 BlockTimeLess,
98 #[error("block timestamp {0} is higher than local time")]
99 BlockTimeHigher(u64),
100 #[error("invalid previous block hash")]
101 PrevBlockHash,
102 #[error("block already exists")]
103 BlockExists,
104 #[error("invalid block signature: {0}")]
105 InvalidBlockSignature(String),
106 #[error("invalid seed: {0}")]
107 InvalidSeed(String),
108
109 #[error("Invalid Attestation: {0}")]
110 InvalidAttestation(AttestationError),
111 #[error("Invalid Failed Iterations: {0}")]
112 InvalidFailedIterations(FailedIterationError),
113
114 #[error(
115 "mismatch, event_bloom: {}, candidate_event_bloom: {}",
116 hex::encode(.0.as_ref()),
117 hex::encode(.1.as_ref())
118 )]
119 EventBloomMismatch(Box<[u8; 256]>, Box<[u8; 256]>),
120 #[error(
121 "mismatch, state_hash: {}, candidate_state_hash: {}",
122 hex::encode(.0),
123 hex::encode(.1)
124 )]
125 StateRootMismatch([u8; 32], [u8; 32]),
126
127 #[error("Generic error in header verification: {0}")]
128 Generic(&'static str),
129
130 #[error("Storage error '{0}' in header verification: {1}")]
131 Storage(&'static str, anyhow::Error),
132}
133
134#[derive(Debug, Error)]
135pub enum StateTransitionError {
136 #[error("Chain tip updated during operation")]
137 TipChanged,
138 #[error("Invalid slash from block: {0}")]
139 InvalidSlash(io::Error),
140 #[error("Invalid generator: {0:?}")]
141 InvalidGenerator(dusk_bytes::Error),
142 #[error("Execution failed: {0}")]
143 ExecutionError(String),
144 #[error("Verification failed: {0}")]
145 VerificationError(String),
146}
147
148impl OperationError {
149 pub fn must_vote(&self) -> bool {
150 !matches!(self, Self::FailedVST(StateTransitionError::TipChanged))
151 }
152}
153
154impl HeaderError {
155 pub fn must_vote(&self) -> bool {
156 match self {
157 HeaderError::MismatchHeight(_, _) => false,
158 HeaderError::BlockTimeHigher(_) => false,
159 HeaderError::PrevBlockHash => false,
160 HeaderError::BlockExists => false,
161 HeaderError::InvalidBlockSignature(_) => false,
162 HeaderError::Storage(..) => false,
163
164 HeaderError::BlockTimeLess => true,
165 HeaderError::UnsupportedVersion => true,
166 HeaderError::EmptyHash => true,
167 HeaderError::InvalidSeed(_) => true,
168 HeaderError::InvalidAttestation(_) => true,
169 HeaderError::InvalidFailedIterations(_) => true,
170 HeaderError::EventBloomMismatch(_, _) => true,
171 HeaderError::StateRootMismatch(_, _) => true,
172
173 HeaderError::Generic(..) => false,
174 }
175 }
176}
177
178#[derive(Debug, Clone, Copy, Error)]
179pub enum AttestationError {
180 #[error("Invalid votes for {0:?}: {1:?}")]
181 InvalidVotes(StepName, StepSigError),
182 #[error("Expected block hash: {0:?}, Got: {1:?}")]
183 InvalidHash(Hash, Hash),
184 #[error("Result: {0:?}, Expected: {1:?}")]
185 InvalidResult(RatificationResult, RatificationResult),
186}
187
188#[derive(Debug, Clone, Copy, Error)]
189pub enum FailedIterationError {
190 #[error("Too many {0}")]
191 TooMany(usize),
192 #[error("Invalid generator. Expected {0:?}")]
193 InvalidGenerator(PublicKeyBytes),
194 #[error("Invalid attestation: {0}")]
195 InvalidAttestation(AttestationError),
196}
197
198impl From<AttestationError> for HeaderError {
199 fn from(value: AttestationError) -> Self {
200 Self::InvalidAttestation(value)
201 }
202}
203
204impl From<AttestationError> for FailedIterationError {
205 fn from(value: AttestationError) -> Self {
206 Self::InvalidAttestation(value)
207 }
208}
209
210impl From<FailedIterationError> for HeaderError {
211 fn from(value: FailedIterationError) -> Self {
212 Self::InvalidFailedIterations(value)
213 }
214}
215
216impl From<io::Error> for OperationError {
217 fn from(value: io::Error) -> Self {
218 Self::InvalidIterationInfo(value)
219 }
220}
221
222impl From<InvalidFault> for OperationError {
223 fn from(value: InvalidFault) -> Self {
224 Self::InvalidFaults(value)
225 }
226}