A few more left to finish
This commit is contained in:
parent
c3b6bc5bff
commit
9867de38b6
|
@ -2538,8 +2538,8 @@ impl BuiltinCosts {
|
|||
.cpu
|
||||
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||
},
|
||||
DefaultFunction::IntegerToByteString => {
|
||||
let size = args[1].cost_as_size()?;
|
||||
d @ DefaultFunction::IntegerToByteString => {
|
||||
let size = args[1].cost_as_size(d)?;
|
||||
|
||||
ExBudget {
|
||||
mem: self.integer_to_byte_string.mem.cost(
|
||||
|
@ -2630,8 +2630,8 @@ impl BuiltinCosts {
|
|||
),
|
||||
}
|
||||
}
|
||||
DefaultFunction::ReplicateByte => {
|
||||
let size = args[0].cost_as_size()?;
|
||||
d @ DefaultFunction::ReplicateByte => {
|
||||
let size = args[0].cost_as_size(d)?;
|
||||
|
||||
ExBudget {
|
||||
mem: self.replicate_byte.mem.cost(size, args[1].to_ex_mem()),
|
||||
|
|
|
@ -120,10 +120,14 @@ pub enum Error {
|
|||
DeserialisationError(String, Value),
|
||||
#[error("integer overflow")]
|
||||
OverflowError,
|
||||
#[error("{0} is not within the bounds of Natural")]
|
||||
#[error("{0} is not within the bounds of a Natural")]
|
||||
OutsideNaturalBounds(BigInt),
|
||||
#[error("{0} is not within the bounds of a Byte")]
|
||||
OutsideByteBounds(BigInt),
|
||||
#[error("readBit: index out of bounds")]
|
||||
ReadBitOutOfBounds,
|
||||
#[error("writeBits: index out of bounds")]
|
||||
WriteBitsOutOfBounds,
|
||||
#[error("blst error {0:?}")]
|
||||
Blst(blst::BLST_ERROR),
|
||||
#[error("blst::hashToGroup")]
|
||||
|
|
|
@ -10,12 +10,12 @@ use crate::{
|
|||
plutus_data_to_bytes,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use num_bigint::BigInt;
|
||||
use num_bigint::{BigInt, Sign};
|
||||
use num_integer::Integer;
|
||||
use num_traits::{Signed, Zero};
|
||||
use num_traits::{FromPrimitive, Signed, Zero};
|
||||
use once_cell::sync::Lazy;
|
||||
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(|| {
|
||||
BigInt::from_bytes_be(
|
||||
|
@ -1522,7 +1522,7 @@ impl DefaultFunction {
|
|||
.collect_vec()
|
||||
};
|
||||
|
||||
Ok(Value::Con(Constant::ByteString(bytes_result).into()))
|
||||
Ok(Value::byte_string(bytes_result))
|
||||
}
|
||||
DefaultFunction::OrByteString => {
|
||||
let should_pad = args[0].unwrap_bool()?;
|
||||
|
@ -1550,7 +1550,7 @@ impl DefaultFunction {
|
|||
.collect_vec()
|
||||
};
|
||||
|
||||
Ok(Value::Con(Constant::ByteString(bytes_result).into()))
|
||||
Ok(Value::byte_string(bytes_result))
|
||||
}
|
||||
DefaultFunction::XorByteString => {
|
||||
let should_pad = args[0].unwrap_bool()?;
|
||||
|
@ -1578,14 +1578,14 @@ impl DefaultFunction {
|
|||
.collect_vec()
|
||||
};
|
||||
|
||||
Ok(Value::Con(Constant::ByteString(bytes_result).into()))
|
||||
Ok(Value::byte_string(bytes_result))
|
||||
}
|
||||
DefaultFunction::ComplementByteString => {
|
||||
let bytes = args[0].unwrap_byte_string()?;
|
||||
|
||||
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 => {
|
||||
let bytes = args[0].unwrap_byte_string()?;
|
||||
|
@ -1606,11 +1606,88 @@ impl DefaultFunction {
|
|||
|
||||
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::CountSetBits => todo!(),
|
||||
DefaultFunction::FindFirstSetBit => todo!(),
|
||||
|
|
|
@ -173,6 +173,19 @@ impl Value {
|
|||
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> {
|
||||
let inner = self.unwrap_constant()?;
|
||||
|
||||
|
@ -211,18 +224,30 @@ impl Value {
|
|||
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()?;
|
||||
|
||||
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) {
|
||||
return Err(Error::IntegerToByteStringSizeTooBig(
|
||||
size.clone(),
|
||||
runtime::INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH,
|
||||
));
|
||||
let error = match func {
|
||||
DefaultFunction::IntegerToByteString => Error::IntegerToByteStringSizeTooBig(
|
||||
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();
|
||||
|
|
Loading…
Reference in New Issue