essential_state_read_vm/
error.rs

1//! The types of errors that might occur throughout state read execution.
2
3pub use crate::constraint::error::{StackError, StackResult};
4#[doc(inline)]
5use crate::{
6    asm::{self, Word},
7    constraint, Gas,
8};
9use thiserror::Error;
10
11/// Shorthand for a `Result` where the error type is a `StateReadError`.
12pub type StateReadResult<T, E> = Result<T, StateReadError<E>>;
13
14/// Shorthand for a `Result` where the error type is an `OpError`.
15pub type OpResult<T, E> = Result<T, OpError<E>>;
16
17/// Shorthand for a `Result` where the error type is an `OpSyncError`.
18pub type OpSyncResult<T> = Result<T, OpSyncError>;
19
20/// Shorthand for a `Result` where the error type is an `OpAsyncError`.
21pub type OpAsyncResult<T, E> = Result<T, OpAsyncError<E>>;
22
23/// Shorthand for a `Result` where the error type is a [`StateMemoryError`].
24pub type StateMemoryResult<T> = Result<T, StateMemoryError>;
25
26/// State read execution failure.
27#[derive(Debug, Error)]
28pub enum StateReadError<E> {
29    /// The operation at the specified index failed.
30    #[error("operation at index {0} failed: {1}")]
31    Op(usize, OpError<E>),
32    /// The program counter is out of range.
33    #[error("program counter {0} out of range (note: programs must end with `Halt`)")]
34    PcOutOfRange(usize),
35}
36
37/// An individual operation failed during state read execution.
38#[derive(Debug, Error)]
39pub enum OpError<E> {
40    /// A synchronous operation failed.
41    #[error("synchronous operation failed: {0}")]
42    Sync(#[from] OpSyncError),
43    /// An asynchronous operation failed.
44    #[error("asynchronous operation failed: {0}")]
45    Async(#[from] OpAsyncError<E>),
46    /// An error occurred while parsing an operation from bytes.
47    #[error("bytecode error: {0}")]
48    FromBytes(#[from] asm::FromBytesError),
49    /// The total gas limit was exceeded.
50    #[error("{0}")]
51    OutOfGas(#[from] OutOfGasError),
52}
53
54/// The gas cost of performing an operation would exceed the gas limit.
55#[derive(Debug, Error)]
56#[error(
57    "operation cost would exceed gas limit\n  \
58    spent: {spent} gas\n  \
59    op cost: {op_gas} gas\n  \
60    limit: {limit} gas"
61)]
62pub struct OutOfGasError {
63    /// Total spent prior to the operation that would exceed the limit.
64    pub spent: Gas,
65    /// The gas required for the operation that failed.
66    pub op_gas: Gas,
67    /// The total gas limit that would be exceeded.
68    pub limit: Gas,
69}
70
71/// A synchronous operation failed.
72#[derive(Debug, Error)]
73pub enum OpSyncError {
74    /// An error occurred during a `Constraint` operation.
75    #[error("constraint operation error: {0}")]
76    Constraint(#[from] constraint::error::OpError),
77    /// An error occurred during a `TotalControlFlow` operation.
78    #[error("control flow operation error: {0}")]
79    TotalControlFlow(#[from] ControlFlowError),
80    /// An error occurred during a `StateSlots` operation.
81    #[error("state slots operation error: {0}")]
82    StateSlots(#[from] StateMemoryError),
83    /// The next program counter would overflow.
84    #[error("the next program counter would overflow")]
85    PcOverflow,
86}
87
88/// A synchronous operation failed.
89#[derive(Debug, Error)]
90pub enum OpAsyncError<E> {
91    /// An error occurred during a `StateRead` operation.
92    #[error("state read operation error: {0}")]
93    StateRead(E),
94    /// A `StateSlots` access related error occurred.
95    #[error("state slots error: {0}")]
96    Memory(#[from] StateMemoryError),
97    /// An error occurred during a `Stack` operation.
98    #[error("stack operation error: {0}")]
99    Stack(#[from] StackError),
100    /// The next program counter would overflow.
101    #[error("the next program counter would overflow")]
102    PcOverflow,
103}
104
105/// Errors occuring during `TotalControlFlow` operation.
106#[derive(Debug, Error)]
107pub enum ControlFlowError {
108    /// A `JumpIf` operation encountered an invalid condition.
109    ///
110    /// Condition values must be 0 (false) or 1 (true).
111    #[error("invalid condition value {0}, expected 0 (false) or 1 (true)")]
112    InvalidJumpIfCondition(Word),
113}
114
115/// Errors occuring during [`crate::StateMemory`] operation.
116#[derive(Debug, Error)]
117pub enum StateMemoryError {
118    /// Attempted to access a state memory slot index that was out of bounds.
119    #[error("index out of bounds")]
120    IndexOutOfBounds,
121    /// An operation would have caused state memory to overflow.
122    #[error("operation would cause state slots to overflow")]
123    Overflow,
124}
125
126impl<E> From<core::convert::Infallible> for OpError<E> {
127    fn from(err: core::convert::Infallible) -> Self {
128        match err {}
129    }
130}
131
132impl From<StackError> for OpSyncError {
133    fn from(err: StackError) -> Self {
134        OpSyncError::Constraint(err.into())
135    }
136}