From b0ea1871513cea7c70196b0ab369b7630e6d1034 Mon Sep 17 00:00:00 2001 From: Kasey White Date: Thu, 29 Dec 2022 18:20:13 -0500 Subject: [PATCH] better data deserialization errors and test hint now runs even being in a sequence --- crates/aiken-lang/src/ast.rs | 49 ++++++++++++++++++++++++------ crates/uplc/src/machine/error.rs | 4 +-- crates/uplc/src/machine/runtime.rs | 25 ++++++++++++--- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index 86b559fa..2d59a8c7 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -87,16 +87,47 @@ pub type UntypedTypeAlias = TypeAlias<()>; impl TypedFunction { pub fn test_hint(&self) -> Option<(BinOp, Box, Box)> { - match &self.body { - TypedExpr::BinOp { - name, - tipo, - left, - right, - .. - } if tipo == &bool() => Some((*name, left.clone(), right.clone())), - _ => None, + do_test_hint(&self.body) + } +} + +pub fn do_test_hint(body: &TypedExpr) -> Option<(BinOp, Box, Box)> { + match body { + TypedExpr::BinOp { + name, + tipo, + left, + right, + .. + } if tipo == &bool() => Some((*name, left.clone(), right.clone())), + TypedExpr::Sequence { expressions, .. } | TypedExpr::Pipeline { expressions, .. } => { + if let Some((binop, left, right)) = do_test_hint(&expressions[expressions.len() - 1]) { + let mut new_left_expressions = expressions.clone(); + new_left_expressions.pop(); + new_left_expressions.push(*left); + + let mut new_right_expressions = expressions.clone(); + new_right_expressions.pop(); + new_right_expressions.push(*right); + + Some(( + binop, + TypedExpr::Sequence { + expressions: new_left_expressions, + location: Span::empty(), + } + .into(), + TypedExpr::Sequence { + expressions: new_right_expressions, + location: Span::empty(), + } + .into(), + )) + } else { + None + } } + _ => None, } } diff --git a/crates/uplc/src/machine/error.rs b/crates/uplc/src/machine/error.rs index d9de5344..7132db2c 100644 --- a/crates/uplc/src/machine/error.rs +++ b/crates/uplc/src/machine/error.rs @@ -44,8 +44,8 @@ pub enum Error { UnexpectedEd25519PublicKeyLength(usize), #[error("Ed25519S Signature should be 64 bytes but it was {0}")] UnexpectedEd25519SignatureLength(usize), - #[error("Failed to deserialise PlutusData:\n\n{0:#?}")] - DeserialisationError(Value), + #[error("Failed to deserialise PlutusData using {0}:\n\n{1:#?}")] + DeserialisationError(String, Value), #[error("Integer overflow")] OverflowError, } diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index a89a0c2d..b2eb90c2 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -769,7 +769,10 @@ impl DefaultFunction { )), ))) } - v => Err(Error::DeserialisationError(v.clone())), + v => Err(Error::DeserialisationError( + "UnConstrData".to_string(), + v.clone(), + )), }, DefaultFunction::UnMapData => match &args[0] { Value::Con(Constant::Data(PlutusData::Map(m))) => { @@ -788,7 +791,10 @@ impl DefaultFunction { .collect(), ))) } - v => Err(Error::DeserialisationError(v.clone())), + v => Err(Error::DeserialisationError( + "UnMapData".to_string(), + v.clone(), + )), }, DefaultFunction::UnListData => match &args[0] { Value::Con(Constant::Data(PlutusData::Array(l))) => { @@ -800,7 +806,10 @@ impl DefaultFunction { .collect(), ))) } - v => Err(Error::DeserialisationError(v.clone())), + v => Err(Error::DeserialisationError( + "UnListData".to_string(), + v.clone(), + )), }, DefaultFunction::UnIData => match &args[0] { Value::Con(Constant::Data(PlutusData::BigInt(b))) => { @@ -812,13 +821,19 @@ impl DefaultFunction { unreachable!() } } - v => Err(Error::DeserialisationError(v.clone())), + v => Err(Error::DeserialisationError( + "UnIData".to_string(), + v.clone(), + )), }, DefaultFunction::UnBData => match &args[0] { Value::Con(Constant::Data(PlutusData::BoundedBytes(b))) => { Ok(Value::Con(Constant::ByteString(b.to_vec()))) } - v => Err(Error::DeserialisationError(v.clone())), + v => Err(Error::DeserialisationError( + "UnBData".to_string(), + v.clone(), + )), }, DefaultFunction::EqualsData => match (&args[0], &args[1]) { (Value::Con(Constant::Data(d1)), Value::Con(Constant::Data(d2))) => {