feat: introduce EvalResult type

This commit is contained in:
rvcas 2023-03-08 01:10:15 -05:00 committed by KtorZ
parent 4f1d14f2a0
commit bd7b8792bf
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
6 changed files with 63 additions and 79 deletions

View File

@ -4285,7 +4285,7 @@ impl<'a> CodeGenerator<'a> {
program.try_into().unwrap(); program.try_into().unwrap();
let evaluated_term: Term<NamedDeBruijn> = let evaluated_term: Term<NamedDeBruijn> =
eval_program.eval(ExBudget::default()).0.unwrap(); eval_program.eval(ExBudget::default()).result().unwrap();
arg_stack.push(evaluated_term.try_into().unwrap()); arg_stack.push(evaluated_term.try_into().unwrap());
anon_func = false; anon_func = false;
@ -5416,7 +5416,7 @@ impl<'a> CodeGenerator<'a> {
let eval_program: Program<NamedDeBruijn> = program.try_into().unwrap(); let eval_program: Program<NamedDeBruijn> = program.try_into().unwrap();
let evaluated_term: Term<NamedDeBruijn> = let evaluated_term: Term<NamedDeBruijn> =
eval_program.eval(ExBudget::default()).0.unwrap(); eval_program.eval(ExBudget::default()).result().unwrap();
term = evaluated_term.try_into().unwrap(); term = evaluated_term.try_into().unwrap();
} }

View File

