cairo_vm/vm/errors/
vm_errors.rs

1// The `(*.0).0` syntax of thiserror falsely triggers this clippy warning
2#![allow(clippy::explicit_auto_deref)]
3
4use crate::stdlib::prelude::*;
5use crate::types::builtin_name::BuiltinName;
6
7use thiserror_no_std::Error;
8
9use crate::Felt252;
10use crate::{
11    types::{
12        errors::math_errors::MathError,
13        relocatable::{MaybeRelocatable, Relocatable},
14    },
15    vm::errors::{
16        exec_scope_errors::ExecScopeError, hint_errors::HintError, memory_errors::MemoryError,
17        runner_errors::RunnerError, trace_errors::TraceError,
18    },
19};
20
21pub const HINT_ERROR_STR: &str = "Got an exception while executing a hint: ";
22
23#[derive(Debug, Error)]
24pub enum VirtualMachineError {
25    #[error(transparent)]
26    RunnerError(#[from] RunnerError),
27    #[error(transparent)]
28    Memory(#[from] MemoryError),
29    #[error(transparent)]
30    Math(#[from] MathError),
31    #[error(transparent)]
32    TracerError(#[from] TraceError),
33    #[error(transparent)]
34    MainScopeError(#[from] ExecScopeError),
35    #[error(transparent)]
36    Other(anyhow::Error),
37    #[error("Instruction should be an int")]
38    InvalidInstructionEncoding,
39    #[error("Invalid op1_register value: {0}")]
40    InvalidOp1Reg(u128),
41    #[error("In immediate mode, off2 should be 1")]
42    ImmShouldBe1,
43    #[error("op0 must be known in double dereference")]
44    UnknownOp0,
45    #[error("Invalid ap_update value: {0}")]
46    InvalidApUpdate(u128),
47    #[error("Invalid pc_update value: {0}")]
48    InvalidPcUpdate(u128),
49    #[error("Res.UNCONSTRAINED cannot be used with ApUpdate.ADD")]
50    UnconstrainedResAdd,
51    #[error("Res.UNCONSTRAINED cannot be used with PcUpdate.JUMP")]
52    UnconstrainedResJump,
53    #[error("Res.UNCONSTRAINED cannot be used with PcUpdate.JUMP_REL")]
54    UnconstrainedResJumpRel,
55    #[error("Res.UNCONSTRAINED cannot be used with Opcode.ASSERT_EQ")]
56    UnconstrainedResAssertEq,
57    #[error("A relocatable value as Res cannot be used with PcUpdate.JUMP_REL")]
58    JumpRelNotInt,
59    #[error(
60        "Failed to compute Res.MUL: Could not complete computation of non pure values {} * {}", (*.0).0, (*.0).1
61    )]
62    ComputeResRelocatableMul(Box<(MaybeRelocatable, MaybeRelocatable)>),
63    #[error(
64        "Failed to compute operand, attempted to use {0} for an OpcodeExtension that is neither Stone nor QM31Operation"
65    )]
66    InvalidTypedOperationOpcodeExtension(Box<str>),
67    #[error("Couldn't compute operand {}. Unknown value for memory cell {}", (*.0).0, (*.0).1)]
68    FailedToComputeOperands(Box<(String, Relocatable)>),
69    #[error("An ASSERT_EQ instruction failed: {} != {}.", (*.0).0, (*.0).1)]
70    DiffAssertValues(Box<(MaybeRelocatable, MaybeRelocatable)>),
71    #[error("Call failed to write return-pc (inconsistent op0): {} != {}. Did you forget to increment ap?", (*.0).0, (*.0).1)]
72    CantWriteReturnPc(Box<(MaybeRelocatable, MaybeRelocatable)>),
73    #[error("Call failed to write return-fp (inconsistent dst): {} != {}. Did you forget to increment ap?", (*.0).0, (*.0).1)]
74    CantWriteReturnFp(Box<(MaybeRelocatable, MaybeRelocatable)>),
75    #[error("Couldn't get or load dst")]
76    NoDst,
77    #[error("Invalid res value: {0}")]
78    InvalidRes(u128),
79    #[error("Invalid opcode value: {0}")]
80    InvalidOpcode(u128),
81    #[error("Invalid opcode extension value: {0}")]
82    InvalidOpcodeExtension(u128),
83    #[error("This is not implemented")]
84    NotImplemented,
85    #[error("Inconsistent auto-deduction for {}, expected {}, got {:?}", (*.0).0, (*.0).1, (*.0).2)]
86    InconsistentAutoDeduction(Box<(BuiltinName, MaybeRelocatable, Option<MaybeRelocatable>)>),
87    #[error("Invalid hint encoding at pc: {0}")]
88    InvalidHintEncoding(Box<MaybeRelocatable>),
89    #[error("Expected output builtin to be present")]
90    NoOutputBuiltin,
91    #[error("Expected range_check builtin to be present")]
92    NoRangeCheckBuiltin,
93    #[error("Expected ecdsa builtin to be present")]
94    NoSignatureBuiltin,
95    #[error("Expected {0} to be present")]
96    NoModBuiltin(BuiltinName),
97    #[error("Div out of range: 0 < {} <= {}", (*.0).0, (*.0).1)]
98    OutOfValidRange(Box<(Felt252, Felt252)>),
99    #[error("Failed to compare {} and {}, cant compare a relocatable to an integer value", (*.0).0, (*.0).1)]
100    DiffTypeComparison(Box<(MaybeRelocatable, MaybeRelocatable)>),
101    #[error("Failed to compare {} and  {}, cant compare two relocatable values of different segment indexes", (*.0).0, (*.0).1)]
102    DiffIndexComp(Box<(Relocatable, Relocatable)>),
103    #[error("Couldn't convert usize to u32")]
104    NoneInMemoryRange,
105    #[error("Expected integer, found: {0:?}")]
106    ExpectedIntAtRange(Box<Option<MaybeRelocatable>>),
107    #[error("Could not convert slice to array")]
108    SliceToArrayError,
109    #[error("Failed to compile hint: {0}")]
110    CompileHintFail(Box<str>),
111    #[error("op1_addr is Op1Addr.IMM, but no immediate was given")]
112    NoImm,
113    #[error("Execution reached the end of the program. Requested remaining steps: {0}.")]
114    EndOfProgram(usize),
115    #[error("Could not reach the end of the program. Executed steps: {0}.")]
116    StepsLimit(u64),
117    #[error("Could not reach the end of the program. RunResources has no remaining steps.")]
118    UnfinishedExecution,
119    #[error("Current run is not finished")]
120    RunNotFinished,
121    #[error("Invalid argument count, expected {} but got {}", (*.0).0, (*.0).1)]
122    InvalidArgCount(Box<(usize, usize)>),
123    #[error("Couldn't parse prime: {0}")]
124    CouldntParsePrime(Box<str>),
125    #[error("{HINT_ERROR_STR}{}", (*.0).1)]
126    Hint(Box<(usize, HintError)>),
127    #[error("Unexpected Failure")]
128    Unexpected,
129    #[error("Out of bounds access to builtin segment")]
130    OutOfBoundsBuiltinSegmentAccess,
131    #[error("Out of bounds access to program segment")]
132    OutOfBoundsProgramSegmentAccess,
133    #[error("Security Error: Invalid Memory Value: temporary address not relocated: {0}")]
134    InvalidMemoryValueTemporaryAddress(Box<Relocatable>),
135    #[error("accessed_addresses is None.")]
136    MissingAccessedAddresses,
137    #[error("Failed to write the output builtin content")]
138    FailedToWriteOutput,
139    #[error("Failed to find index {0} in the vm's relocation table")]
140    RelocationNotFound(usize),
141    #[error("{} batch size is not {}", (*.0).0, (*.0).1)]
142    ModBuiltinBatchSize(Box<(BuiltinName, usize)>),
143    #[error("Blake2s opcode invalid operand: op{0} does not point to {1} u32 numbers.")]
144    Blake2sInvalidOperand(u8, u8),
145    #[error("Blake2s opcode invalid flags {0}")]
146    InvalidBlake2sFlags(u128),
147    #[error("QM31 add mul opcode invalid flags {0}")]
148    InvalidQM31AddMulFlags(u128),
149}
150
151#[cfg(test)]
152mod tests {
153    use super::*;
154
155    #[test]
156    // Test to catch possible enum size regressions
157    fn test_vm_error_size() {
158        let size = crate::stdlib::mem::size_of::<VirtualMachineError>();
159        assert!(size <= 32, "{size}")
160    }
161}