Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 2 additions & 84 deletions fuzz/fuzz_targets/regression_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,6 @@

#![cfg_attr(fuzzing, no_main)]

#[cfg(any(fuzzing, test))]
use std::sync::Arc;

#[cfg(any(fuzzing, test))]
use old_simplicity::{types::Final as OldFinal, Value as OldValue};
#[cfg(any(fuzzing, test))]
use simplicity::types::Final;

#[cfg(any(fuzzing, test))]
fn convert_ty(new: &Final) -> Option<Arc<OldFinal>> {
/// Our stack of tasks describing “what we need to do next.”
enum Task<'a> {
/// Convert this `Final` into an `OldFinal`.
NeedType(&'a Final),
Binary {
is_sum: bool,
dupe: bool,
},
}

// We'll push tasks onto this stack until everything is converted.
let mut task_stack = vec![Task::NeedType(new)];
// As we finish conversion of subtrees, we store them here along with
// a count of units. Because the released version of 0.3.0 does not
// have any typeskip optimization we need to bail out if there are
// too many units, since otherwise we will OOM in from_compact_bits.
let mut result_stack: Vec<(usize, Arc<OldFinal>)> = vec![];
const MAX_UNITS: usize = 1024 * 1024;

// Process tasks in LIFO order
while let Some(task) = task_stack.pop() {
match task {
Task::NeedType(final_ty) => {
if final_ty.is_unit() {
result_stack.push((1, OldFinal::unit()));
} else if let Some((left, right)) = final_ty.as_sum() {
let dupe = Arc::ptr_eq(left, right);
task_stack.push(Task::Binary { is_sum: true, dupe });
if !dupe {
task_stack.push(Task::NeedType(right));
}
task_stack.push(Task::NeedType(left));
} else if let Some((left, right)) = final_ty.as_product() {
let dupe = Arc::ptr_eq(left, right);
task_stack.push(Task::Binary {
is_sum: false,
dupe,
});
if !dupe {
task_stack.push(Task::NeedType(right));
}
task_stack.push(Task::NeedType(left));
} else {
unreachable!();
}
}
Task::Binary { is_sum, dupe } => {
let right = result_stack.pop().expect("right type missing");
let left = if dupe {
(right.0, Arc::clone(&right.1))
} else {
result_stack.pop().expect("left type missing")
};
let new_total = left.0 + right.0;
if new_total > MAX_UNITS {
return None;
}
if is_sum {
result_stack.push((new_total, OldFinal::sum(left.1, right.1)));
} else {
result_stack.push((new_total, OldFinal::product(left.1, right.1)));
}
}
}
}

// At the end, we should have exactly one final type.
assert_eq!(result_stack.len(), 1, "Internal conversion error");
let (_, res) = result_stack.pop().unwrap();
Some(res)
}

#[cfg(any(fuzzing, test))]
fn do_test(data: &[u8]) {
let mut extractor_1 = simplicity_fuzz::Extractor::new(data);
Expand All @@ -95,8 +13,8 @@ fn do_test(data: &[u8]) {
) {
(Some(val), Some(old_val)) => (val, old_val),
(None, None) => return,
(Some(val), None) => panic!("Could extract new value but not old."),
(None, Some(val)) => panic!("Could extract old value but not new."),
(Some(_), None) => panic!("Could extract new value but not old."),
(None, Some(_)) => panic!("Could extract old value but not new."),
};

assert!(val.iter_compact().eq(old_val.iter_compact()));
Expand Down
4 changes: 2 additions & 2 deletions fuzz/generate-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ path = "fuzz_lib/lib.rs"
libfuzzer-sys = "0.4"
# We shouldn't need an explicit version on the next line, but Andrew's tools
# choke on it otherwise. See https://github.com/nix-community/crate2nix/issues/373
simplicity-lang = { path = "..", features = ["test-utils"], version = "0.3.0" }
old_simplicity = { package = "simplicity-lang", version = "0.3.0", default-features = false }
simplicity-lang = { path = "..", features = ["test-utils"], version = "0.4.0" }
old_simplicity = { package = "simplicity-lang", version = "0.3.1", default-features = false }

[dev-dependencies]
base64 = "0.22.1"
Expand Down