1#[doc(inline)]
4use crate::{
5 asm::{self, Word},
6 Gas,
7};
8use core::convert::Infallible;
9use thiserror::Error;
10
11pub type ExecResult<T, E> = Result<T, ExecError<E>>;
13
14pub type EvalResult<T, E> = Result<T, EvalError<E>>;
16
17pub type OpResult<T, E = Infallible> = Result<T, OpError<E>>;
19
20#[derive(Debug, Error)]
22#[error("operation at index {0} failed: {1}")]
23pub struct ExecError<E>(pub usize, pub OpError<E>);
24
25#[derive(Debug, Error)]
27pub enum EvalError<E> {
28 #[error("{0}")]
30 Exec(#[from] ExecError<E>),
31 #[error(
34 "invalid constraint evaluation result\n \
35 expected: [0] (false) or [1] (true)\n \
36 found: {0:?}"
37 )]
38 InvalidEvaluation(crate::Stack),
39}
40
41#[derive(Debug, Error)]
43pub enum OpError<E = Infallible> {
44 #[error("access operation error: {0}")]
46 Access(#[from] AccessError),
47 #[error("ALU operation error: {0}")]
49 Alu(#[from] AluError),
50 #[error("crypto operation error: {0}")]
52 Crypto(#[from] CryptoError),
53 #[error("stack operation error: {0}")]
55 Stack(#[from] StackError),
56 #[error("repeat operation error: {0}")]
58 Repeat(#[from] RepeatError),
59 #[error("total control flow operation error: {0}")]
61 TotalControlFlow(#[from] TotalControlFlowError),
62 #[error("memory operation error: {0}")]
64 Memory(#[from] MemoryError),
65 #[error("parent memory operation error: {0}")]
67 ParentMemory(#[from] ParentMemoryError),
68 #[error("PC counter overflowed")]
70 PcOverflow,
71 #[error("decoding error: {0}")]
73 Decode(#[from] DecodeError),
74 #[error("encoding error: {0}")]
76 Encode(#[from] EncodeError),
77 #[error("state read operation error: {0}")]
79 StateRead(E),
80 #[error("compute operation error: {0}")]
82 Compute(#[from] ComputeError<E>),
83 #[error("bytecode error: {0}")]
85 FromBytes(#[from] asm::FromBytesError),
86 #[error("{0}")]
88 OutOfGas(#[from] OutOfGasError),
89}
90
91#[derive(Debug, Error)]
93#[error(
94 "operation cost would exceed gas limit\n \
95 spent: {spent} gas\n \
96 op cost: {op_gas} gas\n \
97 limit: {limit} gas"
98)]
99pub struct OutOfGasError {
100 pub spent: Gas,
102 pub op_gas: Gas,
104 pub limit: Gas,
106}
107
108#[derive(Debug, Error)]
110pub enum StateReadArgError {
111 #[error("memory error: {0}")]
113 Memory(#[from] MemoryError),
114 #[error("stack operation error: {0}")]
116 Stack(#[from] StackError),
117}
118
119#[derive(Debug, Error)]
121pub enum ControlFlowError {
122 #[error("invalid condition value {0}, expected 0 (false) or 1 (true)")]
126 InvalidJumpIfCondition(Word),
127}
128
129#[derive(Debug, Error)]
131pub enum AccessError {
132 #[error("predicate data slot out of bounds: {0}")]
134 PredicateDataSlotIxOutOfBounds(Word),
135 #[error("the length of a predicate data value is too large: {0}")]
137 PredicateDataValueTooLarge(usize),
138 #[error("predicate data value_ix out of bounds: {0}..{1}")]
140 PredicateDataValueRangeOutOfBounds(Word, Word),
141 #[error("state slot_ix out of bounds: {0}")]
143 StateSlotIxOutOfBounds(Word),
144 #[error("state value_ix out of bounds: {0}..{1}")]
146 StateValueRangeOutOfBounds(Word, Word),
147 #[error("invalid state slot delta: expected `0` or `1`, found {0}")]
149 InvalidStateSlotDelta(Word),
150 #[error("the total length of the set of state mutations was too large: {0}")]
152 StateMutationsLengthTooLarge(usize),
153 #[error("the state slot value was too large: {0}")]
155 StateValueTooLarge(usize),
156 #[error("key length out of bounds: {0}")]
158 KeyLengthOutOfBounds(Word),
159 #[error("invalid access range")]
161 InvalidAccessRange,
162 #[error("the length of the slots was too large: {0}")]
164 SlotsLengthTooLarge(usize),
165 #[error("invalid `which_slots` argument: {0}")]
167 InvalidSlotType(Word),
168 #[error("missing `Access` argument: {0}")]
170 MissingArg(#[from] MissingAccessArgError),
171}
172
173#[derive(Debug, Error)]
175pub enum MissingAccessArgError {
176 #[error("missing `delta` argument for `State` operation")]
178 StateDelta,
179 #[error("missing `len` argument for `State` operation")]
181 StateLen,
182 #[error("missing `value_ix` argument for `State` operation")]
184 StateValueIx,
185 #[error("missing `slot_ix` argument for `State` operation")]
187 StateSlotIx,
188 #[error("missing `len` argument for `PredicateData` operation")]
190 PredDataLen,
191 #[error("missing `value_ix` argument for `PredicateData` operation")]
193 PredDataValueIx,
194 #[error("missing `slot_ix` argument for `PredicateData` operation")]
196 PredDataSlotIx,
197}
198
199#[derive(Debug, Error)]
201pub enum AluError {
202 #[error("word overflow")]
204 Overflow,
205 #[error("word underflow")]
207 Underflow,
208 #[error("attempted to divide by zero")]
210 DivideByZero,
211}
212
213#[derive(Debug, Error)]
215pub enum CryptoError {
216 #[error("failed to verify ed25519 signature: {0}")]
218 Ed25519(#[from] ed25519_dalek::ed25519::Error),
219 #[error("failed to recover secp256k1 public key: {0}")]
221 Secp256k1(#[from] secp256k1::Error),
222 #[error("failed to parse secp256k1 recovery id")]
224 Secp256k1RecoveryId,
225}
226
227pub type StackResult<T> = Result<T, StackError>;
229
230#[derive(Debug, Error)]
232pub enum StackError {
233 #[error("attempted to pop an empty stack")]
235 Empty,
236 #[error("indexed stack out of bounds")]
238 IndexOutOfBounds,
239 #[error("the {}-word stack size limit was exceeded", crate::Stack::SIZE_LIMIT)]
241 Overflow,
242 #[error(
244 "invalid condition\n \
245 expected: [0] (false) or [1] (true)\n \
246 found: {0}"
247 )]
248 InvalidCondition(Word),
249 #[error(transparent)]
251 LenWords(#[from] LenWordsError),
252}
253
254#[derive(Debug, Error)]
256pub enum LenWordsError {
257 #[error("missing length argument for `len words` operation")]
259 MissingLength,
260 #[error("invalid length argument for `len words` operation: {0}")]
262 InvalidLength(Word),
263 #[error("length argument for `len words` operation out of bounds: {0}")]
265 OutOfBounds(Word),
266 #[error("additional length too large for `len words` operation: {0} + {1}")]
268 AdditionalOutOfBounds(usize, usize),
269}
270
271pub type RepeatResult<T> = Result<T, RepeatError>;
273
274#[derive(Debug, Error)]
276pub enum RepeatError {
277 #[error("attempted to repeat to empty stack")]
279 Empty,
280 #[error("attempted to access repeat counter with empty stack")]
282 NoCounter,
283 #[error("The count direction must be 0 or 1")]
285 InvalidCountDirection,
286 #[error("the {}-word stack size limit was exceeded", crate::Stack::SIZE_LIMIT)]
288 Overflow,
289}
290
291pub type TotalControlFlowResult<T> = Result<T, TotalControlFlowError>;
293
294#[derive(Debug, Error)]
296pub enum TotalControlFlowError {
297 #[error("jump forward if requires a boolean condition")]
299 InvalidJumpForwardIfCondition,
300 #[error("jump forward if requires to jump at least one instruction")]
302 JumpedToSelf,
303 #[error("halt if requires a boolean condition")]
305 InvalidHaltIfCondition,
306 #[error("panic if requires a boolean condition")]
308 InvalidPanicIfCondition,
309 #[error("program panicked with `PanicIf` operation. The stack at the time of panic: {0:?}")]
311 Panic(Vec<Word>),
312}
313
314pub type MemoryResult<T> = Result<T, MemoryError>;
316
317#[derive(Debug, Error)]
319pub enum MemoryError {
320 #[error("attempted to pop an empty memory")]
322 Empty,
323 #[error("indexed memory out of bounds")]
325 IndexOutOfBounds,
326 #[error("the {}-word stack size limit was exceeded", crate::Memory::SIZE_LIMIT)]
328 Overflow,
329}
330
331#[derive(Debug, Error)]
333pub enum ParentMemoryError {
334 #[error("Attempted to access parent memory outside of a `Compute` context")]
336 NoParent,
337 #[error("A memory access error occurred: {0}")]
339 Memory(#[from] MemoryError),
340}
341
342pub type ComputeResult<T, E> = Result<T, ComputeError<E>>;
344
345#[derive(Debug, Error)]
347pub enum ComputeError<E> {
348 #[error("cannot exceed compute depth: {0}")]
350 DepthReached(usize),
351 #[error("stack operation error: {0}")]
353 Stack(#[from] StackError),
354 #[error("memory error: {0}")]
356 Memory(#[from] MemoryError),
357 #[error("execution error")]
359 Exec(Box<ExecError<E>>),
360 #[error("compute breadth is not at least 1: {0}")]
362 InvalidBreadth(Word),
363}
364
365#[derive(Debug, Error)]
367pub enum DecodeError {
368 #[error("failed to decode set: {0:?}")]
370 Set(Vec<Word>),
371 #[error("item length too large: {0}")]
373 ItemLengthTooLarge(usize),
374}
375
376#[derive(Debug, Error)]
378pub enum EncodeError {
379 #[error("item length too large: {0}")]
381 ItemLengthTooLarge(usize),
382}
383
384impl<E> From<core::convert::Infallible> for OpError<E> {
385 fn from(err: core::convert::Infallible) -> Self {
386 match err {}
387 }
388}
389
390impl<E> From<StateReadArgError> for OpError<E> {
391 fn from(err: StateReadArgError) -> Self {
392 match err {
393 StateReadArgError::Memory(e) => OpError::Memory(e),
394 StateReadArgError::Stack(e) => OpError::Stack(e),
395 }
396 }
397}
398
399impl<E> OpError<E> {
400 pub fn from_infallible(value: OpError<Infallible>) -> Self {
402 match value {
403 OpError::Access(access_error) => OpError::Access(access_error),
404 OpError::Alu(alu_error) => OpError::Alu(alu_error),
405 OpError::Crypto(crypto_error) => OpError::Crypto(crypto_error),
406 OpError::Stack(stack_error) => OpError::Stack(stack_error),
407 OpError::Repeat(repeat_error) => OpError::Repeat(repeat_error),
408 OpError::TotalControlFlow(total_control_flow_error) => {
409 OpError::TotalControlFlow(total_control_flow_error)
410 }
411 OpError::Memory(memory_error) => OpError::Memory(memory_error),
412 OpError::ParentMemory(memory_error) => OpError::ParentMemory(memory_error),
413 OpError::PcOverflow => OpError::PcOverflow,
414 OpError::Decode(decode_error) => OpError::Decode(decode_error),
415 OpError::Encode(encode_error) => OpError::Encode(encode_error),
416 OpError::StateRead(_) => unreachable!(),
417 OpError::FromBytes(from_bytes_error) => OpError::FromBytes(from_bytes_error),
418 OpError::OutOfGas(out_of_gas_error) => OpError::OutOfGas(out_of_gas_error),
419 OpError::Compute(_) => unreachable!(),
420 }
421 }
422}