Skip to main content

cairo_vm/vm/errors/
memory_errors.rs

1// The `(*.0).0` syntax of thiserror falsely triggers this clippy warning
2#![allow(clippy::explicit_auto_deref)]
3
4use crate::types::builtin_name::BuiltinName;
5
6use thiserror::Error;
7
8use crate::Felt252;
9
10use crate::types::{
11    errors::math_errors::MathError,
12    relocatable::{MaybeRelocatable, Relocatable},
13};
14
15#[derive(Debug, PartialEq, Error)]
16pub enum MemoryError {
17    #[error("Cell {0} has already been accessed; it cannot be removed.")]
18    UnsetAccessedCell(Relocatable),
19    #[error("Cell {0} is not allocated; it cannot be removed.")]
20    UnsetUnallocatedCell(Relocatable),
21    #[error(transparent)]
22    Math(#[from] MathError),
23    #[error(transparent)]
24    InsufficientAllocatedCells(#[from] InsufficientAllocatedCellsError),
25    #[error("Can't insert into segment #{}; memory only has {} segment", (*.0).0, (*.0).1)]
26    UnallocatedSegment(Box<(usize, usize)>),
27    #[error("Memory addresses must be relocatable")]
28    AddressNotRelocatable,
29    #[error("Range-check validation failed, number {} is out of valid range [0, {}]", (*.0).0, (*.0).1)]
30    RangeCheckNumOutOfBounds(Box<(Felt252, Felt252)>),
31    #[error("Range-check validation failed, encountered non-int value at address {0}")]
32    RangeCheckFoundNonInt(Box<Relocatable>),
33    #[error("Inconsistent memory assignment at address {:?}. {:?} != {:?}", (*.0).0, (*.0).1, (*.0).2)]
34    InconsistentMemory(Box<(Relocatable, MaybeRelocatable, MaybeRelocatable)>),
35    #[error("Inconsistent Relocation")]
36    Relocation,
37    #[error("Could not cast arguments")]
38    WriteArg,
39    #[error("Memory addresses mustn't be in a TemporarySegment, segment: {0}")]
40    AddressInTemporarySegment(isize),
41    #[error("Memory addresses must be in a TemporarySegment, segment: {0}")]
42    AddressNotInTemporarySegment(isize),
43    #[error("Temporary segment found while relocating (flattening), segment: {0}")]
44    TemporarySegmentInRelocation(isize),
45    #[error("The TemporarySegment: {0} doesn't have a relocation address")]
46    NonZeroOffset(usize),
47    #[error("Attempt to overwrite a relocation rule, segment: {0}")]
48    DuplicatedRelocation(isize),
49    #[error("Segment effective sizes haven't been calculated.")]
50    MissingSegmentUsedSizes,
51    #[error("Found a memory gap when calling get_continuous_range with base:{} and size: {}", (*.0).0, (*.0).1)]
52    GetRangeMemoryGap(Box<(Relocatable, usize)>),
53    #[error("Error calculating builtin memory units")]
54    ErrorCalculatingMemoryUnits,
55    #[error("Missing memory cells for {0}")]
56    MissingMemoryCells(Box<BuiltinName>),
57    #[error("Missing memory cells for {}: {:?}", (*.0).0, (*.0).1)]
58    MissingMemoryCellsWithOffsets(Box<(BuiltinName, Vec<usize>)>),
59    #[error("ErrorInitializing Verifying Key from public key: {0:?}")]
60    InitializingVerifyingKey(Box<Vec<u8>>),
61    #[error(
62        "Signature {}, is invalid, with respect to the public key {}, 
63    and the message hash {}.", (*.0).0, (*.0).1, (*.0).2
64    )]
65    InvalidSignature(Box<(String, Felt252, Felt252)>),
66    #[error(
67        "Signature hint is missing for ECDSA builtin at address {0}.
68    Add it using 'ecdsa_builtin.add_signature'."
69    )]
70    SignatureNotFound(Box<Relocatable>),
71    #[error("Could not create pubkey from: {0:?}")]
72    ErrorParsingPubKey(Box<str>),
73    #[error("Could not retrieve message from: {0:?}")]
74    ErrorRetrievingMessage(Box<str>),
75    #[error("Error verifying given signature")]
76    ErrorVerifyingSignature,
77    #[error("ECDSA builtin: Expected public key at address {0} to be an integer")]
78    PubKeyNonInt(Box<Relocatable>),
79    #[error("ECDSA builtin: Expected message hash at address {0} to be an integer")]
80    MsgNonInt(Box<Relocatable>),
81    #[error("Failed to fetch {} return values, ap is only {}", (*.0).0, (*.0).1)]
82    FailedToGetReturnValues(Box<(usize, Relocatable)>),
83    #[error("Segment {} has {} amount of accessed addresses but its size is only {}.", (*.0).0, (*.0).1, (*.0).2)]
84    SegmentHasMoreAccessedAddressesThanSize(Box<(usize, usize, usize)>),
85    #[error("gen_arg: found argument of invalid type.")]
86    GenArgInvalidType,
87    // Memory.get() errors
88    #[error("Expected integer at address {0}")]
89    ExpectedInteger(Box<Relocatable>),
90    #[error("Expected relocatable at address {0}")]
91    ExpectedRelocatable(Box<Relocatable>),
92    #[error("Unknown memory cell at address {0}")]
93    UnknownMemoryCell(Box<Relocatable>),
94    // SegmentArenaBuiltin
95    #[error("segment_arena_builtin: assert used >= INITIAL_SEGMENT_SIZE")]
96    InvalidUsedSizeSegmentArena,
97    #[error("Vector capacity exceeded")]
98    VecCapacityExceeded,
99    #[error("Memory wasn't relocated")]
100    UnrelocatedMemory,
101    #[error("Malformed public memory")]
102    MalformedPublicMemory,
103    #[error("Temporary segment {0} has no relocation mapping (unmapped temporary segment).")]
104    UnmappedTemporarySegment(isize),
105}
106
107#[derive(Debug, PartialEq, Eq, Error)]
108pub enum InsufficientAllocatedCellsError {
109    #[error("Number of steps must be at least {} for the {}.", (*.0).0, (*.0).1)]
110    MinStepNotReached(Box<(usize, BuiltinName)>),
111    #[error("The {} used {} cells but the capacity is {}.", (*.0).0, (*.0).1, (*.0).2)]
112    BuiltinCells(Box<(BuiltinName, usize, usize)>),
113    #[error("There are only {} cells to fill the range checks holes, but potentially {} are required.", (*.0).0, (*.0).1)]
114    RangeCheckUnits(Box<(usize, usize)>),
115    #[error("There are only {} cells to fill the diluted check holes, but potentially {} are required.", (*.0).0, (*.0).1)]
116    DilutedCells(Box<(usize, usize)>),
117    #[error("There are only {} cells to fill the memory address holes, but {} are required.", (*.0).0, (*.0).1)]
118    MemoryAddresses(Box<(u32, usize)>),
119}
120
121#[cfg(test)]
122mod tests {
123    use super::*;
124
125    #[test]
126    // Test to catch possible enum size regressions
127    fn test_memory_error_size() {
128        let size = std::mem::size_of::<MemoryError>();
129        assert!(size <= 24, "{size}")
130    }
131
132    #[test]
133    // Test to catch possible enum size regressions
134    fn test_insufficient_allocated_cells_error_size() {
135        let size = std::mem::size_of::<InsufficientAllocatedCellsError>();
136        assert!(size <= 16, "{size}")
137    }
138}