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