1#[doc(inline)]
4use crate::{
5 asm::{self, Word},
6 Gas,
7};
8use thiserror::Error;
9
10pub type ExecResult<T, E> = Result<T, ExecError<E>>;
12
13pub type EvalSyncResult<T> = Result<T, EvalSyncError>;
15
16pub type ExecSyncResult<T> = Result<T, ExecSyncError>;
18
19pub type OpResult<T, E> = Result<T, OpError<E>>;
21
22pub type OpSyncResult<T> = Result<T, OpSyncError>;
24
25pub type OpAsyncResult<T, E> = Result<T, OpAsyncError<E>>;
27
28#[derive(Debug, Error)]
30#[error("operation at index {0} failed: {1}")]
31pub struct ExecError<E>(pub usize, pub OpError<E>);
32
33#[derive(Debug, Error)]
35pub enum EvalSyncError {
36 #[error("{0}")]
38 Exec(#[from] ExecSyncError),
39 #[error(
42 "invalid constraint evaluation result\n \
43 expected: [0] (false) or [1] (true)\n \
44 found: {0:?}"
45 )]
46 InvalidEvaluation(crate::Stack),
47}
48
49#[derive(Debug, Error)]
51#[error("operation at index {0} failed: {1}")]
52pub struct ExecSyncError(pub usize, pub OpSyncError);
53
54#[derive(Debug, Error)]
56pub enum OpError<E> {
57 #[error("synchronous operation failed: {0}")]
59 Sync(#[from] OpSyncError),
60 #[error("asynchronous operation failed: {0}")]
62 Async(#[from] OpAsyncError<E>),
63 #[error("bytecode error: {0}")]
65 FromBytes(#[from] asm::FromBytesError),
66 #[error("{0}")]
68 OutOfGas(#[from] OutOfGasError),
69}
70
71#[derive(Debug, Error)]
73#[error(
74 "operation cost would exceed gas limit\n \
75 spent: {spent} gas\n \
76 op cost: {op_gas} gas\n \
77 limit: {limit} gas"
78)]
79pub struct OutOfGasError {
80 pub spent: Gas,
82 pub op_gas: Gas,
84 pub limit: Gas,
86}
87
88#[derive(Debug, Error)]
90pub enum OpAsyncError<E> {
91 #[error("state read operation error: {0}")]
93 StateRead(E),
94 #[error("memory error: {0}")]
96 Memory(#[from] MemoryError),
97 #[error("stack operation error: {0}")]
99 Stack(#[from] StackError),
100 #[error("the next program counter would overflow")]
102 PcOverflow,
103}
104
105#[derive(Debug, Error)]
107pub enum OpSyncError {
108 #[error("access operation error: {0}")]
110 Access(#[from] AccessError),
111 #[error("ALU operation error: {0}")]
113 Alu(#[from] AluError),
114 #[error("crypto operation error: {0}")]
116 Crypto(#[from] CryptoError),
117 #[error("stack operation error: {0}")]
119 Stack(#[from] StackError),
120 #[error("repeat operation error: {0}")]
122 Repeat(#[from] RepeatError),
123 #[error("total control flow operation error: {0}")]
125 TotalControlFlow(#[from] TotalControlFlowError),
126 #[error("temporary operation error: {0}")]
128 Memory(#[from] MemoryError),
129 #[error("bytecode error: {0}")]
131 FromBytes(#[from] asm::FromBytesError),
132 #[error("PC counter overflowed")]
134 PcOverflow,
135 #[error("decoding error: {0}")]
137 Decode(#[from] DecodeError),
138 #[error("encoding error: {0}")]
140 Encode(#[from] EncodeError),
141}
142
143#[derive(Debug, Error)]
145pub enum ControlFlowError {
146 #[error("invalid condition value {0}, expected 0 (false) or 1 (true)")]
150 InvalidJumpIfCondition(Word),
151}
152
153#[derive(Debug, Error)]
155pub enum AccessError {
156 #[error("predicate data slot out of bounds: {0}")]
158 PredicateDataSlotIxOutOfBounds(Word),
159 #[error("the length of a predicate data value is too large: {0}")]
161 PredicateDataValueTooLarge(usize),
162 #[error("predicate data value_ix out of bounds: {0}..{1}")]
164 PredicateDataValueRangeOutOfBounds(Word, Word),
165 #[error("state slot_ix out of bounds: {0}")]
167 StateSlotIxOutOfBounds(Word),
168 #[error("state value_ix out of bounds: {0}..{1}")]
170 StateValueRangeOutOfBounds(Word, Word),
171 #[error("invalid state slot delta: expected `0` or `1`, found {0}")]
173 InvalidStateSlotDelta(Word),
174 #[error("the total length of the set of state mutations was too large: {0}")]
176 StateMutationsLengthTooLarge(usize),
177 #[error("the state slot value was too large: {0}")]
179 StateValueTooLarge(usize),
180 #[error("key length out of bounds: {0}")]
182 KeyLengthOutOfBounds(Word),
183 #[error("invalid access range")]
185 InvalidAccessRange,
186 #[error("the length of the slots was too large: {0}")]
188 SlotsLengthTooLarge(usize),
189 #[error("invalid `which_slots` argument: {0}")]
191 InvalidSlotType(Word),
192 #[error("missing `Access` argument: {0}")]
194 MissingArg(#[from] MissingAccessArgError),
195}
196
197#[derive(Debug, Error)]
199pub enum MissingAccessArgError {
200 #[error("missing `delta` argument for `State` operation")]
202 StateDelta,
203 #[error("missing `len` argument for `State` operation")]
205 StateLen,
206 #[error("missing `value_ix` argument for `State` operation")]
208 StateValueIx,
209 #[error("missing `slot_ix` argument for `State` operation")]
211 StateSlotIx,
212 #[error("missing `len` argument for `PredicateData` operation")]
214 PredDataLen,
215 #[error("missing `value_ix` argument for `PredicateData` operation")]
217 PredDataValueIx,
218 #[error("missing `slot_ix` argument for `PredicateData` operation")]
220 PredDataSlotIx,
221}
222
223#[derive(Debug, Error)]
225pub enum AluError {
226 #[error("word overflow")]
228 Overflow,
229 #[error("word underflow")]
231 Underflow,
232 #[error("attempted to divide by zero")]
234 DivideByZero,
235}
236
237#[derive(Debug, Error)]
239pub enum CryptoError {
240 #[error("failed to verify ed25519 signature: {0}")]
242 Ed25519(#[from] ed25519_dalek::ed25519::Error),
243 #[error("failed to recover secp256k1 public key: {0}")]
245 Secp256k1(#[from] secp256k1::Error),
246 #[error("failed to parse secp256k1 recovery id")]
248 Secp256k1RecoveryId,
249}
250
251pub type StackResult<T> = Result<T, StackError>;
253
254#[derive(Debug, Error)]
256pub enum StackError {
257 #[error("attempted to pop an empty stack")]
259 Empty,
260 #[error("indexed stack out of bounds")]
262 IndexOutOfBounds,
263 #[error("the {}-word stack size limit was exceeded", crate::Stack::SIZE_LIMIT)]
265 Overflow,
266 #[error(
268 "invalid condition\n \
269 expected: [0] (false) or [1] (true)\n \
270 found: {0}"
271 )]
272 InvalidCondition(Word),
273 #[error(transparent)]
275 LenWords(#[from] LenWordsError),
276}
277
278#[derive(Debug, Error)]
280pub enum LenWordsError {
281 #[error("missing length argument for `len words` operation")]
283 MissingLength,
284 #[error("invalid length argument for `len words` operation: {0}")]
286 InvalidLength(Word),
287 #[error("length argument for `len words` operation out of bounds: {0}")]
289 OutOfBounds(Word),
290 #[error("additional length too large for `len words` operation: {0} + {1}")]
292 AdditionalOutOfBounds(usize, usize),
293}
294
295pub type RepeatResult<T> = Result<T, RepeatError>;
297
298#[derive(Debug, Error)]
300pub enum RepeatError {
301 #[error("attempted to repeat to empty stack")]
303 Empty,
304 #[error("attempted to access repeat counter with empty stack")]
306 NoCounter,
307 #[error("The count direction must be 0 or 1")]
309 InvalidCountDirection,
310 #[error("the {}-word stack size limit was exceeded", crate::Stack::SIZE_LIMIT)]
312 Overflow,
313}
314
315pub type TotalControlFlowResult<T> = Result<T, TotalControlFlowError>;
317
318#[derive(Debug, Error)]
320pub enum TotalControlFlowError {
321 #[error("jump forward if requires a boolean condition")]
323 InvalidJumpForwardIfCondition,
324 #[error("jump forward if requires to jump at least one instruction")]
326 JumpedToSelf,
327 #[error("halt if requires a boolean condition")]
329 InvalidHaltIfCondition,
330 #[error("panic if requires a boolean condition")]
332 InvalidPanicIfCondition,
333 #[error("program panicked with `PanicIf` operation. The stack at the time of panic: {0:?}")]
335 Panic(Vec<Word>),
336}
337
338pub type MemoryResult<T> = Result<T, MemoryError>;
340
341#[derive(Debug, Error)]
343pub enum MemoryError {
344 #[error("attempted to pop an empty memory")]
346 Empty,
347 #[error("indexed memory out of bounds")]
349 IndexOutOfBounds,
350 #[error("the {}-word stack size limit was exceeded", crate::Memory::SIZE_LIMIT)]
352 Overflow,
353}
354
355#[derive(Debug, Error)]
357pub enum DecodeError {
358 #[error("failed to decode set: {0:?}")]
360 Set(Vec<Word>),
361 #[error("item length too large: {0}")]
363 ItemLengthTooLarge(usize),
364}
365
366#[derive(Debug, Error)]
368pub enum EncodeError {
369 #[error("item length too large: {0}")]
371 ItemLengthTooLarge(usize),
372}
373
374impl From<core::convert::Infallible> for OpSyncError {
375 fn from(err: core::convert::Infallible) -> Self {
376 match err {}
377 }
378}
379
380impl<E> From<core::convert::Infallible> for OpError<E> {
381 fn from(err: core::convert::Infallible) -> Self {
382 match err {}
383 }
384}