From 36154ff643139d079cd1b8fcd813ea7a55a20029 Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Mon, 30 Nov 2020 13:25:00 -0500 Subject: [PATCH] Implement Amt fuzzer (#871) * Implement Amt fuzzer * Fix typo * Change author --- ipld/amt/Cargo.toml | 2 +- ipld/amt/fuzz/.gitignore | 5 +++ ipld/amt/fuzz/Cargo.toml | 29 ++++++++++++++ ipld/amt/fuzz/fuzz_targets/amt_fuzz.rs | 52 ++++++++++++++++++++++++++ ipld/amt/src/amt.rs | 4 +- 5 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 ipld/amt/fuzz/.gitignore create mode 100644 ipld/amt/fuzz/Cargo.toml create mode 100644 ipld/amt/fuzz/fuzz_targets/amt_fuzz.rs diff --git a/ipld/amt/Cargo.toml b/ipld/amt/Cargo.toml index ac6b8b7b79bf..3908a19c5167 100644 --- a/ipld/amt/Cargo.toml +++ b/ipld/amt/Cargo.toml @@ -22,6 +22,6 @@ criterion = "0.3.1" ipld_blockstore = { path = "../blockstore", features = ["tracking"] } [[bench]] -name = "amt_beckmark" +name = "amt_benchmark" path = "benches/amt_benchmark.rs" harness = false \ No newline at end of file diff --git a/ipld/amt/fuzz/.gitignore b/ipld/amt/fuzz/.gitignore new file mode 100644 index 000000000000..e0fb40571e93 --- /dev/null +++ b/ipld/amt/fuzz/.gitignore @@ -0,0 +1,5 @@ + +target +corpus +artifacts +Cargo.lock \ No newline at end of file diff --git a/ipld/amt/fuzz/Cargo.toml b/ipld/amt/fuzz/Cargo.toml new file mode 100644 index 000000000000..1a6fc93274d8 --- /dev/null +++ b/ipld/amt/fuzz/Cargo.toml @@ -0,0 +1,29 @@ + +[package] +name = "ipld_amt-fuzz" +version = "0.0.0" +authors = ["ChainSafe Systems "] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.3" +arbitrary = { version = "0.4", features = ["derive"] } +ahash = "0.5" +db = { path = "../../../node/db" } + +[dependencies.ipld_amt] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "amt_fuzz" +path = "fuzz_targets/amt_fuzz.rs" +test = false +doc = false diff --git a/ipld/amt/fuzz/fuzz_targets/amt_fuzz.rs b/ipld/amt/fuzz/fuzz_targets/amt_fuzz.rs new file mode 100644 index 000000000000..86f956043510 --- /dev/null +++ b/ipld/amt/fuzz/fuzz_targets/amt_fuzz.rs @@ -0,0 +1,52 @@ +#![no_main] +use arbitrary::Arbitrary; +use ipld_amt::{Amt, MAX_INDEX}; +use libfuzzer_sys::fuzz_target; + +#[derive(Debug, Arbitrary)] +struct Operation { + idx: u64, + method: Method, +} + +#[derive(Debug, Arbitrary)] +enum Method { + Insert(u64), + Remove, + Get, +} + +fuzz_target!(|data: (u8, Vec)| { + let (flush_rate, operations) = data; + let db = db::MemoryDB::default(); + let mut amt = Amt::new(&db); + let mut elements = ahash::AHashMap::new(); + + let flush_rate = (flush_rate as usize).saturating_add(5); + for (i, Operation { idx, method }) in operations.into_iter().enumerate() { + if i % flush_rate == 0 { + // Periodic flushing of Amt to fuzz blockstore usage also + amt.flush().unwrap(); + } + if idx > MAX_INDEX { + continue; + } + + match method { + Method::Insert(v) => { + elements.insert(idx, v); + amt.set(idx, v).unwrap(); + } + Method::Remove => { + let el = elements.remove(&idx); + let amt_deleted = amt.delete(idx).unwrap(); + assert_eq!(amt_deleted, el.is_some()); + } + Method::Get => { + let ev = elements.get(&idx); + let av = amt.get(idx).unwrap(); + assert_eq!(av, ev); + } + } + } +}); diff --git a/ipld/amt/src/amt.rs b/ipld/amt/src/amt.rs index d90ca2c82350..a1acb38e3218 100644 --- a/ipld/amt/src/amt.rs +++ b/ipld/amt/src/amt.rs @@ -72,12 +72,12 @@ where Ok(Self { root, block_store }) } - // Getter for height + /// Gets the height of the `Amt`. pub fn height(&self) -> u64 { self.root.height } - // Getter for count + /// Gets count of elements added in the `Amt`. pub fn count(&self) -> u64 { self.root.count }