Skip to main content

amaru_uplc/machine/
error.rs

1use std::array::TryFromSliceError;
2
3use crate::{
4    binder::Eval,
5    bls::BlsError,
6    builtin::DefaultFunction,
7    constant::{Constant, Integer},
8    data::PlutusData,
9    term::Term,
10    typ::Type,
11};
12
13use super::{value::Value, ExBudget};
14
15#[derive(thiserror::Error, Debug)]
16pub enum MachineError<'a, V>
17where
18    V: Eval<'a>,
19{
20    #[error("Explicit error term")]
21    ExplicitErrorTerm,
22    #[error("Non-function application")]
23    NonFunctionApplication(&'a Value<'a, V>, &'a Value<'a, V>),
24    #[error("Non-constant value")]
25    NotAConstant(&'a Value<'a, V>),
26    #[error("Open term evaluated")]
27    OpenTermEvaluated(&'a Term<'a, V>),
28    #[error("Out of budget")]
29    OutOfExError(ExBudget),
30    #[error("Unexpected builtin term argument")]
31    UnexpectedBuiltinTermArgument(&'a Term<'a, V>),
32    #[error("Non-polymorphic instantiation")]
33    NonPolymorphicInstantiation(&'a Value<'a, V>),
34    #[error("Builtin term argument expected")]
35    BuiltinTermArgumentExpected(&'a Term<'a, V>),
36    #[error("Non-constructor scrutinized")]
37    NonConstrScrutinized(&'a Value<'a, V>),
38    #[error("Non-integer index")]
39    MissingCaseBranch(&'a [&'a Term<'a, V>], &'a Value<'a, V>),
40    #[error(transparent)]
41    Runtime(RuntimeError<'a>),
42    #[error("Max constr tag exceeded")]
43    MaxConstrTagExceeded(&'a Value<'a, V>),
44    #[error("No cost found for builtin function: {0:?}")]
45    NoCostForBuiltin(DefaultFunction),
46}
47
48#[derive(thiserror::Error, Debug)]
49pub enum RuntimeError<'a> {
50    #[error("Byte string out of bounds")]
51    ByteStringOutOfBounds(&'a [u8], &'a Integer),
52    #[error("Type mismatch")]
53    TypeMismatch(Type<'a>, &'a Constant<'a>),
54    #[error("Expected pair")]
55    ExpectedPair(&'a Constant<'a>),
56    #[error("Expected list")]
57    ExpectedList(&'a Constant<'a>),
58    #[error("Expected array")]
59    ExpectedArray(&'a Constant<'a>),
60    #[error("Not data")]
61    NotData(&'a Constant<'a>),
62    #[error("Malformed data")]
63    MalFormedData(&'a PlutusData<'a>),
64    #[error("Empty list")]
65    EmptyList(&'a [&'a Constant<'a>]),
66    #[error("Unexpected Ed25519 public key length")]
67    UnexpectedEd25519PublicKeyLength(TryFromSliceError),
68    #[error("Unexpected Ed25519 signature length")]
69    UnexpectedEd25519SignatureLength(TryFromSliceError),
70    #[error("Division by zero")]
71    DivisionByZero(&'a Integer, &'a Integer),
72    #[error("MkCons type mismatch")]
73    MkConsTypeMismatch(&'a Constant<'a>),
74    #[error("Byte string cons not a byte")]
75    ByteStringConsNotAByte(&'a Integer),
76    #[error(transparent)]
77    Secp256k1(#[from] secp256k1::Error),
78    #[error(transparent)]
79    DecodeUtf8(#[from] std::str::Utf8Error),
80    #[error(transparent)]
81    Bls(#[from] BlsError),
82    #[error("Bls Error: Hash to curve dst too big")]
83    HashToCurveDstTooBig,
84    #[error(
85        "bytes size beyond limit when converting from integer\n{:>13} {0}\n{:>13} {1}",
86        "Size",
87        "Maximum"
88    )]
89    IntegerToByteStringSizeTooBig(&'a Integer, i64),
90    #[error(
91        "bytes size below limit when converting from integer\n{:>13} {0}\n{:>13} {1}",
92        "Size",
93        "Minimum"
94    )]
95    IntegerToByteStringSizeTooSmall(&'a Integer, usize),
96    #[error("integerToByteString encountered negative input\n{:>13} {0}", "Input")]
97    IntegerToByteStringNegativeInput(&'a Integer),
98    #[error("integerToByteString encountered negative size\n{:>13} {0}", "Size")]
99    IntegerToByteStringNegativeSize(&'a Integer),
100    #[error("Empty byte array")]
101    EmptyByteArray,
102    #[error(
103        "readBit: index out of bounds\n{:>13} {0}\n{:>13} {1}",
104        "Index",
105        "Size"
106    )]
107    ReadBitOutOfBounds(&'a Integer, usize),
108    #[error(
109        "writeBits: an index is out of bounds\n{:>13} {0}\n{:>13} {1}",
110        "Index",
111        "Size"
112    )]
113    WriteBitsOutOfBounds(&'a Integer, usize),
114    #[error("{0} is not within the bounds of a Byte")]
115    OutsideByteBounds(&'a Integer),
116    #[error("{0} is not within the bounds of usize")]
117    OutsideUsizeBounds(&'a Integer),
118    #[error(
119        "bytes size beyond limit when replicating byte\n{:>13} {0}\n{:>13} {1}",
120        "Size",
121        "Maximum"
122    )]
123    ReplicateByteSizeTooBig(&'a Integer, i64),
124    #[error(
125        "bytes size below limit when replicating byte\n{:>13} {0}\n{:>13} {1}",
126        "Size",
127        "Minimum"
128    )]
129    ReplicateByteSizeTooSmall(&'a Integer, usize),
130    #[error("replicateByte encountered negative input\n{:>13} {0}", "Input")]
131    ReplicateByteNegativeInput(&'a Integer),
132    #[error("replicateByte encountered negative size\n{:>13} {0}", "Size")]
133    ReplicateByteNegativeSize(&'a Integer),
134    #[error(
135        "indexArray: index out of bounds\n{:>13} {0}\n{:>13} {1}",
136        "Index",
137        "Size"
138    )]
139    IndexArrayOutOfBounds(&'a Integer, usize),
140    #[error("Serialization error")]
141    SerializationError(&'a PlutusData<'a>),
142}
143
144impl<'a, V> MachineError<'a, V>
145where
146    V: Eval<'a>,
147{
148    pub fn runtime(runtime_error: RuntimeError<'a>) -> Self {
149        MachineError::Runtime(runtime_error)
150    }
151
152    pub fn type_mismatch(expected: Type<'a>, constant: &'a Constant<'a>) -> Self {
153        MachineError::runtime(RuntimeError::TypeMismatch(expected, constant))
154    }
155
156    pub fn mk_cons_type_mismatch(constant: &'a Constant<'a>) -> Self {
157        MachineError::runtime(RuntimeError::MkConsTypeMismatch(constant))
158    }
159
160    pub fn expected_pair(constant: &'a Constant<'a>) -> Self {
161        MachineError::runtime(RuntimeError::ExpectedPair(constant))
162    }
163
164    pub fn expected_list(constant: &'a Constant<'a>) -> Self {
165        MachineError::runtime(RuntimeError::ExpectedList(constant))
166    }
167
168    pub fn expected_array(constant: &'a Constant<'a>) -> Self {
169        MachineError::runtime(RuntimeError::ExpectedArray(constant))
170    }
171
172    pub fn empty_list(constant: &'a [&'a Constant<'a>]) -> Self {
173        MachineError::runtime(RuntimeError::EmptyList(constant))
174    }
175
176    pub fn byte_string_out_of_bounds(byte_string: &'a [u8], index: &'a Integer) -> Self {
177        MachineError::runtime(RuntimeError::ByteStringOutOfBounds(byte_string, index))
178    }
179
180    pub fn not_data(constant: &'a Constant<'a>) -> Self {
181        MachineError::runtime(RuntimeError::NotData(constant))
182    }
183
184    pub fn malformed_data(plutus_data: &'a PlutusData<'a>) -> Self {
185        MachineError::runtime(RuntimeError::MalFormedData(plutus_data))
186    }
187
188    pub fn unexpected_ed25519_public_key_length(length: TryFromSliceError) -> Self {
189        MachineError::runtime(RuntimeError::UnexpectedEd25519PublicKeyLength(length))
190    }
191
192    pub fn unexpected_ed25519_signature_length(length: TryFromSliceError) -> Self {
193        MachineError::runtime(RuntimeError::UnexpectedEd25519SignatureLength(length))
194    }
195
196    pub fn division_by_zero(numerator: &'a Integer, denominator: &'a Integer) -> Self {
197        MachineError::runtime(RuntimeError::DivisionByZero(numerator, denominator))
198    }
199
200    pub fn byte_string_cons_not_a_byte(byte: &'a Integer) -> Self {
201        MachineError::runtime(RuntimeError::ByteStringConsNotAByte(byte))
202    }
203
204    pub fn secp256k1(error: secp256k1::Error) -> Self {
205        MachineError::runtime(RuntimeError::Secp256k1(error))
206    }
207
208    pub fn decode_utf8(error: std::str::Utf8Error) -> Self {
209        MachineError::runtime(RuntimeError::DecodeUtf8(error))
210    }
211
212    pub fn bls(error: BlsError) -> Self {
213        MachineError::runtime(RuntimeError::Bls(error))
214    }
215
216    pub fn hash_to_curve_dst_too_big() -> Self {
217        MachineError::runtime(RuntimeError::HashToCurveDstTooBig)
218    }
219
220    pub fn integer_to_byte_string_size_too_big(integer: &'a Integer, maximum: i64) -> Self {
221        MachineError::runtime(RuntimeError::IntegerToByteStringSizeTooBig(
222            integer, maximum,
223        ))
224    }
225
226    pub fn integer_to_byte_string_size_too_small(integer: &'a Integer, minimum: usize) -> Self {
227        MachineError::runtime(RuntimeError::IntegerToByteStringSizeTooSmall(
228            integer, minimum,
229        ))
230    }
231
232    pub fn integer_to_byte_string_negative_input(integer: &'a Integer) -> Self {
233        MachineError::runtime(RuntimeError::IntegerToByteStringNegativeInput(integer))
234    }
235
236    pub fn integer_to_byte_string_negative_size(integer: &'a Integer) -> Self {
237        MachineError::runtime(RuntimeError::IntegerToByteStringNegativeSize(integer))
238    }
239
240    pub fn empty_byte_array() -> Self {
241        MachineError::runtime(RuntimeError::EmptyByteArray)
242    }
243
244    pub fn read_bit_out_of_bounds(index: &'a Integer, size: usize) -> Self {
245        MachineError::runtime(RuntimeError::ReadBitOutOfBounds(index, size))
246    }
247
248    pub fn write_bits_out_of_bounds(index: &'a Integer, size: usize) -> Self {
249        MachineError::runtime(RuntimeError::WriteBitsOutOfBounds(index, size))
250    }
251
252    pub fn outside_byte_bounds(integer: &'a Integer) -> Self {
253        MachineError::runtime(RuntimeError::OutsideByteBounds(integer))
254    }
255
256    pub fn outside_usize_bounds(integer: &'a Integer) -> Self {
257        MachineError::runtime(RuntimeError::OutsideUsizeBounds(integer))
258    }
259
260    pub fn replicate_byte_negative_size(integer: &'a Integer) -> Self {
261        MachineError::runtime(RuntimeError::ReplicateByteNegativeSize(integer))
262    }
263
264    pub fn replicate_byte_size_too_big(integer: &'a Integer, maximum: i64) -> Self {
265        MachineError::runtime(RuntimeError::ReplicateByteSizeTooBig(integer, maximum))
266    }
267
268    pub fn replicate_byte_negative_input(integer: &'a Integer) -> Self {
269        MachineError::runtime(RuntimeError::ReplicateByteNegativeInput(integer))
270    }
271
272    pub fn index_array_out_of_bounds(index: &'a Integer, size: usize) -> Self {
273        MachineError::runtime(RuntimeError::IndexArrayOutOfBounds(index, size))
274    }
275
276    pub fn serialization_error(data: &'a PlutusData<'a>) -> Self {
277        MachineError::runtime(RuntimeError::SerializationError(data))
278    }
279}