Avoid wiping out traces when accessing logs

The clones are cheap enough here that we likely don't need to worry about the cost of cloning; and this removes a significant foot-gun where you can wipe out the logs/labels by accessing the other field.
This commit is contained in:
Pi Lanningham 2025-02-17 15:55:33 -05:00 committed by Lucas
parent 8115443990
commit 4adf6f27ad
4 changed files with 16 additions and 14 deletions

View File

@ -222,7 +222,7 @@ unsafe impl Send for UnitTest {}
impl UnitTest { impl UnitTest {
pub fn run(self, plutus_version: &PlutusVersion) -> UnitTestResult<(Constant, Rc<Type>)> { pub fn run(self, plutus_version: &PlutusVersion) -> UnitTestResult<(Constant, Rc<Type>)> {
let mut eval_result = Program::<NamedDeBruijn>::try_from(self.program.clone()) let eval_result = Program::<NamedDeBruijn>::try_from(self.program.clone())
.unwrap() .unwrap()
.eval_version(ExBudget::max(), &plutus_version.into()); .eval_version(ExBudget::max(), &plutus_version.into());
@ -384,7 +384,7 @@ impl PropertyTest {
.sample(&self.fuzzer.program)? .sample(&self.fuzzer.program)?
.expect("A seeded PRNG returned 'None' which indicates a fuzzer is ill-formed and implemented wrongly; please contact library's authors."); .expect("A seeded PRNG returned 'None' which indicates a fuzzer is ill-formed and implemented wrongly; please contact library's authors.");
let mut result = self.eval(&value, plutus_version); let result = self.eval(&value, plutus_version);
for label in result.labels() { for label in result.labels() {
// NOTE: There may be other log outputs that interefere with labels. So *by // NOTE: There may be other log outputs that interefere with labels. So *by
@ -536,7 +536,7 @@ impl Benchmark {
Ok(Some((new_prng, value))) => { Ok(Some((new_prng, value))) => {
prng = new_prng; prng = new_prng;
let mut result = self.eval(&value, plutus_version); let result = self.eval(&value, plutus_version);
match result.result() { match result.result() {
Ok(_) => measures.push((size, result.cost())), Ok(_) => measures.push((size, result.cost())),
Err(uplc_error) => { Err(uplc_error) => {
@ -664,7 +664,7 @@ impl Prng {
fuzzer: &Program<Name>, fuzzer: &Program<Name>,
) -> Result<Option<(Prng, PlutusData)>, FuzzerError> { ) -> Result<Option<(Prng, PlutusData)>, FuzzerError> {
let program = Program::<NamedDeBruijn>::try_from(fuzzer.apply_data(self.uplc())).unwrap(); let program = Program::<NamedDeBruijn>::try_from(fuzzer.apply_data(self.uplc())).unwrap();
let mut result = program.eval(ExBudget::max()); let result = program.eval(ExBudget::max());
result result
.result() .result()
.map_err(|uplc_error| FuzzerError { .map_err(|uplc_error| FuzzerError {

View File

@ -77,7 +77,7 @@ pub fn exec(
let program = Program::<NamedDeBruijn>::try_from(program).into_diagnostic()?; let program = Program::<NamedDeBruijn>::try_from(program).into_diagnostic()?;
let mut eval_result = if debug { let eval_result = if debug {
program.eval_debug(ExBudget::default(), &Language::PlutusV3) program.eval_debug(ExBudget::default(), &Language::PlutusV3)
} else { } else {
program.eval(budget) program.eval(budget)

View File

@ -31,20 +31,22 @@ impl EvalResult {
self.initial_budget - self.remaining_budget self.initial_budget - self.remaining_budget
} }
pub fn traces(&mut self) -> Vec<Trace> { pub fn traces(&self) -> Vec<Trace> {
std::mem::take(&mut self.traces) self.traces.clone()
} }
pub fn logs(&mut self) -> Vec<String> { pub fn logs(&self) -> Vec<String> {
std::mem::take(&mut self.traces) self.traces
.into_iter() .iter()
.cloned()
.filter_map(Trace::unwrap_log) .filter_map(Trace::unwrap_log)
.collect() .collect()
} }
pub fn labels(&mut self) -> Vec<String> { pub fn labels(&self) -> Vec<String> {
std::mem::take(&mut self.traces) self.traces
.into_iter() .iter()
.cloned()
.filter_map(Trace::unwrap_label) .filter_map(Trace::unwrap_label)
.collect() .collect()
} }

View File

@ -49,7 +49,7 @@ pub fn eval_redeemer(
ScriptContext::V3 { .. } => program.apply_data(script_context.to_plutus_data()), ScriptContext::V3 { .. } => program.apply_data(script_context.to_plutus_data()),
}; };
let mut eval_result = if let Some(costs) = cost_mdl_opt { let eval_result = if let Some(costs) = cost_mdl_opt {
program.eval_as(lang, costs, Some(initial_budget)) program.eval_as(lang, costs, Some(initial_budget))
} else { } else {
program.eval_version(ExBudget::default(), lang) program.eval_version(ExBudget::default(), lang)