From 42784965d228a0dda1e4cf1efcb81a12cfeaeaea Mon Sep 17 00:00:00 2001 From: KtorZ Date: Wed, 14 Aug 2024 02:46:04 +0200 Subject: [PATCH] Implement new costing function for {divide,quotient,mod,remainder}_integer As well as fixing a couple of other issues thanks to conformance tests. Some functions like multiply_integer or verify_ed25519_signature have also slightly changed their costing function. --- crates/uplc/src/machine/cost_model.rs | 498 +++++++++++++++++--------- crates/uplc/src/machine/error.rs | 4 +- crates/uplc/src/machine/runtime.rs | 4 +- crates/uplc/src/parser.rs | 18 +- crates/uplc/tests/conformance.rs | 9 +- 5 files changed, 352 insertions(+), 181 deletions(-) diff --git a/crates/uplc/src/machine/cost_model.rs b/crates/uplc/src/machine/cost_model.rs index bd02cfb9..86eec4d0 100644 --- a/crates/uplc/src/machine/cost_model.rs +++ b/crates/uplc/src/machine/cost_model.rs @@ -1320,116 +1320,84 @@ impl BuiltinCosts { intercept: 0, slope: 1, }), - cpu: TwoArguments::AddedSizes(AddedSizes { + cpu: TwoArguments::MultipliedSizes(MultipliedSizes { intercept: 90434, slope: 519, }), }, - // FIXME: Costing function for divide_integer has changed in v3 - // - // "divideInteger-cpu-arguments-constant": 85848, - // "divideInteger-cpu-arguments-model-arguments-c00": 123203, - // "divideInteger-cpu-arguments-model-arguments-c01": 7305, - // "divideInteger-cpu-arguments-model-arguments-c02": -900, - // "divideInteger-cpu-arguments-model-arguments-c10": 1716, - // "divideInteger-cpu-arguments-model-arguments-c11": 549, - // "divideInteger-cpu-arguments-model-arguments-c20": 57, - // "divideInteger-cpu-arguments-model-arguments-minimum": 85848, - // "divideInteger-memory-arguments-intercept": 0, - // "divideInteger-memory-arguments-minimum": 1, - // "divideInteger-memory-arguments-slope": 1, divide_integer: CostingFun { mem: TwoArguments::SubtractedSizes(SubtractedSizes { intercept: 0, slope: 1, minimum: 1, }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: 196500, - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { - intercept: 453240, - slope: 220, - })), - }), + cpu: TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + 85848, + TwoArgumentsQuadraticFunction { + minimum: 85848, + coeff_00: 123203, + coeff_01: 7305, + coeff_02: -900, + coeff_10: 1716, + coeff_11: 549, + coeff_20: 57, + }, + ), }, - // FIXME Costing function for quotient_integer has changed in v3 - // - // "quotientInteger-cpu-arguments-constant": 85848, - // "quotientInteger-cpu-arguments-model-arguments-c00": 123203, - // "quotientInteger-cpu-arguments-model-arguments-c01": 7305, - // "quotientInteger-cpu-arguments-model-arguments-c02": -900, - // "quotientInteger-cpu-arguments-model-arguments-c10": 1716, - // "quotientInteger-cpu-arguments-model-arguments-c11": 549, - // "quotientInteger-cpu-arguments-model-arguments-c20": 57, - // "quotientInteger-cpu-arguments-model-arguments-minimum": 85848, - // "quotientInteger-memory-arguments-intercept": 0, - // "quotientInteger-memory-arguments-minimum": 1, - // "quotientInteger-memory-arguments-slope": 1, quotient_integer: CostingFun { mem: TwoArguments::SubtractedSizes(SubtractedSizes { intercept: 0, slope: 1, minimum: 1, }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: 196500, - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { - intercept: 453240, - slope: 220, - })), - }), + cpu: TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + 85848, + TwoArgumentsQuadraticFunction { + minimum: 85848, + coeff_00: 123203, + coeff_01: 7305, + coeff_02: -900, + coeff_10: 1716, + coeff_11: 549, + coeff_20: 57, + }, + ), }, - // FIXME Costing function for remainder_integer has changed in v3 - // - // "remainderInteger-cpu-arguments-constant": 85848, - // "remainderInteger-cpu-arguments-model-arguments-c00": 123203, - // "remainderInteger-cpu-arguments-model-arguments-c01": 7305, - // "remainderInteger-cpu-arguments-model-arguments-c02": -900, - // "remainderInteger-cpu-arguments-model-arguments-c10": 1716, - // "remainderInteger-cpu-arguments-model-arguments-c11": 549, - // "remainderInteger-cpu-arguments-model-arguments-c20": 57, - // "remainderInteger-cpu-arguments-model-arguments-minimum": 85848, - // "remainderInteger-memory-arguments-intercept": 0, - // "remainderInteger-memory-arguments-slope": 1, remainder_integer: CostingFun { - mem: TwoArguments::SubtractedSizes(SubtractedSizes { + mem: TwoArguments::LinearInY(LinearSize { intercept: 0, slope: 1, - minimum: 1, - }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: 196500, - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { - intercept: 453240, - slope: 220, - })), }), + cpu: TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + 85848, + TwoArgumentsQuadraticFunction { + minimum: 85848, + coeff_00: 123203, + coeff_01: 7305, + coeff_02: -900, + coeff_10: 1716, + coeff_11: 549, + coeff_20: 57, + }, + ), }, - // FIXME: Costing function for mod_integer has changed in v3 - // - // "modInteger-cpu-arguments-constant": 85848, - // "modInteger-cpu-arguments-model-arguments-c00": 123203, - // "modInteger-cpu-arguments-model-arguments-c01": 7305, - // "modInteger-cpu-arguments-model-arguments-c02": -900, - // "modInteger-cpu-arguments-model-arguments-c10": 1716, - // "modInteger-cpu-arguments-model-arguments-c11": 549, - // "modInteger-cpu-arguments-model-arguments-c20": 57, - // "modInteger-cpu-arguments-model-arguments-minimum": 85848, - // "modInteger-memory-arguments-intercept": 0, - // "modInteger-memory-arguments-slope": 1, mod_integer: CostingFun { - mem: TwoArguments::SubtractedSizes(SubtractedSizes { + mem: TwoArguments::LinearInY(LinearSize { intercept: 0, slope: 1, - minimum: 1, - }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: 196500, - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { - intercept: 453240, - slope: 220, - })), }), + cpu: TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + 85848, + TwoArgumentsQuadraticFunction { + minimum: 85848, + coeff_00: 123203, + coeff_01: 7305, + coeff_02: -900, + coeff_10: 1716, + coeff_11: 549, + coeff_20: 57, + }, + ), }, equals_integer: CostingFun { mem: TwoArguments::ConstantCost(1), @@ -1479,7 +1447,7 @@ impl BuiltinCosts { }), cpu: ThreeArguments::LinearInZ(LinearSize { intercept: 20467, - slope: 0, + slope: 1, }), }, length_of_byte_string: CostingFun { @@ -1535,7 +1503,7 @@ impl BuiltinCosts { }, verify_ed25519_signature: CostingFun { mem: ThreeArguments::ConstantCost(10), - cpu: ThreeArguments::LinearInZ(LinearSize { + cpu: ThreeArguments::LinearInY(LinearSize { intercept: 53384111, slope: 14333, }), @@ -3158,14 +3126,26 @@ pub fn initialize_cost_model(version: &Language, costs: &[i64]) -> CostModel { .get("multiply_integer-mem-arguments-slope") .unwrap_or(&30000000000), }), - cpu: TwoArguments::AddedSizes(AddedSizes { - intercept: *cost_map - .get("multiply_integer-cpu-arguments-intercept") - .unwrap_or(&30000000000), - slope: *cost_map - .get("multiply_integer-cpu-arguments-slope") - .unwrap_or(&30000000000), - }), + cpu: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::AddedSizes(AddedSizes { + intercept: *cost_map + .get("multiply_integer-cpu-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("multiply_integer-cpu-arguments-slope") + .unwrap_or(&30000000000), + }) + } + Language::PlutusV3 => TwoArguments::MultipliedSizes(MultipliedSizes { + intercept: *cost_map + .get("multiply_integer-cpu-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("multiply_integer-cpu-arguments-slope") + .unwrap_or(&30000000000), + }), + }, }, divide_integer: CostingFun { mem: TwoArguments::SubtractedSizes(SubtractedSizes { @@ -3179,19 +3159,51 @@ pub fn initialize_cost_model(version: &Language, costs: &[i64]) -> CostModel { .get("divide_integer-mem-arguments-minimum") .unwrap_or(&30000000000), }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: *cost_map - .get("divide_integer-cpu-arguments-constant") - .unwrap_or(&30000000000), - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { - intercept: *cost_map - .get("divide_integer-cpu-arguments-model-arguments-intercept") + cpu: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { + constant: *cost_map + .get("divide_integer-cpu-arguments-constant") + .unwrap_or(&30000000000), + model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { + intercept: *cost_map + .get("divide_integer-cpu-arguments-model-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("divide_integer-cpu-arguments-model-arguments-slope") + .unwrap_or(&30000000000), + })), + }) + } + Language::PlutusV3 => TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + *cost_map + .get("divide_integer-cpu-arguments-constant") .unwrap_or(&30000000000), - slope: *cost_map - .get("divide_integer-cpu-arguments-model-arguments-slope") - .unwrap_or(&30000000000), - })), - }), + TwoArgumentsQuadraticFunction { + minimum: *cost_map + .get("divide_integer-cpu-arguments-minimum") + .unwrap_or(&30000000000), + coeff_00: *cost_map + .get("divide_integer-cpu-arguments-c00") + .unwrap_or(&30000000000), + coeff_10: *cost_map + .get("divide_integer-cpu-arguments-c10") + .unwrap_or(&30000000000), + coeff_01: *cost_map + .get("divide_integer-cpu-arguments-c01") + .unwrap_or(&30000000000), + coeff_20: *cost_map + .get("divide_integer-cpu-arguments-c20") + .unwrap_or(&30000000000), + coeff_11: *cost_map + .get("divide_integer-cpu-arguments-c11") + .unwrap_or(&30000000000), + coeff_02: *cost_map + .get("divide_integer-cpu-arguments-c02") + .unwrap_or(&30000000000), + }, + ), + }, }, quotient_integer: CostingFun { mem: TwoArguments::SubtractedSizes(SubtractedSizes { @@ -3205,71 +3217,193 @@ pub fn initialize_cost_model(version: &Language, costs: &[i64]) -> CostModel { .get("quotient_integer-mem-arguments-minimum") .unwrap_or(&30000000000), }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: *cost_map - .get("quotient_integer-cpu-arguments-constant") - .unwrap_or(&30000000000), - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { - intercept: *cost_map - .get("quotient_integer-cpu-arguments-model-arguments-intercept") + cpu: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { + constant: *cost_map + .get("quotient_integer-cpu-arguments-constant") + .unwrap_or(&30000000000), + model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { + intercept: *cost_map + .get("quotient_integer-cpu-arguments-model-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("quotient_integer-cpu-arguments-model-arguments-slope") + .unwrap_or(&30000000000), + })), + }) + } + Language::PlutusV3 => TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + *cost_map + .get("quotient_integer-cpu-arguments-constant") .unwrap_or(&30000000000), - slope: *cost_map - .get("quotient_integer-cpu-arguments-model-arguments-slope") - .unwrap_or(&30000000000), - })), - }), + TwoArgumentsQuadraticFunction { + minimum: *cost_map + .get("quotient_integer-cpu-arguments-minimum") + .unwrap_or(&30000000000), + coeff_00: *cost_map + .get("quotient_integer-cpu-arguments-c00") + .unwrap_or(&30000000000), + coeff_10: *cost_map + .get("quotient_integer-cpu-arguments-c10") + .unwrap_or(&30000000000), + coeff_01: *cost_map + .get("quotient_integer-cpu-arguments-c01") + .unwrap_or(&30000000000), + coeff_20: *cost_map + .get("quotient_integer-cpu-arguments-c20") + .unwrap_or(&30000000000), + coeff_11: *cost_map + .get("quotient_integer-cpu-arguments-c11") + .unwrap_or(&30000000000), + coeff_02: *cost_map + .get("quotient_integer-cpu-arguments-c02") + .unwrap_or(&30000000000), + }, + ), + }, }, remainder_integer: CostingFun { - mem: TwoArguments::SubtractedSizes(SubtractedSizes { - intercept: *cost_map - .get("remainder_integer-mem-arguments-intercept") - .unwrap_or(&30000000000), - slope: *cost_map - .get("remainder_integer-mem-arguments-slope") - .unwrap_or(&30000000000), - minimum: *cost_map - .get("remainder_integer-mem-arguments-minimum") - .unwrap_or(&30000000000), - }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: *cost_map - .get("remainder_integer-cpu-arguments-constant") - .unwrap_or(&30000000000), - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { + mem: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::SubtractedSizes(SubtractedSizes { + intercept: *cost_map + .get("remainder_integer-mem-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("remainder_integer-mem-arguments-slope") + .unwrap_or(&30000000000), + minimum: *cost_map + .get("remainder_integer-mem-arguments-minimum") + .unwrap_or(&30000000000), + }) + } + Language::PlutusV3 => TwoArguments::LinearInY(LinearSize { intercept: *cost_map - .get("remainder_integer-cpu-arguments-model-arguments-intercept") + .get("remainder_integer-mem-arguments-intercept") .unwrap_or(&30000000000), slope: *cost_map - .get("remainder_integer-cpu-arguments-model-arguments-slope") + .get("remainder_integer-mem-arguments-slope") .unwrap_or(&30000000000), - })), - }), + }), + }, + cpu: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { + constant: *cost_map + .get("remainder_integer-cpu-arguments-constant") + .unwrap_or(&30000000000), + model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { + intercept: *cost_map + .get( + "remainder_integer-cpu-arguments-model-arguments-intercept", + ) + .unwrap_or(&30000000000), + slope: *cost_map + .get("remainder_integer-cpu-arguments-model-arguments-slope") + .unwrap_or(&30000000000), + })), + }) + } + Language::PlutusV3 => TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + *cost_map + .get("remainder_integer-cpu-arguments-constant") + .unwrap_or(&30000000000), + TwoArgumentsQuadraticFunction { + minimum: *cost_map + .get("remainder_integer-cpu-arguments-minimum") + .unwrap_or(&30000000000), + coeff_00: *cost_map + .get("remainder_integer-cpu-arguments-c00") + .unwrap_or(&30000000000), + coeff_10: *cost_map + .get("remainder_integer-cpu-arguments-c10") + .unwrap_or(&30000000000), + coeff_01: *cost_map + .get("remainder_integer-cpu-arguments-c01") + .unwrap_or(&30000000000), + coeff_20: *cost_map + .get("remainder_integer-cpu-arguments-c20") + .unwrap_or(&30000000000), + coeff_11: *cost_map + .get("remainder_integer-cpu-arguments-c11") + .unwrap_or(&30000000000), + coeff_02: *cost_map + .get("remainder_integer-cpu-arguments-c02") + .unwrap_or(&30000000000), + }, + ), + }, }, mod_integer: CostingFun { - mem: TwoArguments::SubtractedSizes(SubtractedSizes { - intercept: *cost_map - .get("mod_integer-mem-arguments-intercept") - .unwrap_or(&30000000000), - slope: *cost_map - .get("mod_integer-mem-arguments-slope") - .unwrap_or(&30000000000), - minimum: *cost_map - .get("mod_integer-mem-arguments-minimum") - .unwrap_or(&30000000000), - }), - cpu: TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { - constant: *cost_map - .get("mod_integer-cpu-arguments-constant") - .unwrap_or(&30000000000), - model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { + mem: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::SubtractedSizes(SubtractedSizes { + intercept: *cost_map + .get("mod_integer-mem-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("mod_integer-mem-arguments-slope") + .unwrap_or(&30000000000), + minimum: *cost_map + .get("mod_integer-mem-arguments-minimum") + .unwrap_or(&30000000000), + }) + } + Language::PlutusV3 => TwoArguments::LinearInY(LinearSize { intercept: *cost_map - .get("mod_integer-cpu-arguments-model-arguments-intercept") + .get("mod_integer-mem-arguments-intercept") .unwrap_or(&30000000000), slope: *cost_map - .get("mod_integer-cpu-arguments-model-arguments-slope") + .get("mod_integer-mem-arguments-slope") .unwrap_or(&30000000000), - })), - }), + }), + }, + cpu: match version { + Language::PlutusV1 | Language::PlutusV2 => { + TwoArguments::ConstAboveDiagonal(ConstantOrTwoArguments { + constant: *cost_map + .get("mod_integer-cpu-arguments-constant") + .unwrap_or(&30000000000), + model: Box::new(TwoArguments::MultipliedSizes(MultipliedSizes { + intercept: *cost_map + .get("mod_integer-cpu-arguments-model-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("mod_integer-cpu-arguments-model-arguments-slope") + .unwrap_or(&30000000000), + })), + }) + } + Language::PlutusV3 => TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY( + *cost_map + .get("mod_integer-cpu-arguments-constant") + .unwrap_or(&30000000000), + TwoArgumentsQuadraticFunction { + minimum: *cost_map + .get("mod_integer-cpu-arguments-minimum") + .unwrap_or(&30000000000), + coeff_00: *cost_map + .get("mod_integer-cpu-arguments-c00") + .unwrap_or(&30000000000), + coeff_10: *cost_map + .get("mod_integer-cpu-arguments-c10") + .unwrap_or(&30000000000), + coeff_01: *cost_map + .get("mod_integer-cpu-arguments-c01") + .unwrap_or(&30000000000), + coeff_20: *cost_map + .get("mod_integer-cpu-arguments-c20") + .unwrap_or(&30000000000), + coeff_11: *cost_map + .get("mod_integer-cpu-arguments-c11") + .unwrap_or(&30000000000), + coeff_02: *cost_map + .get("mod_integer-cpu-arguments-c02") + .unwrap_or(&30000000000), + }, + ), + }, }, equals_integer: CostingFun { mem: TwoArguments::ConstantCost( @@ -3493,14 +3627,21 @@ pub fn initialize_cost_model(version: &Language, costs: &[i64]) -> CostModel { .get("verify_ed25519_signature-mem-arguments") .unwrap_or(&30000000000), ), - cpu: ThreeArguments::LinearInZ(LinearSize { - intercept: *cost_map - .get("verify_ed25519_signature-cpu-arguments-intercept") - .unwrap_or(&30000000000), - slope: *cost_map - .get("verify_ed25519_signature-cpu-arguments-slope") - .unwrap_or(&30000000000), - }), + cpu: { + let sizes = LinearSize { + intercept: *cost_map + .get("verify_ed25519_signature-cpu-arguments-intercept") + .unwrap_or(&30000000000), + slope: *cost_map + .get("verify_ed25519_signature-cpu-arguments-slope") + .unwrap_or(&30000000000), + }; + + match version { + Language::PlutusV1 | Language::PlutusV2 => ThreeArguments::LinearInZ(sizes), + Language::PlutusV3 => ThreeArguments::LinearInY(sizes), + } + }, }, verify_ecdsa_secp256k1_signature: CostingFun { mem: ThreeArguments::ConstantCost( @@ -4238,6 +4379,7 @@ pub enum TwoArguments { ConstAboveDiagonal(ConstantOrTwoArguments), ConstBelowDiagonal(ConstantOrTwoArguments), QuadraticInY(QuadraticFunction), + ConstAboveDiagonalIntoQuadraticXAndY(i64, TwoArgumentsQuadraticFunction), } impl TwoArguments { @@ -4275,6 +4417,21 @@ impl TwoArguments { } } TwoArguments::QuadraticInY(q) => q.coeff_0 + (q.coeff_1 * y) + (q.coeff_2 * y * y), + TwoArguments::ConstAboveDiagonalIntoQuadraticXAndY(constant, q) => { + if x < y { + *constant + } else { + std::cmp::max( + q.minimum, + q.coeff_00 + + q.coeff_10 * x + + q.coeff_01 * y + + q.coeff_20 * x * x + + q.coeff_11 * x * y + + q.coeff_02 * y * y, + ) + } + } } } } @@ -4380,6 +4537,17 @@ pub struct QuadraticFunction { coeff_2: i64, } +#[derive(Debug, PartialEq, Clone)] +pub struct TwoArgumentsQuadraticFunction { + minimum: i64, + coeff_00: i64, + coeff_10: i64, + coeff_01: i64, + coeff_20: i64, + coeff_11: i64, + coeff_02: i64, +} + #[repr(u8)] pub enum StepKind { Constant = 0, diff --git a/crates/uplc/src/machine/error.rs b/crates/uplc/src/machine/error.rs index d4255ccf..b25b29df 100644 --- a/crates/uplc/src/machine/error.rs +++ b/crates/uplc/src/machine/error.rs @@ -63,8 +63,8 @@ pub enum Error { Utf8(#[from] FromUtf8Error), #[error("Out of Bounds\n\nindex: {}\nbytestring: {}\npossible: 0 - {}", .0, hex::encode(.1), .1.len() - 1)] ByteStringOutOfBounds(BigInt, Vec), - #[error("Attempt to consByteString something bigger than one byte {0}")] - ByteStringConsBiggerThanOneByte(BigInt), + #[error("Attempt to consByteString something than isn't a byte between [0-255]: {0}")] + ByteStringConsNotAByte(BigInt), #[error("Divide By Zero\n\n{0} / {1}")] DivideByZero(BigInt, BigInt), #[error("Ed25519S PublicKey should be 32 bytes but it was {0}")] diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index 384f932a..c69bd038 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -485,8 +485,8 @@ impl DefaultFunction { wrap.try_into().unwrap() } BuiltinSemantics::V2 => { - if *arg1 > 255.into() { - return Err(Error::ByteStringConsBiggerThanOneByte(arg1.clone())); + if *arg1 > 255.into() || *arg1 < 0.into() { + return Err(Error::ByteStringConsNotAByte(arg1.clone())); } arg1.try_into().unwrap() diff --git a/crates/uplc/src/parser.rs b/crates/uplc/src/parser.rs index 87c97087..24c96e64 100644 --- a/crates/uplc/src/parser.rs +++ b/crates/uplc/src/parser.rs @@ -1,16 +1,13 @@ -use std::{ops::Neg, rc::Rc, str::FromStr}; - use crate::{ ast::{Constant, Name, Program, Term, Type}, builtins::DefaultFunction, - machine::runtime::Compressable, - machine::value::to_pallas_bigint, + machine::{runtime::Compressable, value::to_pallas_bigint}, }; - use interner::Interner; use num_bigint::BigInt; use pallas_primitives::alonzo::PlutusData; use peg::{error::ParseError, str::LineCol}; +use std::{ops::Neg, rc::Rc, str::FromStr}; pub mod interner; @@ -195,10 +192,10 @@ peg::parser! { = n:$(['0'..='9']+) {? n.parse().or(Err("usize")) } rule number() -> isize - = n:$("-"* ['0'..='9']+) {? n.parse().or(Err("isize")) } + = n:$(("-"/"+")* ['0'..='9']+) {? n.parse().or(Err("isize")) } rule big_number() -> BigInt - = n:$("-"* ['0'..='9']+) {? (if n.starts_with('-') { BigInt::parse_bytes(&n.as_bytes()[1..], 10).map(|i| i.neg()) } else { BigInt::parse_bytes(n.as_bytes(), 10) }).ok_or("BigInt") } + = n:$(("-"/"+")* ['0'..='9']+) {? (if n.starts_with('-') { BigInt::parse_bytes(&n.as_bytes()[1..], 10).map(|i| i.neg()) } else { BigInt::parse_bytes(n.as_bytes(), 10) }).ok_or("BigInt") } rule boolean() -> bool = b:$("True" / "False") { b == "True" } @@ -375,11 +372,12 @@ peg::parser! { #[cfg(test)] mod tests { + use crate::{ + ast::{Constant, Name, Program, Term, Type, Unique}, + builtins::DefaultFunction, + }; use num_bigint::BigInt; use pretty_assertions::assert_eq; - - use crate::ast::{Constant, Name, Program, Term, Type, Unique}; - use crate::builtins::DefaultFunction; use std::rc::Rc; #[test] diff --git a/crates/uplc/tests/conformance.rs b/crates/uplc/tests/conformance.rs index c75eda0f..7aca4897 100644 --- a/crates/uplc/tests/conformance.rs +++ b/crates/uplc/tests/conformance.rs @@ -94,8 +94,13 @@ fn plutus_conformance_tests(language: Language) { match eval { Ok((actual, cost)) => { pretty_assertions::assert_eq!(expected, Ok(actual), "{}", path.display()); - if let Ok(budget) = file_to_budget(&expected_budget_file) { - pretty_assertions::assert_eq!(budget, cost, "{}", path.display()); + match language { + Language::PlutusV1 | Language::PlutusV2 => {} + Language::PlutusV3 => { + if let Ok(budget) = file_to_budget(&expected_budget_file) { + pretty_assertions::assert_eq!(budget, cost, "{}", path.display()); + } + } } } Err(err) => pretty_assertions::assert_eq!(expected, Err(err), "{}", path.display()),