use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::Opcode;
#[derive(Clone, Error, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum ExecutionError {
#[error("invalid memory access for opcode {0} and address {1}")]
InvalidMemoryAccess(Opcode, u64),
#[error("invalid memory access for untrusted program at address {0}, not aligned to 4 bytes")]
InvalidMemoryAccessUntrustedProgram(u64),
#[error("unimplemented syscall {0}")]
UnsupportedSyscall(u32),
#[error("breakpoint encountered")]
Breakpoint(),
#[error("exceeded cycle limit of {0}")]
ExceededCycleLimit(u64),
#[error("syscall called in unconstrained mode")]
InvalidSyscallUsage(u64),
#[error("got unimplemented as opcode")]
Unimplemented(),
#[error("program ended in unconstrained mode")]
EndInUnconstrained(),
#[error("unconstrained cycle limit exceeded")]
UnconstrainedCycleLimitExceeded(u64),
#[error("Unexpected exit code: {0}")]
UnexpectedExitCode(u32),
#[error("Instruction not found, page protect/ untrusted program set to off")]
InstructionNotFound(),
#[error("Running executor in non-sharding state, but got a shard boundary or trace end")]
InvalidShardingState(),
#[error("SP1 program consumes too much memory")]
TooMuchMemory(),
#[error("{0}")]
Other(String),
}