add a data builtin and do ex_mem for pairs, list, data

This commit is contained in:
Kasey White
2022-08-26 00:21:18 -04:00
committed by Kasey White
parent 45e22c1ea8
commit 73e367ad53
9 changed files with 133 additions and 37 deletions

View File

@@ -16,7 +16,7 @@ exclude = ["test_data/*"]
cryptoxide = "0.4.2"
flat-rs = { path = "../flat", version = "0.0.10" }
hex = "0.4.3"
minicbor = { version = "0.18.0", features = ["std"] }
minicbor = { version = "0.17.1", features = ["std"] }
pallas-primitives = "0.12.0"
peg = "0.8.0"
pretty = "0.11.3"

View File

@@ -6,3 +6,10 @@ pub mod machine;
pub mod parser;
mod pretty;
pub mod program_builder;
pub use pallas_primitives::alonzo::PlutusData;
use pallas_primitives::Fragment;
pub fn plutus_data(bytes: &[u8]) -> PlutusData {
PlutusData::decode_fragment(bytes).unwrap()
}

View File

@@ -1,4 +1,4 @@
use std::rc::Rc;
use std::{collections::VecDeque, ops::Deref, rc::Rc};
use crate::{
ast::{Constant, NamedDeBruijn, Term, Type},
@@ -11,6 +11,7 @@ mod runtime;
use cost_model::{ExBudget, StepKind};
pub use error::Error;
use pallas_primitives::babbage::{BigInt, PlutusData};
use self::{cost_model::CostModel, runtime::BuiltinRuntime};
@@ -436,6 +437,7 @@ impl Value {
matches!(self, Value::Con(Constant::Bool(_)))
}
// TODO: Make this to_ex_mem not recursive.
pub fn to_ex_mem(&self) -> i64 {
match self {
Value::Con(c) => match c {
@@ -453,8 +455,10 @@ impl Value {
Constant::ProtoList(_, items) => items.iter().fold(0, |acc, constant| {
acc + Value::Con(constant.clone()).to_ex_mem()
}),
Constant::ProtoPair(_, _, _, _) => todo!(),
Constant::Data(_) => todo!(),
Constant::ProtoPair(_, _, l, r) => {
Value::Con(*l.clone()).to_ex_mem() + Value::Con(*r.clone()).to_ex_mem()
}
Constant::Data(item) => self.data_to_ex_mem(item),
},
Value::Delay(_, _) => 1,
Value::Lambda { .. } => 1,
@@ -462,6 +466,70 @@ impl Value {
}
}
// I made data not recursive since data tends to be deeply nested
// thus causing a significant hit on performance
pub fn data_to_ex_mem(&self, data: &PlutusData) -> i64 {
let mut stack: VecDeque<&PlutusData> = VecDeque::new();
let mut total = 0;
stack.push_front(data);
while let Some(item) = stack.pop_front() {
// each time we deconstruct a data we add 4 memory units
total += 4;
match item {
PlutusData::Constr(c) => {
// note currently tag is not factored into cost of memory
// create new stack with of items from the list of data
let mut new_stack: VecDeque<&PlutusData> =
VecDeque::from_iter(c.fields.deref().iter());
// Append old stack to the back of the new stack
new_stack.append(&mut stack);
stack = new_stack;
}
PlutusData::Map(m) => {
let mut new_stack: VecDeque<&PlutusData>;
// create new stack with of items from the list of pairs of data
new_stack = m.deref().iter().fold(VecDeque::new(), |mut acc, d| {
acc.push_back(&d.0);
acc.push_back(&d.1);
acc
});
// Append old stack to the back of the new stack
new_stack.append(&mut stack);
stack = new_stack;
}
PlutusData::BigInt(i) => {
if let BigInt::Int(g) = i {
let numb: i64 = (*g).try_into().unwrap();
total += Value::Con(Constant::Integer(numb as isize)).to_ex_mem();
} else {
unreachable!()
};
}
PlutusData::BoundedBytes(b) => {
let byte_string: Vec<u8> = b.deref().clone();
total += Value::Con(Constant::ByteString(byte_string)).to_ex_mem();
}
PlutusData::Array(a) => {
// create new stack with of items from the list of data
let mut new_stack: VecDeque<&PlutusData> =
VecDeque::from_iter(a.deref().iter());
// Append old stack to the back of the new stack
new_stack.append(&mut stack);
stack = new_stack;
}
PlutusData::ArrayIndef(a) => {
// create new stack with of items from the list of data
let mut new_stack: VecDeque<&PlutusData> =
VecDeque::from_iter(a.deref().iter());
// Append old stack to the back of the new stack
new_stack.append(&mut stack);
stack = new_stack;
}
}
}
total
}
pub fn expect_type(&self, r#type: Type) -> Result<(), Error> {
let constant: Constant = self.clone().try_into()?;
@@ -522,7 +590,7 @@ impl From<&Constant> for Type {
Constant::ProtoPair(t1, t2, _, _) => {
Type::Pair(Box::new(t1.clone()), Box::new(t2.clone()))
}
Constant::Data(_) => todo!(),
Constant::Data(_) => Type::Data,
}
}
}

View File

@@ -825,7 +825,10 @@ impl BuiltinCosts {
DefaultFunction::ListData => todo!(),
DefaultFunction::IData => todo!(),
DefaultFunction::BData => todo!(),
DefaultFunction::UnConstrData => todo!(),
DefaultFunction::UnConstrData => ExBudget {
mem: self.un_constr_data.mem.cost(args[0].to_ex_mem()),
cpu: self.un_constr_data.cpu.cost(args[0].to_ex_mem()),
},
DefaultFunction::UnMapData => todo!(),
DefaultFunction::UnListData => todo!(),
DefaultFunction::UnIData => todo!(),

View File

@@ -1,3 +1,7 @@
use std::ops::Deref;
use pallas_primitives::babbage::PlutusData;
use crate::{
ast::{Constant, Type},
builtins::DefaultFunction,
@@ -116,7 +120,7 @@ impl DefaultFunction {
DefaultFunction::ListData => todo!(),
DefaultFunction::IData => todo!(),
DefaultFunction::BData => todo!(),
DefaultFunction::UnConstrData => todo!(),
DefaultFunction::UnConstrData => 1,
DefaultFunction::UnMapData => todo!(),
DefaultFunction::UnListData => todo!(),
DefaultFunction::UnIData => todo!(),
@@ -175,7 +179,7 @@ impl DefaultFunction {
DefaultFunction::ListData => todo!(),
DefaultFunction::IData => todo!(),
DefaultFunction::BData => todo!(),
DefaultFunction::UnConstrData => todo!(),
DefaultFunction::UnConstrData => 0,
DefaultFunction::UnMapData => todo!(),
DefaultFunction::UnListData => todo!(),
DefaultFunction::UnIData => todo!(),
@@ -278,7 +282,7 @@ impl DefaultFunction {
DefaultFunction::ListData => todo!(),
DefaultFunction::IData => todo!(),
DefaultFunction::BData => todo!(),
DefaultFunction::UnConstrData => todo!(),
DefaultFunction::UnConstrData => arg.expect_type(Type::Data),
DefaultFunction::UnMapData => todo!(),
DefaultFunction::UnListData => todo!(),
DefaultFunction::UnIData => todo!(),
@@ -625,7 +629,24 @@ impl DefaultFunction {
DefaultFunction::ListData => todo!(),
DefaultFunction::IData => todo!(),
DefaultFunction::BData => todo!(),
DefaultFunction::UnConstrData => todo!(),
DefaultFunction::UnConstrData => match &args[0] {
Value::Con(Constant::Data(PlutusData::Constr(c))) => {
Ok(Value::Con(Constant::ProtoPair(
Type::Integer,
Type::List(Box::new(Type::Data)),
Box::new(Constant::Integer(c.tag as isize)),
Box::new(Constant::ProtoList(
Type::Data,
c.fields
.deref()
.iter()
.map(|d| Constant::Data(d.clone()))
.collect(),
)),
)))
}
_ => unreachable!(),
},
DefaultFunction::UnMapData => todo!(),
DefaultFunction::UnListData => todo!(),
DefaultFunction::UnIData => todo!(),

View File

@@ -185,7 +185,22 @@ impl Constant {
RcDoc::text(","),
))
.append(RcDoc::text("]")),
Constant::ProtoPair(_, _, _, _) => todo!(),
Constant::ProtoPair(r#type1, r#type2, left, right) => RcDoc::text("(")
.append(
RcDoc::text("pair")
.append(RcDoc::line())
.append(r#type1.to_doc())
.append(RcDoc::line())
.append(r#type2.to_doc()),
)
.append(RcDoc::line_())
.append(RcDoc::text(")"))
.append(RcDoc::line())
.append(RcDoc::text("("))
.append(left.to_doc_list())
.append(RcDoc::text(","))
.append(right.to_doc_list())
.append(RcDoc::text(")")),
Constant::Data(_) => todo!(),
}
}
@@ -206,7 +221,7 @@ impl Constant {
))
.append(RcDoc::text("]")),
Constant::ProtoPair(_, _, _, _) => todo!(),
Constant::Data(_) => todo!(),
Constant::Data(data) => RcDoc::text("todo"),
}
}
}
@@ -228,7 +243,7 @@ impl Type {
.append(RcDoc::line_())
.append(RcDoc::text(")")),
Type::Pair(_, _) => todo!(),
Type::Data => todo!(),
Type::Data => RcDoc::text("data"),
}
}
}