diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index 6198b463..2f53c6cd 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -89,8 +89,6 @@ impl BuiltinRuntime { } pub fn push(&mut self, arg: Value) -> Result<(), Error> { - self.fun.check_type(&arg, &self.args)?; - self.args.push(arg); Ok(()) @@ -437,8 +435,8 @@ impl DefaultFunction { ) -> Result { match self { DefaultFunction::AddInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; let result = arg1 + arg2; @@ -447,8 +445,8 @@ impl DefaultFunction { Ok(value) } DefaultFunction::SubtractInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; let result = arg1 - arg2; @@ -457,8 +455,8 @@ impl DefaultFunction { Ok(value) } DefaultFunction::MultiplyInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; let result = arg1 * arg2; @@ -467,8 +465,8 @@ impl DefaultFunction { Ok(value) } DefaultFunction::DivideInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; if *arg2 != 0.into() { let (result, _) = arg1.div_mod_floor(arg2); @@ -481,8 +479,8 @@ impl DefaultFunction { } } DefaultFunction::QuotientInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; if *arg2 != 0.into() { let (result, _) = arg1.div_rem(arg2); @@ -495,8 +493,8 @@ impl DefaultFunction { } } DefaultFunction::RemainderInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; if *arg2 != 0.into() { let (_, result) = arg1.div_rem(arg2); @@ -509,8 +507,8 @@ impl DefaultFunction { } } DefaultFunction::ModInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; if *arg2 != 0.into() { let (_, result) = arg1.div_mod_floor(arg2); @@ -523,32 +521,32 @@ impl DefaultFunction { } } DefaultFunction::EqualsInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; let value = Value::bool(arg1 == arg2); Ok(value) } DefaultFunction::LessThanInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; let value = Value::bool(arg1 < arg2); Ok(value) } DefaultFunction::LessThanEqualsInteger => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; let value = Value::bool(arg1 <= arg2); Ok(value) } DefaultFunction::AppendByteString => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_byte_string()?; let result = arg1.iter().copied().chain(arg2.iter().copied()).collect(); @@ -557,8 +555,8 @@ impl DefaultFunction { Ok(value) } DefaultFunction::ConsByteString => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_byte_string()?; let byte: u8 = match semantics { BuiltinSemantics::V1 => { @@ -584,9 +582,9 @@ impl DefaultFunction { Ok(value) } DefaultFunction::SliceByteString => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_integer(); - let arg3 = args[2].unwrap_byte_string(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_integer()?; + let arg3 = args[2].unwrap_byte_string()?; let skip: usize = if arg1.lt(&0.into()) { 0 @@ -606,15 +604,15 @@ impl DefaultFunction { Ok(value) } DefaultFunction::LengthOfByteString => { - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let value = Value::integer(arg1.len().into()); Ok(value) } DefaultFunction::IndexByteString => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_integer(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_integer()?; let index: i128 = arg2.try_into().unwrap(); @@ -629,24 +627,24 @@ impl DefaultFunction { } } DefaultFunction::EqualsByteString => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_byte_string()?; let value = Value::bool(arg1 == arg2); Ok(value) } DefaultFunction::LessThanByteString => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_byte_string()?; let value = Value::bool(arg1 < arg2); Ok(value) } DefaultFunction::LessThanEqualsByteString => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_byte_string()?; let value = Value::bool(arg1 <= arg2); @@ -655,7 +653,7 @@ impl DefaultFunction { DefaultFunction::Sha2_256 => { use cryptoxide::{digest::Digest, sha2::Sha256}; - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let mut hasher = Sha256::new(); @@ -672,7 +670,7 @@ impl DefaultFunction { DefaultFunction::Sha3_256 => { use cryptoxide::{digest::Digest, sha3::Sha3_256}; - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let mut hasher = Sha3_256::new(); @@ -690,7 +688,7 @@ impl DefaultFunction { DefaultFunction::Blake2b_224 => { use cryptoxide::{blake2b::Blake2b, digest::Digest}; - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let mut digest = [0u8; 28]; let mut context = Blake2b::new(28); @@ -705,7 +703,7 @@ impl DefaultFunction { DefaultFunction::Blake2b_256 => { use cryptoxide::{blake2b::Blake2b, digest::Digest}; - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let mut digest = [0u8; 32]; let mut context = Blake2b::new(32); @@ -720,7 +718,7 @@ impl DefaultFunction { DefaultFunction::Keccak_256 => { use cryptoxide::{digest::Digest, sha3::Keccak256}; - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let mut hasher = Keccak256::new(); @@ -737,9 +735,9 @@ impl DefaultFunction { DefaultFunction::VerifyEd25519Signature => { use cryptoxide::ed25519; - let public_key = args[0].unwrap_byte_string(); - let message = args[1].unwrap_byte_string(); - let signature = args[2].unwrap_byte_string(); + let public_key = args[0].unwrap_byte_string()?; + let message = args[1].unwrap_byte_string()?; + let signature = args[2].unwrap_byte_string()?; let public_key: [u8; 32] = public_key .clone() @@ -758,37 +756,37 @@ impl DefaultFunction { Ok(value) } DefaultFunction::VerifyEcdsaSecp256k1Signature => { - let public_key = args[0].unwrap_byte_string(); - let message = args[1].unwrap_byte_string(); - let signature = args[2].unwrap_byte_string(); + let public_key = args[0].unwrap_byte_string()?; + let message = args[1].unwrap_byte_string()?; + let signature = args[2].unwrap_byte_string()?; verify_ecdsa(public_key, message, signature) } DefaultFunction::VerifySchnorrSecp256k1Signature => { - let public_key = args[0].unwrap_byte_string(); - let message = args[1].unwrap_byte_string(); - let signature = args[2].unwrap_byte_string(); + let public_key = args[0].unwrap_byte_string()?; + let message = args[1].unwrap_byte_string()?; + let signature = args[2].unwrap_byte_string()?; verify_schnorr(public_key, message, signature) } DefaultFunction::AppendString => { - let arg1 = args[0].unwrap_string(); - let arg2 = args[1].unwrap_string(); + let arg1 = args[0].unwrap_string()?; + let arg2 = args[1].unwrap_string()?; let value = Value::string(format!("{arg1}{arg2}")); Ok(value) } DefaultFunction::EqualsString => { - let arg1 = args[0].unwrap_string(); - let arg2 = args[1].unwrap_string(); + let arg1 = args[0].unwrap_string()?; + let arg2 = args[1].unwrap_string()?; let value = Value::bool(arg1 == arg2); Ok(value) } DefaultFunction::EncodeUtf8 => { - let arg1 = args[0].unwrap_string(); + let arg1 = args[0].unwrap_string()?; let bytes = arg1.as_bytes().to_vec(); @@ -797,7 +795,7 @@ impl DefaultFunction { Ok(value) } DefaultFunction::DecodeUtf8 => { - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let string = String::from_utf8(arg1.clone())?; @@ -806,7 +804,7 @@ impl DefaultFunction { Ok(value) } DefaultFunction::IfThenElse => { - let condition = args[0].unwrap_bool(); + let condition = args[0].unwrap_bool()?; if *condition { Ok(args[1].clone()) @@ -815,35 +813,33 @@ impl DefaultFunction { } } DefaultFunction::ChooseUnit => { - // We don't need to check it here because this is already done in - // expect_type - // let Value::Con(Constant::Unit) = args[0] else {unreachable!()}; + args[0].unwrap_unit()?; Ok(args[1].clone()) } DefaultFunction::Trace => { - let arg1 = args[0].unwrap_string(); + let arg1 = args[0].unwrap_string()?; logs.push(arg1.clone()); Ok(args[1].clone()) } DefaultFunction::FstPair => { - let (_, _, first, _) = args[0].unwrap_pair(); + let (_, _, first, _) = args[0].unwrap_pair()?; let value = Value::Con(first.clone()); Ok(value) } DefaultFunction::SndPair => { - let (_, _, _, second) = args[0].unwrap_pair(); + let (_, _, _, second) = args[0].unwrap_pair()?; let value = Value::Con(second.clone()); Ok(value) } DefaultFunction::ChooseList => { - let (_, list) = args[0].unwrap_list(); + let (_, list) = args[0].unwrap_list()?; if list.is_empty() { Ok(args[1].clone()) @@ -852,8 +848,12 @@ impl DefaultFunction { } } DefaultFunction::MkCons => { - let item = args[0].unwrap_constant(); - let (r#type, list) = args[1].unwrap_list(); + let item = args[0].unwrap_constant()?; + let (r#type, list) = args[1].unwrap_list()?; + + if *r#type != Type::from(item) { + return Err(Error::TypeMismatch(Type::from(item), r#type.clone())); + } let mut ret = vec![item.clone()]; @@ -864,15 +864,10 @@ impl DefaultFunction { Ok(value) } DefaultFunction::HeadList => { - let c @ Value::Con(inner) = &args[0] else { - unreachable!() - }; - let Constant::ProtoList(_, list) = inner.as_ref() else { - unreachable!() - }; + let (_, list) = args[0].unwrap_list()?; if list.is_empty() { - Err(Error::EmptyList(c.clone())) + Err(Error::EmptyList(args[0].clone())) } else { let value = Value::Con(list[0].clone().into()); @@ -880,15 +875,10 @@ impl DefaultFunction { } } DefaultFunction::TailList => { - let c @ Value::Con(inner) = &args[0] else { - unreachable!() - }; - let Constant::ProtoList(r#type, list) = inner.as_ref() else { - unreachable!() - }; + let (r#type, list) = args[0].unwrap_list()?; if list.is_empty() { - Err(Error::EmptyList(c.clone())) + Err(Error::EmptyList(args[0].clone())) } else { let value = Value::list(r#type.clone(), list[1..].to_vec()); @@ -896,14 +886,14 @@ impl DefaultFunction { } } DefaultFunction::NullList => { - let (_, list) = args[0].unwrap_list(); + let (_, list) = args[0].unwrap_list()?; let value = Value::bool(list.is_empty()); Ok(value) } DefaultFunction::ChooseData => { - let con = args[0].unwrap_constant(); + let con = args[0].unwrap_constant()?; match con { Constant::Data(PlutusData::Constr(_)) => Ok(args[1].clone()), @@ -915,8 +905,8 @@ impl DefaultFunction { } } DefaultFunction::ConstrData => { - let i = args[0].unwrap_integer(); - let l = args[1].unwrap_data_list(); + let i = args[0].unwrap_integer()?; + let l = args[1].unwrap_data_list()?; let data_list: Vec = l .iter() @@ -939,7 +929,7 @@ impl DefaultFunction { Ok(value) } DefaultFunction::MapData => { - let (_, list) = args[0].unwrap_list(); + let (_, list) = args[0].unwrap_list()?; let mut map = Vec::new(); @@ -961,7 +951,7 @@ impl DefaultFunction { Ok(value) } DefaultFunction::ListData => { - let (_, list) = args[0].unwrap_list(); + let (_, list) = args[0].unwrap_list()?; let data_list: Vec = list .iter() @@ -976,14 +966,14 @@ impl DefaultFunction { Ok(value) } DefaultFunction::IData => { - let i = args[0].unwrap_integer(); + let i = args[0].unwrap_integer()?; let value = Value::data(PlutusData::BigInt(to_pallas_bigint(i))); Ok(value) } DefaultFunction::BData => { - let b = args[0].unwrap_byte_string(); + let b = args[0].unwrap_byte_string()?; let value = Value::data(PlutusData::BoundedBytes(b.clone().try_into().unwrap())); @@ -1022,10 +1012,7 @@ impl DefaultFunction { Ok(value) } - v => Err(Error::DeserialisationError( - "UnConstrData".to_string(), - v.clone(), - )), + v => Err(Error::NotAConstant(v.clone())), }, DefaultFunction::UnMapData => match &args[0] { v @ Value::Con(inner) => { @@ -1055,10 +1042,7 @@ impl DefaultFunction { Ok(value) } - v => Err(Error::DeserialisationError( - "UnMapData".to_string(), - v.clone(), - )), + v => Err(Error::NotAConstant(v.clone())), }, DefaultFunction::UnListData => match &args[0] { v @ Value::Con(inner) => { @@ -1079,10 +1063,7 @@ impl DefaultFunction { Ok(value) } - v => Err(Error::DeserialisationError( - "UnListData".to_string(), - v.clone(), - )), + v => Err(Error::NotAConstant(v.clone())), }, DefaultFunction::UnIData => match &args[0] { v @ Value::Con(inner) => { @@ -1097,10 +1078,7 @@ impl DefaultFunction { Ok(value) } - v => Err(Error::DeserialisationError( - "UnIData".to_string(), - v.clone(), - )), + v => Err(Error::NotAConstant(v.clone())), }, DefaultFunction::UnBData => match &args[0] { v @ Value::Con(inner) => { @@ -1115,34 +1093,18 @@ impl DefaultFunction { Ok(value) } - v => Err(Error::DeserialisationError( - "UnBData".to_string(), - v.clone(), - )), + v => Err(Error::NotAConstant(v.clone())), }, DefaultFunction::EqualsData => { - let (Value::Con(inner1), Value::Con(inner2)) = (&args[0], &args[1]) else { - unreachable!() - }; - - let Constant::Data(d1) = inner1.as_ref() else { - unreachable!() - }; - let Constant::Data(d2) = inner2.as_ref() else { - unreachable!() - }; + let d1 = args[0].unwrap_data()?; + let d2 = args[1].unwrap_data()?; let value = Value::bool(d1.eq(d2)); Ok(value) } DefaultFunction::SerialiseData => { - let Value::Con(inner) = &args[0] else { - unreachable!() - }; - let Constant::Data(d) = inner.as_ref() else { - unreachable!() - }; + let d = args[0].unwrap_data()?; let serialized_data = plutus_data_to_bytes(d).unwrap(); @@ -1151,16 +1113,8 @@ impl DefaultFunction { Ok(value) } DefaultFunction::MkPairData => { - let (Value::Con(inner1), Value::Con(inner2)) = (&args[0], &args[1]) else { - unreachable!() - }; - - let Constant::Data(d1) = inner1.as_ref() else { - unreachable!() - }; - let Constant::Data(d2) = inner2.as_ref() else { - unreachable!() - }; + let d1 = args[0].unwrap_data()?; + let d2 = args[1].unwrap_data()?; let constant = Constant::ProtoPair( Type::Data, @@ -1174,11 +1128,15 @@ impl DefaultFunction { Ok(value) } DefaultFunction::MkNilData => { + args[0].unwrap_unit()?; + let value = Value::list(Type::Data, vec![]); Ok(value) } DefaultFunction::MkNilPairData => { + args[0].unwrap_unit()?; + let constant = Constant::ProtoList( Type::Pair(Rc::new(Type::Data), Rc::new(Type::Data)), vec![], @@ -1190,8 +1148,8 @@ impl DefaultFunction { } DefaultFunction::Bls12_381_G1_Add => { - let arg1 = args[0].unwrap_bls12_381_g1_element(); - let arg2 = args[1].unwrap_bls12_381_g1_element(); + let arg1 = args[0].unwrap_bls12_381_g1_element()?; + let arg2 = args[1].unwrap_bls12_381_g1_element()?; let mut out = blst::blst_p1::default(); @@ -1208,7 +1166,7 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G1_Neg => { - let arg1 = args[0].unwrap_bls12_381_g1_element(); + let arg1 = args[0].unwrap_bls12_381_g1_element()?; let mut out = *arg1; @@ -1225,8 +1183,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G1_ScalarMul => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_bls12_381_g1_element(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_bls12_381_g1_element()?; let size_scalar = size_of::(); @@ -1266,8 +1224,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G1_Equal => { - let arg1 = args[0].unwrap_bls12_381_g1_element(); - let arg2 = args[1].unwrap_bls12_381_g1_element(); + let arg1 = args[0].unwrap_bls12_381_g1_element()?; + let arg2 = args[1].unwrap_bls12_381_g1_element()?; let is_equal = unsafe { blst::blst_p1_is_equal(arg1, arg2) }; @@ -1276,7 +1234,7 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G1_Compress => { - let arg1 = args[0].unwrap_bls12_381_g1_element(); + let arg1 = args[0].unwrap_bls12_381_g1_element()?; let out = arg1.compress(); @@ -1285,7 +1243,7 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G1_Uncompress => { - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let out = blst::blst_p1::uncompress(arg1)?; @@ -1294,8 +1252,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G1_HashToGroup => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_byte_string()?; if arg2.len() > 255 { return Err(Error::HashToCurveDstTooBig); @@ -1321,8 +1279,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_Add => { - let arg1 = args[0].unwrap_bls12_381_g2_element(); - let arg2 = args[1].unwrap_bls12_381_g2_element(); + let arg1 = args[0].unwrap_bls12_381_g2_element()?; + let arg2 = args[1].unwrap_bls12_381_g2_element()?; let mut out = blst::blst_p2::default(); @@ -1339,7 +1297,7 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_Neg => { - let arg1 = args[0].unwrap_bls12_381_g2_element(); + let arg1 = args[0].unwrap_bls12_381_g2_element()?; let mut out = *arg1; @@ -1356,8 +1314,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_ScalarMul => { - let arg1 = args[0].unwrap_integer(); - let arg2 = args[1].unwrap_bls12_381_g2_element(); + let arg1 = args[0].unwrap_integer()?; + let arg2 = args[1].unwrap_bls12_381_g2_element()?; let size_scalar = size_of::(); @@ -1397,8 +1355,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_Equal => { - let arg1 = args[0].unwrap_bls12_381_g2_element(); - let arg2 = args[1].unwrap_bls12_381_g2_element(); + let arg1 = args[0].unwrap_bls12_381_g2_element()?; + let arg2 = args[1].unwrap_bls12_381_g2_element()?; let is_equal = unsafe { blst::blst_p2_is_equal(arg1, arg2) }; @@ -1407,7 +1365,7 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_Compress => { - let arg1 = args[0].unwrap_bls12_381_g2_element(); + let arg1 = args[0].unwrap_bls12_381_g2_element()?; let out = arg1.compress(); @@ -1416,7 +1374,7 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_Uncompress => { - let arg1 = args[0].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; let out = blst::blst_p2::uncompress(arg1)?; @@ -1425,8 +1383,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_G2_HashToGroup => { - let arg1 = args[0].unwrap_byte_string(); - let arg2 = args[1].unwrap_byte_string(); + let arg1 = args[0].unwrap_byte_string()?; + let arg2 = args[1].unwrap_byte_string()?; if arg2.len() > 255 { return Err(Error::HashToCurveDstTooBig); @@ -1452,8 +1410,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_MillerLoop => { - let arg1 = args[0].unwrap_bls12_381_g1_element(); - let arg2 = args[1].unwrap_bls12_381_g2_element(); + let arg1 = args[0].unwrap_bls12_381_g1_element()?; + let arg2 = args[1].unwrap_bls12_381_g2_element()?; let mut out = blst::blst_fp12::default(); @@ -1472,8 +1430,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_MulMlResult => { - let arg1 = args[0].unwrap_bls12_381_ml_result(); - let arg2 = args[1].unwrap_bls12_381_ml_result(); + let arg1 = args[0].unwrap_bls12_381_ml_result()?; + let arg2 = args[1].unwrap_bls12_381_ml_result()?; let mut out = blst::blst_fp12::default(); @@ -1486,8 +1444,8 @@ impl DefaultFunction { Ok(Value::Con(constant.into())) } DefaultFunction::Bls12_381_FinalVerify => { - let arg1 = args[0].unwrap_bls12_381_ml_result(); - let arg2 = args[1].unwrap_bls12_381_ml_result(); + let arg1 = args[0].unwrap_bls12_381_ml_result()?; + let arg2 = args[1].unwrap_bls12_381_ml_result()?; let verified = unsafe { blst::blst_fp12_finalverify(arg1, arg2) }; diff --git a/crates/uplc/src/machine/value.rs b/crates/uplc/src/machine/value.rs index f322b0ba..6e54f6fe 100644 --- a/crates/uplc/src/machine/value.rs +++ b/crates/uplc/src/machine/value.rs @@ -69,125 +69,138 @@ impl Value { Value::Con(constant.into()) } - pub(super) fn unwrap_integer(&self) -> &BigInt { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::Integer(integer) = inner.as_ref() else { - unreachable!() + pub(super) fn unwrap_integer(&self) -> Result<&BigInt, Error> { + let inner = self.unwrap_constant()?; + + let Constant::Integer(integer) = inner else { + return Err(Error::TypeMismatch(Type::Integer, inner.into())); }; - integer + Ok(integer) } - pub(super) fn unwrap_byte_string(&self) -> &Vec { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::ByteString(byte_string) = inner.as_ref() else { - unreachable!() + pub(super) fn unwrap_byte_string(&self) -> Result<&Vec, Error> { + let inner = self.unwrap_constant()?; + + let Constant::ByteString(byte_string) = inner else { + return Err(Error::TypeMismatch(Type::ByteString, inner.into())); }; - byte_string + Ok(byte_string) } - pub(super) fn unwrap_string(&self) -> &String { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::String(string) = inner.as_ref() else { - unreachable!() + pub(super) fn unwrap_string(&self) -> Result<&String, Error> { + let inner = self.unwrap_constant()?; + + let Constant::String(string) = inner else { + return Err(Error::TypeMismatch(Type::String, inner.into())); }; - string + Ok(string) } - pub(super) fn unwrap_bool(&self) -> &bool { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::Bool(condition) = inner.as_ref() else { - unreachable!() + pub(super) fn unwrap_bool(&self) -> Result<&bool, Error> { + let inner = self.unwrap_constant()?; + + let Constant::Bool(condition) = inner else { + return Err(Error::TypeMismatch(Type::Bool, inner.into())); }; - condition + Ok(condition) } - pub(super) fn unwrap_pair(&self) -> (&Type, &Type, &Rc, &Rc) { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::ProtoPair(t1, t2, first, second) = inner.as_ref() else { - unreachable!() + #[allow(clippy::type_complexity)] + pub(super) fn unwrap_pair( + &self, + ) -> Result<(&Type, &Type, &Rc, &Rc), Error> { + let inner = self.unwrap_constant()?; + + let Constant::ProtoPair(t1, t2, first, second) = inner else { + return Err(Error::PairTypeMismatch(inner.into())); }; - (t1, t2, first, second) + Ok((t1, t2, first, second)) } - pub(super) fn unwrap_list(&self) -> (&Type, &Vec) { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::ProtoList(t, list) = inner.as_ref() else { - unreachable!() + pub(super) fn unwrap_list(&self) -> Result<(&Type, &Vec), Error> { + let inner = self.unwrap_constant()?; + + let Constant::ProtoList(t, list) = inner else { + return Err(Error::ListTypeMismatch(inner.into())); }; - (t, list) + Ok((t, list)) } - pub(super) fn unwrap_constant(&self) -> &Constant { + pub(super) fn unwrap_data(&self) -> Result<&PlutusData, Error> { + let inner = self.unwrap_constant()?; + + let Constant::Data(data) = inner else { + return Err(Error::TypeMismatch(Type::Data, inner.into())); + }; + + Ok(data) + } + + pub(super) fn unwrap_unit(&self) -> Result<(), Error> { + let inner = self.unwrap_constant()?; + + let Constant::Unit = inner else { + return Err(Error::TypeMismatch(Type::Unit, inner.into())); + }; + + Ok(()) + } + + pub(super) fn unwrap_constant(&self) -> Result<&Constant, Error> { let Value::Con(item) = self else { - unreachable!() + return Err(Error::NotAConstant(self.clone())); }; - item.as_ref() + Ok(item.as_ref()) } - pub(super) fn unwrap_data_list(&self) -> &Vec { - let Value::Con(inner) = self else { - unreachable!() - }; - let Constant::ProtoList(Type::Data, list) = inner.as_ref() else { - unreachable!() + pub(super) fn unwrap_data_list(&self) -> Result<&Vec, Error> { + let inner = self.unwrap_constant()?; + + let Constant::ProtoList(Type::Data, list) = inner else { + return Err(Error::TypeMismatch( + Type::List(Type::Data.into()), + inner.into(), + )); }; - list + Ok(list) } - pub(super) fn unwrap_bls12_381_g1_element(&self) -> &blst::blst_p1 { - let Value::Con(inner) = self else { - unreachable!() + pub(super) fn unwrap_bls12_381_g1_element(&self) -> Result<&blst::blst_p1, Error> { + let inner = self.unwrap_constant()?; + + let Constant::Bls12_381G1Element(element) = inner else { + return Err(Error::TypeMismatch(Type::Bls12_381G1Element, inner.into())); }; - let Constant::Bls12_381G1Element(element) = inner.as_ref() else { - unreachable!() - }; - - element + Ok(element) } - pub(super) fn unwrap_bls12_381_g2_element(&self) -> &blst::blst_p2 { - let Value::Con(inner) = self else { - unreachable!() + pub(super) fn unwrap_bls12_381_g2_element(&self) -> Result<&blst::blst_p2, Error> { + let inner = self.unwrap_constant()?; + + let Constant::Bls12_381G2Element(element) = inner else { + return Err(Error::TypeMismatch(Type::Bls12_381G2Element, inner.into())); }; - let Constant::Bls12_381G2Element(element) = inner.as_ref() else { - unreachable!() - }; - - element + Ok(element) } - pub(super) fn unwrap_bls12_381_ml_result(&self) -> &blst::blst_fp12 { - let Value::Con(inner) = self else { - unreachable!() + pub(super) fn unwrap_bls12_381_ml_result(&self) -> Result<&blst::blst_fp12, Error> { + let inner = self.unwrap_constant()?; + + let Constant::Bls12_381MlResult(element) = inner else { + return Err(Error::TypeMismatch(Type::Bls12_381MlResult, inner.into())); }; - let Constant::Bls12_381MlResult(element) = inner.as_ref() else { - unreachable!() - }; - - element + Ok(element) } pub fn is_integer(&self) -> bool { diff --git a/crates/uplc/test_data/conformance/evaluation/builtin/constant/bls12-381/G1/bad-syntax-1/bad-syntax-1.uplc.expected b/crates/uplc/test_data/conformance/evaluation/builtin/constant/bls12-381/G1/bad-syntax-1/bad-syntax-1.uplc.expected index 13b380d3..fd569489 100644 --- a/crates/uplc/test_data/conformance/evaluation/builtin/constant/bls12-381/G1/bad-syntax-1/bad-syntax-1.uplc.expected +++ b/crates/uplc/test_data/conformance/evaluation/builtin/constant/bls12-381/G1/bad-syntax-1/bad-syntax-1.uplc.expected @@ -1 +1 @@ -parse error +parse error \ No newline at end of file diff --git a/crates/uplc/test_data/conformance/evaluation/builtin/interleaving/iteWrongCondTypePartiallyApplied/iteWrongCondTypePartiallyApplied.uplc b/crates/uplc/test_data/conformance/evaluation/builtin/interleaving/iteWrongCondTypePartiallyApplied/iteWrongCondTypePartiallyApplied.uplc new file mode 100644 index 00000000..b356a921 --- /dev/null +++ b/crates/uplc/test_data/conformance/evaluation/builtin/interleaving/iteWrongCondTypePartiallyApplied/iteWrongCondTypePartiallyApplied.uplc @@ -0,0 +1,7 @@ +(program + 1.0.0 + [ + [ (force (builtin ifThenElse)) (con string "11 <= 22") ] + (con string "\172(11 <= 22)") + ] +) diff --git a/crates/uplc/test_data/conformance/evaluation/builtin/interleaving/iteWrongCondTypePartiallyApplied/iteWrongCondTypePartiallyApplied.uplc.expected b/crates/uplc/test_data/conformance/evaluation/builtin/interleaving/iteWrongCondTypePartiallyApplied/iteWrongCondTypePartiallyApplied.uplc.expected new file mode 100644 index 00000000..aead86ec --- /dev/null +++ b/crates/uplc/test_data/conformance/evaluation/builtin/interleaving/iteWrongCondTypePartiallyApplied/iteWrongCondTypePartiallyApplied.uplc.expected @@ -0,0 +1,4 @@ +(program 1.0.0 [ + [ (force (builtin ifThenElse)) (con string "11 <= 22") ] + (con string "\172(11 <= 22)") +]) \ No newline at end of file diff --git a/crates/uplc/test_data/conformance/evaluation/term/unlifting-unsat/unlifting-unsat.uplc b/crates/uplc/test_data/conformance/evaluation/term/unlifting-unsat/unlifting-unsat.uplc new file mode 100644 index 00000000..ce2efb7b --- /dev/null +++ b/crates/uplc/test_data/conformance/evaluation/term/unlifting-unsat/unlifting-unsat.uplc @@ -0,0 +1,2 @@ +-- ill-typed but does not fail at runtime because the builtin application is not saturated. +(program 1.0.0 [(builtin addInteger) (con unit ())]) \ No newline at end of file diff --git a/crates/uplc/test_data/conformance/evaluation/term/unlifting-unsat/unlifting-unsat.uplc.expected b/crates/uplc/test_data/conformance/evaluation/term/unlifting-unsat/unlifting-unsat.uplc.expected new file mode 100644 index 00000000..57d2ddd4 --- /dev/null +++ b/crates/uplc/test_data/conformance/evaluation/term/unlifting-unsat/unlifting-unsat.uplc.expected @@ -0,0 +1 @@ +(program 1.0.0 [ (builtin addInteger) (con unit ()) ]) \ No newline at end of file