1use crate::{
4 asm::{self, Word},
5 Stack,
6};
7use core::fmt;
8use thiserror::Error;
9
10pub type CheckResult<T> = Result<T, CheckError>;
12
13#[derive(Debug, Error)]
15pub enum CheckError {
16 #[error("errors occurred while executing one or more constraints: {0}")]
18 ConstraintErrors(#[from] ConstraintErrors),
19 #[error("one or more constraints were unsatisfied: {0}")]
21 ConstraintsUnsatisfied(#[from] ConstraintsUnsatisfied),
22}
23
24#[derive(Debug, Error)]
26pub struct ConstraintErrors(pub Vec<(usize, ConstraintError)>);
27
28#[derive(Debug, Error)]
30pub struct ConstraintsUnsatisfied(pub Vec<usize>);
31
32pub type ConstraintResult<T> = Result<T, ConstraintError>;
34
35#[derive(Debug, Error)]
37pub enum ConstraintError {
38 #[error(
41 "invalid constraint evaluation result\n \
42 expected: [0] (false) or [1] (true)\n \
43 found: {0:?}"
44 )]
45 InvalidEvaluation(Stack),
46 #[error("operation at index {0} failed: {1}")]
48 Op(usize, OpError),
49}
50
51pub type OpResult<T> = Result<T, OpError>;
53
54#[derive(Debug, Error)]
56pub enum OpError {
57 #[error("access operation error: {0}")]
59 Access(#[from] AccessError),
60 #[error("ALU operation error: {0}")]
62 Alu(#[from] AluError),
63 #[error("crypto operation error: {0}")]
65 Crypto(#[from] CryptoError),
66 #[error("stack operation error: {0}")]
68 Stack(#[from] StackError),
69 #[error("repeat operation error: {0}")]
71 Repeat(#[from] RepeatError),
72 #[error("total control flow operation error: {0}")]
74 TotalControlFlow(#[from] TotalControlFlowError),
75 #[error("temporary operation error: {0}")]
77 Temporary(#[from] TemporaryError),
78 #[error("bytecode error: {0}")]
80 FromBytes(#[from] asm::FromBytesError),
81 #[error("PC counter overflowed")]
83 PcOverflow,
84 #[error("decoding error: {0}")]
86 Decode(#[from] DecodeError),
87 #[error("encoding error: {0}")]
89 Encode(#[from] EncodeError),
90}
91
92#[derive(Debug, Error)]
94pub enum AccessError {
95 #[error("decision variable slot out of bounds: {0}")]
97 DecisionSlotIxOutOfBounds(Word),
98 #[error("decision variable slot index out of bounds")]
100 DecisionIndexOutOfBounds,
101 #[error("the length of a decision variable slot is too large: {0}")]
103 DecisionLengthTooLarge(usize),
104 #[error("decision var value_ix out of bounds: {0}..{1}")]
106 DecisionValueRangeOutOfBounds(Word, Word),
107 #[error("solution data index out of bounds")]
109 SolutionDataOutOfBounds,
110 #[error("state slot_ix out of bounds: {0}")]
112 StateSlotIxOutOfBounds(Word),
113 #[error("state value_ix out of bounds: {0}..{1}")]
115 StateValueRangeOutOfBounds(Word, Word),
116 #[error("invalid state slot delta: expected `0` or `1`, found {0}")]
118 InvalidStateSlotDelta(Word),
119 #[error("the total length of the set of state mutations was too large: {0}")]
121 StateMutationsLengthTooLarge(usize),
122 #[error("the state slot value was too large: {0}")]
124 StateValueTooLarge(usize),
125 #[error("key length out of bounds: {0}")]
127 KeyLengthOutOfBounds(Word),
128 #[error("invalid access range")]
130 InvalidAccessRange,
131 #[error("the length of the slots was too large: {0}")]
133 SlotsLengthTooLarge(usize),
134 #[error("invalid `which_slots` argument: {0}")]
136 InvalidSlotType(Word),
137 #[error("missing `Access` argument: {0}")]
139 MissingArg(#[from] MissingAccessArgError),
140}
141
142#[derive(Debug, Error)]
144pub enum MissingAccessArgError {
145 #[error("missing `delta` argument for `State` operation")]
147 StateDelta,
148 #[error("missing `len` argument for `State` operation")]
150 StateLen,
151 #[error("missing `value_ix` argument for `State` operation")]
153 StateValueIx,
154 #[error("missing `slot_ix` argument for `State` operation")]
156 StateSlotIx,
157 #[error("missing `len` argument for `DecisionVar` operation")]
159 DecVarLen,
160 #[error("missing `value_ix` argument for `DecisionVar` operation")]
162 DecVarValueIx,
163 #[error("missing `slot_ix` argument for `DecisionVar` operation")]
165 DecVarSlotIx,
166}
167
168#[derive(Debug, Error)]
170pub enum AluError {
171 #[error("word overflow")]
173 Overflow,
174 #[error("word underflow")]
176 Underflow,
177 #[error("attempted to divide by zero")]
179 DivideByZero,
180}
181
182#[derive(Debug, Error)]
184pub enum CryptoError {
185 #[error("failed to verify ed25519 signature: {0}")]
187 Ed25519(#[from] ed25519_dalek::ed25519::Error),
188 #[error("failed to recover secp256k1 public key: {0}")]
190 Secp256k1(#[from] secp256k1::Error),
191 #[error("failed to parse secp256k1 recovery id")]
193 Secp256k1RecoveryId,
194}
195
196pub type StackResult<T> = Result<T, StackError>;
198
199#[derive(Debug, Error)]
201pub enum StackError {
202 #[error("attempted to pop an empty stack")]
204 Empty,
205 #[error("indexed stack out of bounds")]
207 IndexOutOfBounds,
208 #[error("the {}-word stack size limit was exceeded", crate::Stack::SIZE_LIMIT)]
210 Overflow,
211 #[error(
213 "invalid condition\n \
214 expected: [0] (false) or [1] (true)\n \
215 found: {0}"
216 )]
217 InvalidCondition(Word),
218 #[error(transparent)]
220 LenWords(#[from] LenWordsError),
221}
222
223#[derive(Debug, Error)]
225pub enum LenWordsError {
226 #[error("missing length argument for `len words` operation")]
228 MissingLength,
229 #[error("invalid length argument for `len words` operation: {0}")]
231 InvalidLength(Word),
232 #[error("length argument for `len words` operation out of bounds: {0}")]
234 OutOfBounds(Word),
235 #[error("additional length too large for `len words` operation: {0} + {1}")]
237 AdditionalOutOfBounds(usize, usize),
238}
239
240pub type RepeatResult<T> = Result<T, RepeatError>;
242
243#[derive(Debug, Error)]
245pub enum RepeatError {
246 #[error("attempted to repeat to empty stack")]
248 Empty,
249 #[error("attempted to access repeat counter with empty stack")]
251 NoCounter,
252 #[error("The count direction must be 0 or 1")]
254 InvalidCountDirection,
255 #[error("the {}-word stack size limit was exceeded", crate::Stack::SIZE_LIMIT)]
257 Overflow,
258}
259
260pub type TotalControlFlowResult<T> = Result<T, TotalControlFlowError>;
262
263#[derive(Debug, Error)]
265pub enum TotalControlFlowError {
266 #[error("jump forward if requires a boolean condition")]
268 InvalidJumpForwardIfCondition,
269 #[error("jump forward if requires to jump at least one instruction")]
271 JumpedToSelf,
272 #[error("halt if requires a boolean condition")]
274 InvalidHaltIfCondition,
275 #[error("panic if requires a boolean condition")]
277 InvalidPanicIfCondition,
278 #[error("program panicked with `PanicIf` operation. The stack at the time of panic: {0:?}")]
280 Panic(Vec<Word>),
281}
282
283pub type TemporaryResult<T> = Result<T, TemporaryError>;
285
286#[derive(Debug, Error)]
288pub enum TemporaryError {
289 #[error("attempted to pop an empty memory")]
291 Empty,
292 #[error("indexed memory out of bounds")]
294 IndexOutOfBounds,
295 #[error("the {}-word stack size limit was exceeded", crate::Memory::SIZE_LIMIT)]
297 Overflow,
298}
299
300#[derive(Debug, Error)]
302pub enum DecodeError {
303 #[error("failed to decode set: {0:?}")]
305 Set(Vec<Word>),
306 #[error("item length too large: {0}")]
308 ItemLengthTooLarge(usize),
309}
310
311#[derive(Debug, Error)]
313pub enum EncodeError {
314 #[error("item length too large: {0}")]
316 ItemLengthTooLarge(usize),
317}
318
319impl fmt::Display for ConstraintErrors {
320 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
321 f.write_str("the constraints at the following indices failed: \n")?;
322 for (ix, err) in &self.0 {
323 f.write_str(&format!(" {ix}: {err}\n"))?;
324 }
325 Ok(())
326 }
327}
328
329impl fmt::Display for ConstraintsUnsatisfied {
330 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
331 f.write_str("the constraints at the following indices returned false: \n")?;
332 for ix in &self.0 {
333 f.write_str(&format!(" {ix}\n"))?;
334 }
335 Ok(())
336 }
337}
338
339impl From<core::convert::Infallible> for OpError {
340 fn from(err: core::convert::Infallible) -> Self {
341 match err {}
342 }
343}
344impl From<MissingAccessArgError> for OpError {
345 fn from(err: MissingAccessArgError) -> Self {
346 AccessError::MissingArg(err).into()
347 }
348}