@ -279,13 +279,13 @@ impl Diagnostic for Error {
None => None, None => None,
Some(hint) => { Some(hint) => {
let budget = ExBudget { mem: i64::MAX, cpu: i64::MAX, }; let budget = ExBudget { mem: i64::MAX, cpu: i64::MAX, };
let left = pretty::boxed("left", &match hint.left.eval(budget) { let left = pretty::boxed("left", &match hint.left.eval(budget).result() {
(Ok(term), _, _) => format!("{term}"), Ok(term) => format!("{term}"),
(Err(err), _, _) => format!("{err}"), Err(err) => format!("{err}"),
}); });
let right = pretty::boxed("right", &match hint.right.eval(budget) { let right = pretty::boxed("right", &match hint.right.eval(budget).result() {
(Ok(term), _, _) => format!("{term}"), Ok(term) => format!("{term}"),
(Err(err), _, _) => format!("{err}"), Err(err) => format!("{err}"),
}); });
let msg = match hint.bin_op { let msg = match hint.bin_op {
BinOp::And => Some(format!("{left}\n\nand\n\n{right}\n\nshould both be true.")), BinOp::And => Some(format!("{left}\n\nand\n\n{right}\n\nshould both be true.")),

View File

@ -37,7 +37,7 @@ use std::{
}; };
use telemetry::EventListener; use telemetry::EventListener;
use uplc::{ use uplc::{
ast::{Constant, DeBruijn, Term}, ast::{DeBruijn, Term},
machine::cost_model::ExBudget, machine::cost_model::ExBudget,
}; };
@ -726,22 +726,16 @@ where
scripts scripts
.into_par_iter() .into_par_iter()
.map(|script| match script.program.eval(initial_budget) { .map(|script| {
(Ok(result), remaining_budget, logs) => EvalInfo { let mut eval_result = script.program.eval(initial_budget);
success: result != Term::Error
&& result != Term::Constant(Constant::Bool(false).into()), EvalInfo {
success: !eval_result.failed(),
script, script,
spent_budget: initial_budget - remaining_budget, spent_budget: eval_result.cost(),
output: Some(result), logs: eval_result.logs(),
logs, output: eval_result.result().ok(),
}, }
(Err(..), remaining_budget, logs) => EvalInfo {
success: false,
script,
spent_budget: initial_budget - remaining_budget,
output: None,
logs,
},
}) })
.collect() .collect()
} }

View File

@ -24,6 +24,7 @@ use crate::{
flat::Binder, flat::Binder,
machine::{ machine::{
cost_model::{initialize_cost_model, CostModel, ExBudget}, cost_model::{initialize_cost_model, CostModel, ExBudget},
eval_result::EvalResult,
Machine, Machine,
}, },
}; };
@ -595,14 +596,7 @@ impl From<Term<FakeNamedDeBruijn>> for Term<NamedDeBruijn> {
} }
impl Program<NamedDeBruijn> { impl Program<NamedDeBruijn> {
pub fn eval( pub fn eval(&self, initial_budget: ExBudget) -> EvalResult {
&self,
initial_budget: ExBudget,
) -> (
Result<Term<NamedDeBruijn>, crate::machine::Error>,
ExBudget,
Vec<String>,
) {
let mut machine = Machine::new( let mut machine = Machine::new(
Language::PlutusV2, Language::PlutusV2,
CostModel::default(), CostModel::default(),
@ -612,22 +606,16 @@ impl Program<NamedDeBruijn> {
let term = machine.run(&self.term); let term = machine.run(&self.term);
(term, machine.ex_budget, machine.logs) EvalResult::new(term, machine.ex_budget, initial_budget, machine.logs)
} }
/// Evaluate a Program as PlutusV1 /// Evaluate a Program as PlutusV1
pub fn eval_v1( pub fn eval_v1(&self) -> EvalResult {
&self,
) -> (
Result<Term<NamedDeBruijn>, crate::machine::Error>,
ExBudget,
Vec<String>,
) {
let mut machine = Machine::new(Language::PlutusV1, CostModel::v1(), ExBudget::v1(), 200); let mut machine = Machine::new(Language::PlutusV1, CostModel::v1(), ExBudget::v1(), 200);
let term = machine.run(&self.term); let term = machine.run(&self.term);
(term, machine.ex_budget, machine.logs) EvalResult::new(term, machine.ex_budget, ExBudget::v1(), machine.logs)
} }
pub fn eval_as( pub fn eval_as(
@ -635,11 +623,7 @@ impl Program<NamedDeBruijn> {
version: &Language, version: &Language,
costs: &[i64], costs: &[i64],
initial_budget: Option<&ExBudget>, initial_budget: Option<&ExBudget>,
) -> ( ) -> EvalResult {
Result<Term<NamedDeBruijn>, crate::machine::Error>,
ExBudget,
Vec<String>,
) {
let budget = match initial_budget { let budget = match initial_budget {
Some(b) => *b, Some(b) => *b,
None => ExBudget::default(), None => ExBudget::default(),
@ -654,19 +638,12 @@ impl Program<NamedDeBruijn> {
let term = machine.run(&self.term); let term = machine.run(&self.term);
(term, machine.ex_budget, machine.logs) EvalResult::new(term, machine.ex_budget, budget, machine.logs)
} }
} }
impl Program<DeBruijn> { impl Program<DeBruijn> {
pub fn eval( pub fn eval(&self, initial_budget: ExBudget) -> EvalResult {
&self,
initial_budget: ExBudget,
) -> (
Result<Term<NamedDeBruijn>, crate::machine::Error>,
ExBudget,
Vec<String>,
) {
let program: Program<NamedDeBruijn> = self.clone().into(); let program: Program<NamedDeBruijn> = self.clone().into();
program.eval(initial_budget) program.eval(initial_budget)

View File

@ -8,6 +8,7 @@ use crate::{
pub mod cost_model; pub mod cost_model;
mod error; mod error;
pub mod eval_result;
pub mod runtime; pub mod runtime;
use cost_model::{ExBudget, StepKind}; use cost_model::{ExBudget, StepKind};
@ -785,9 +786,9 @@ mod tests {
}, },
}; };
let (eval_result, _, _) = program.eval(ExBudget::default()); let eval_result = program.eval(ExBudget::default());
let term = eval_result.unwrap(); let term = eval_result.result().unwrap();
assert_eq!( assert_eq!(
term, term,
@ -834,10 +835,10 @@ mod tests {
]; ];
for (fun, n, m, result) in test_data { for (fun, n, m, result) in test_data {
let (eval_result, _, _) = make_program(fun, n, m).eval(ExBudget::default()); let eval_result = make_program(fun, n, m).eval(ExBudget::default());
assert_eq!( assert_eq!(
eval_result.unwrap(), eval_result.result().unwrap(),
Term::Constant(Constant::Integer(result.into()).into()) Term::Constant(Constant::Integer(result.into()).into())
); );
} }

View File

@ -730,7 +730,7 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .apply_data(script_context.to_plutus_data());
let (result, budget, logs) = if let Some(cost_mdls) = cost_mdls_opt { let mut eval_result = if let Some(cost_mdls) = cost_mdls_opt {
let costs = if let Some(costs) = &cost_mdls.plutus_v1 { let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
costs costs
} else { } else {
@ -742,9 +742,12 @@ pub fn eval_redeemer(
program.eval_v1() program.eval_v1()
}; };
match result { let cost = eval_result.cost();
let logs = eval_result.logs();
match eval_result.result() {
Ok(_) => (), Ok(_) => (),
Err(err) => return Err(Error::Machine(err, budget, logs)), Err(err) => return Err(Error::Machine(err, cost, logs)),
} }
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
@ -752,8 +755,8 @@ pub fn eval_redeemer(
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (initial_budget.mem - budget.mem) as u32, mem: cost.mem as u32,
steps: (initial_budget.cpu - budget.cpu) as u64, steps: cost.cpu as u64,
}, },
}; };
@ -776,7 +779,7 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .apply_data(script_context.to_plutus_data());
let (result, budget, logs) = if let Some(cost_mdls) = cost_mdls_opt { let mut eval_result = if let Some(cost_mdls) = cost_mdls_opt {
let costs = if let Some(costs) = &cost_mdls.plutus_v2 { let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
costs costs
} else { } else {
@ -788,9 +791,12 @@ pub fn eval_redeemer(
program.eval(ExBudget::default()) program.eval(ExBudget::default())
}; };
match result { let cost = eval_result.cost();
let logs = eval_result.logs();
match eval_result.result() {
Ok(_) => (), Ok(_) => (),
Err(err) => return Err(Error::Machine(err, budget, logs)), Err(err) => return Err(Error::Machine(err, cost, logs)),
} }
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
@ -798,8 +804,8 @@ pub fn eval_redeemer(
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (initial_budget.mem - budget.mem) as u32, mem: cost.mem as u32,
steps: (initial_budget.cpu - budget.cpu) as u64, steps: cost.cpu as u64,
}, },
}; };
@ -824,7 +830,7 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .apply_data(script_context.to_plutus_data());
let (result, budget, logs) = if let Some(cost_mdls) = cost_mdls_opt { let mut eval_result = if let Some(cost_mdls) = cost_mdls_opt {
let costs = if let Some(costs) = &cost_mdls.plutus_v1 { let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
costs costs
} else { } else {
@ -836,9 +842,12 @@ pub fn eval_redeemer(
program.eval_v1() program.eval_v1()
}; };
match result { let cost = eval_result.cost();
let logs = eval_result.logs();
match eval_result.result() {
Ok(_) => (), Ok(_) => (),
Err(err) => return Err(Error::Machine(err, budget, logs)), Err(err) => return Err(Error::Machine(err, cost, logs)),
} }
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
@ -846,8 +855,8 @@ pub fn eval_redeemer(
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (initial_budget.mem - budget.mem) as u32, mem: cost.mem as u32,
steps: (initial_budget.cpu - budget.cpu) as u64, steps: cost.cpu as u64,
}, },
}; };
@ -869,7 +878,7 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .apply_data(script_context.to_plutus_data());
let (result, budget, logs) = if let Some(cost_mdls) = cost_mdls_opt { let mut eval_result = if let Some(cost_mdls) = cost_mdls_opt {
let costs = if let Some(costs) = &cost_mdls.plutus_v2 { let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
costs costs
} else { } else {
@ -881,9 +890,12 @@ pub fn eval_redeemer(
program.eval(ExBudget::default()) program.eval(ExBudget::default())
}; };
match result { let cost = eval_result.cost();
let logs = eval_result.logs();
match eval_result.result() {
Ok(_) => (), Ok(_) => (),
Err(err) => return Err(Error::Machine(err, budget, logs)), Err(err) => return Err(Error::Machine(err, cost, logs)),
} }
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
@ -891,8 +903,8 @@ pub fn eval_redeemer(
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (initial_budget.mem - budget.mem) as u32, mem: cost.mem as u32,
steps: (initial_budget.cpu - budget.cpu) as u64, steps: cost.cpu as u64,
}, },
}; };