1use {sbpf_common::errors::ExecutionError, thiserror::Error};
2
3#[derive(Error, Debug, Clone)]
5pub enum SbpfVmError {
6 #[error("Division by zero")]
7 DivisionByZero,
8
9 #[error("Invalid memory access at address {0:#x}")]
10 InvalidMemoryAccess(u64),
11
12 #[error("Memory region out of bounds: address {0:#x}, length {1}")]
13 MemoryOutOfBounds(u64, usize),
14
15 #[error("Invalid operand")]
16 InvalidOperand,
17
18 #[error("Program counter out of bounds: {0}")]
19 PcOutOfBounds(usize),
20
21 #[error("Invalid instruction format")]
22 InvalidInstruction,
23
24 #[error("Call depth exceeded (max {0})")]
25 CallDepthExceeded(usize),
26
27 #[error("Execution limit reached ({0} steps)")]
28 ExecutionLimitReached(u64),
29
30 #[error("Syscall error: {0}")]
31 SyscallError(String),
32
33 #[error("Compute budget exceeded: limit {limit}, consumed {consumed}")]
34 ComputeBudgetExceeded { limit: u64, consumed: u64 },
35
36 #[error("Program aborted")]
37 Abort,
38
39 #[error("Overlapping memory regions")]
40 OverlappingMemoryRegions,
41
42 #[error("Too many slices for hashing")]
43 TooManySlices,
44
45 #[error("Max seed length exceeded for PDA")]
46 MaxSeedLengthExceeded,
47
48 #[error("Invalid slice conversion")]
49 InvalidSliceConversion,
50}
51
52pub type SbpfVmResult<T> = Result<T, SbpfVmError>;
53
54impl From<ExecutionError> for SbpfVmError {
55 fn from(err: ExecutionError) -> Self {
56 match err {
57 ExecutionError::DivisionByZero => SbpfVmError::DivisionByZero,
58 ExecutionError::InvalidOperand => SbpfVmError::InvalidOperand,
59 ExecutionError::InvalidInstruction => SbpfVmError::InvalidInstruction,
60 ExecutionError::CallDepthExceeded(n) => SbpfVmError::CallDepthExceeded(n),
61 ExecutionError::InvalidMemoryAccess(addr) => SbpfVmError::InvalidMemoryAccess(addr),
62 ExecutionError::SyscallError(s) => SbpfVmError::SyscallError(s),
63 }
64 }
65}