pub use crate::constraint::error::{StackError, StackResult};
#[doc(inline)]
use crate::{
asm::{self, Word},
constraint, Gas,
};
use thiserror::Error;
pub type StateReadResult<T, E> = Result<T, StateReadError<E>>;
pub type OpResult<T, E> = Result<T, OpError<E>>;
pub type OpSyncResult<T> = Result<T, OpSyncError>;
pub type OpAsyncResult<T, E> = Result<T, OpAsyncError<E>>;
pub type StateMemoryResult<T> = Result<T, StateMemoryError>;
#[derive(Debug, Error)]
pub enum StateReadError<E> {
#[error("operation at index {0} failed: {1}")]
Op(usize, OpError<E>),
#[error("program counter {0} out of range (note: programs must end with `Halt`)")]
PcOutOfRange(usize),
}
#[derive(Debug, Error)]
pub enum OpError<E> {
#[error("synchronous operation failed: {0}")]
Sync(#[from] OpSyncError),
#[error("asynchronous operation failed: {0}")]
Async(#[from] OpAsyncError<E>),
#[error("bytecode error: {0}")]
FromBytes(#[from] asm::FromBytesError),
#[error("{0}")]
OutOfGas(#[from] OutOfGasError),
}
#[derive(Debug, Error)]
#[error(
"operation cost would exceed gas limit\n \
spent: {spent} gas\n \
op cost: {op_gas} gas\n \
limit: {limit} gas"
)]
pub struct OutOfGasError {
pub spent: Gas,
pub op_gas: Gas,
pub limit: Gas,
}
#[derive(Debug, Error)]
pub enum OpSyncError {
#[error("constraint operation error: {0}")]
Constraint(#[from] constraint::error::OpError),
#[error("control flow operation error: {0}")]
TotalControlFlow(#[from] ControlFlowError),
#[error("state slots operation error: {0}")]
StateSlots(#[from] StateMemoryError),
#[error("the next program counter would overflow")]
PcOverflow,
}
#[derive(Debug, Error)]
pub enum OpAsyncError<E> {
#[error("state read operation error: {0}")]
StateRead(E),
#[error("state slots error: {0}")]
Memory(#[from] StateMemoryError),
#[error("stack operation error: {0}")]
Stack(#[from] StackError),
#[error("the next program counter would overflow")]
PcOverflow,
}
#[derive(Debug, Error)]
pub enum ControlFlowError {
#[error("invalid condition value {0}, expected 0 (false) or 1 (true)")]
InvalidJumpIfCondition(Word),
}
#[derive(Debug, Error)]
pub enum StateMemoryError {
#[error("index out of bounds")]
IndexOutOfBounds,
#[error("operation would cause state slots to overflow")]
Overflow,
}
impl<E> From<core::convert::Infallible> for OpError<E> {
fn from(err: core::convert::Infallible) -> Self {
match err {}
}
}
impl From<StackError> for OpSyncError {
fn from(err: StackError) -> Self {
OpSyncError::Constraint(err.into())
}
}