A few more left to finish
This commit is contained in:
parent
c3b6bc5bff
commit
9867de38b6
|
@ -2538,8 +2538,8 @@ impl BuiltinCosts {
|
||||||
.cpu
|
.cpu
|
||||||
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
},
|
},
|
||||||
DefaultFunction::IntegerToByteString => {
|
d @ DefaultFunction::IntegerToByteString => {
|
||||||
let size = args[1].cost_as_size()?;
|
let size = args[1].cost_as_size(d)?;
|
||||||
|
|
||||||
ExBudget {
|
ExBudget {
|
||||||
mem: self.integer_to_byte_string.mem.cost(
|
mem: self.integer_to_byte_string.mem.cost(
|
||||||
|
@ -2630,8 +2630,8 @@ impl BuiltinCosts {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultFunction::ReplicateByte => {
|
d @ DefaultFunction::ReplicateByte => {
|
||||||
let size = args[0].cost_as_size()?;
|
let size = args[0].cost_as_size(d)?;
|
||||||
|
|
||||||
ExBudget {
|
ExBudget {
|
||||||
mem: self.replicate_byte.mem.cost(size, args[1].to_ex_mem()),
|
mem: self.replicate_byte.mem.cost(size, args[1].to_ex_mem()),
|
||||||
|
|
|
@ -120,10 +120,14 @@ pub enum Error {
|
||||||
DeserialisationError(String, Value),
|
DeserialisationError(String, Value),
|
||||||
#[error("integer overflow")]
|
#[error("integer overflow")]
|
||||||
OverflowError,
|
OverflowError,
|
||||||
#[error("{0} is not within the bounds of Natural")]
|
#[error("{0} is not within the bounds of a Natural")]
|
||||||
OutsideNaturalBounds(BigInt),
|
OutsideNaturalBounds(BigInt),
|
||||||
|
#[error("{0} is not within the bounds of a Byte")]
|
||||||
|
OutsideByteBounds(BigInt),
|
||||||
#[error("readBit: index out of bounds")]
|
#[error("readBit: index out of bounds")]
|
||||||
ReadBitOutOfBounds,
|
ReadBitOutOfBounds,
|
||||||
|
#[error("writeBits: index out of bounds")]
|
||||||
|
WriteBitsOutOfBounds,
|
||||||
#[error("blst error {0:?}")]
|
#[error("blst error {0:?}")]
|
||||||
Blst(blst::BLST_ERROR),
|
Blst(blst::BLST_ERROR),
|
||||||
#[error("blst::hashToGroup")]
|
#[error("blst::hashToGroup")]
|
||||||
|
|
|
@ -10,12 +10,12 @@ use crate::{
|
||||||
plutus_data_to_bytes,
|
plutus_data_to_bytes,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use num_bigint::BigInt;
|
use num_bigint::{BigInt, Sign};
|
||||||
use num_integer::Integer;
|
use num_integer::Integer;
|
||||||
use num_traits::{Signed, Zero};
|
use num_traits::{FromPrimitive, Signed, Zero};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use pallas_primitives::conway::{Language, PlutusData};
|
use pallas_primitives::conway::{Language, PlutusData};
|
||||||
use std::{mem::size_of, ops::Deref, rc::Rc};
|
use std::{io::Read, mem::size_of, ops::Deref, rc::Rc};
|
||||||
|
|
||||||
static SCALAR_PERIOD: Lazy<BigInt> = Lazy::new(|| {
|
static SCALAR_PERIOD: Lazy<BigInt> = Lazy::new(|| {
|
||||||
BigInt::from_bytes_be(
|
BigInt::from_bytes_be(
|
||||||
|
@ -1522,7 +1522,7 @@ impl DefaultFunction {
|
||||||
.collect_vec()
|
.collect_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Value::Con(Constant::ByteString(bytes_result).into()))
|
Ok(Value::byte_string(bytes_result))
|
||||||
}
|
}
|
||||||
DefaultFunction::OrByteString => {
|
DefaultFunction::OrByteString => {
|
||||||
let should_pad = args[0].unwrap_bool()?;
|
let should_pad = args[0].unwrap_bool()?;
|
||||||
|
@ -1550,7 +1550,7 @@ impl DefaultFunction {
|
||||||
.collect_vec()
|
.collect_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Value::Con(Constant::ByteString(bytes_result).into()))
|
Ok(Value::byte_string(bytes_result))
|
||||||
}
|
}
|
||||||
DefaultFunction::XorByteString => {
|
DefaultFunction::XorByteString => {
|
||||||
let should_pad = args[0].unwrap_bool()?;
|
let should_pad = args[0].unwrap_bool()?;
|
||||||
|
@ -1578,14 +1578,14 @@ impl DefaultFunction {
|
||||||
.collect_vec()
|
.collect_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Value::Con(Constant::ByteString(bytes_result).into()))
|
Ok(Value::byte_string(bytes_result))
|
||||||
}
|
}
|
||||||
DefaultFunction::ComplementByteString => {
|
DefaultFunction::ComplementByteString => {
|
||||||
let bytes = args[0].unwrap_byte_string()?;
|
let bytes = args[0].unwrap_byte_string()?;
|
||||||
|
|
||||||
let result = bytes.into_iter().map(|b| b ^ 255).collect_vec();
|
let result = bytes.into_iter().map(|b| b ^ 255).collect_vec();
|
||||||
|
|
||||||
Ok(Value::Con(Constant::ByteString(result).into()))
|
Ok(Value::byte_string(result))
|
||||||
}
|
}
|
||||||
DefaultFunction::ReadBit => {
|
DefaultFunction::ReadBit => {
|
||||||
let bytes = args[0].unwrap_byte_string()?;
|
let bytes = args[0].unwrap_byte_string()?;
|
||||||
|
@ -1606,11 +1606,88 @@ impl DefaultFunction {
|
||||||
|
|
||||||
let bit_test = (byte >> bit_offset) & 1 == 1;
|
let bit_test = (byte >> bit_offset) & 1 == 1;
|
||||||
|
|
||||||
Ok(Value::Con(Constant::Bool(bit_test).into()))
|
Ok(Value::bool(bit_test))
|
||||||
|
}
|
||||||
|
DefaultFunction::WriteBits => {
|
||||||
|
let mut bytes = args[0].unwrap_byte_string()?.clone();
|
||||||
|
let indices = args[1].unwrap_int_list()?;
|
||||||
|
let set_bit = args[2].unwrap_bool()?;
|
||||||
|
|
||||||
|
for index in indices {
|
||||||
|
let Constant::Integer(bit_index) = index else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
if *bit_index < 0.into() || *bit_index >= (bytes.len() * 8).into() {
|
||||||
|
return Err(Error::WriteBitsOutOfBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (byte_index, bit_offset) = bit_index.div_rem(&8.into());
|
||||||
|
|
||||||
|
let bit_offset = usize::try_from(bit_offset).unwrap();
|
||||||
|
|
||||||
|
let flipped_index = bytes.len() - 1 - usize::try_from(byte_index).unwrap();
|
||||||
|
|
||||||
|
let bit_mask: u8 = 1 >> bit_offset;
|
||||||
|
|
||||||
|
if *set_bit {
|
||||||
|
bytes[flipped_index] |= bit_mask;
|
||||||
|
} else {
|
||||||
|
bytes[flipped_index] &= !bit_mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::byte_string(bytes))
|
||||||
|
}
|
||||||
|
DefaultFunction::ReplicateByte => {
|
||||||
|
let size = args[0].unwrap_integer()?;
|
||||||
|
let byte = args[1].unwrap_integer()?;
|
||||||
|
|
||||||
|
// Safe since this is checked by cost model
|
||||||
|
let size = usize::try_from(size).unwrap();
|
||||||
|
|
||||||
|
let Ok(byte) = u8::try_from(byte) else {
|
||||||
|
return Err(Error::OutsideByteBounds(byte.clone()));
|
||||||
|
};
|
||||||
|
|
||||||
|
let value = if size == 0 {
|
||||||
|
Value::byte_string(vec![])
|
||||||
|
} else {
|
||||||
|
Value::byte_string([byte].repeat(size - 1))
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
DefaultFunction::ShiftByteString => {
|
||||||
|
let bytes = args[0].unwrap_byte_string()?;
|
||||||
|
let shift = args[1].unwrap_integer()?;
|
||||||
|
|
||||||
|
let byte_length = bytes.len();
|
||||||
|
|
||||||
|
if BigInt::from_usize(byte_length).unwrap() * 8 < shift.abs() {
|
||||||
|
let mut new_vec = vec![];
|
||||||
|
|
||||||
|
new_vec.resize(byte_length, 0);
|
||||||
|
return Ok(Value::byte_string(new_vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes = BigInt::from_bytes_be(Sign::NoSign, bytes);
|
||||||
|
|
||||||
|
let is_shl = shift >= &0.into();
|
||||||
|
|
||||||
|
let bytes = if is_shl {
|
||||||
|
bytes << usize::try_from(shift.abs()).unwrap()
|
||||||
|
} else {
|
||||||
|
bytes >> usize::try_from(shift.abs()).unwrap()
|
||||||
|
}
|
||||||
|
.to_bytes_be()
|
||||||
|
.1
|
||||||
|
.into_iter()
|
||||||
|
.take(byte_length)
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
Ok(Value::byte_string(bytes))
|
||||||
}
|
}
|
||||||
DefaultFunction::WriteBits => todo!(),
|
|
||||||
DefaultFunction::ReplicateByte => todo!(),
|
|
||||||
DefaultFunction::ShiftByteString => todo!(),
|
|
||||||
DefaultFunction::RotateByteString => todo!(),
|
DefaultFunction::RotateByteString => todo!(),
|
||||||
DefaultFunction::CountSetBits => todo!(),
|
DefaultFunction::CountSetBits => todo!(),
|
||||||
DefaultFunction::FindFirstSetBit => todo!(),
|
DefaultFunction::FindFirstSetBit => todo!(),
|
||||||
|
|
|
@ -173,6 +173,19 @@ impl Value {
|
||||||
Ok(list)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn unwrap_int_list(&self) -> Result<&Vec<Constant>, Error> {
|
||||||
|
let inner = self.unwrap_constant()?;
|
||||||
|
|
||||||
|
let Constant::ProtoList(Type::Integer, list) = inner else {
|
||||||
|
return Err(Error::TypeMismatch(
|
||||||
|
Type::List(Type::Integer.into()),
|
||||||
|
inner.into(),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(list)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn unwrap_bls12_381_g1_element(&self) -> Result<&blst::blst_p1, Error> {
|
pub(super) fn unwrap_bls12_381_g1_element(&self) -> Result<&blst::blst_p1, Error> {
|
||||||
let inner = self.unwrap_constant()?;
|
let inner = self.unwrap_constant()?;
|
||||||
|
|
||||||
|
@ -211,18 +224,30 @@ impl Value {
|
||||||
matches!(self, Value::Con(b) if matches!(b.as_ref(), Constant::Bool(_)))
|
matches!(self, Value::Con(b) if matches!(b.as_ref(), Constant::Bool(_)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cost_as_size(&self) -> Result<i64, Error> {
|
pub fn cost_as_size(&self, func: DefaultFunction) -> Result<i64, Error> {
|
||||||
let size = self.unwrap_integer()?;
|
let size = self.unwrap_integer()?;
|
||||||
|
|
||||||
if size.is_negative() {
|
if size.is_negative() {
|
||||||
return Err(Error::IntegerToByteStringNegativeSize(size.clone()));
|
let error = match func {
|
||||||
|
DefaultFunction::IntegerToByteString => {
|
||||||
|
Error::IntegerToByteStringNegativeSize(size.clone())
|
||||||
|
}
|
||||||
|
DefaultFunction::ReplicateByte => todo!(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
return Err(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if size > &BigInt::from(runtime::INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH) {
|
if size > &BigInt::from(runtime::INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH) {
|
||||||
return Err(Error::IntegerToByteStringSizeTooBig(
|
let error = match func {
|
||||||
size.clone(),
|
DefaultFunction::IntegerToByteString => Error::IntegerToByteStringSizeTooBig(
|
||||||
runtime::INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH,
|
size.clone(),
|
||||||
));
|
runtime::INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH,
|
||||||
|
),
|
||||||
|
DefaultFunction::ReplicateByte => todo!(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
return Err(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
let arg1: i64 = u64::try_from(size).unwrap().try_into().unwrap();
|
let arg1: i64 = u64::try_from(size).unwrap().try_into().unwrap();
|
||||||
|
|
Loading…
Reference in New Issue