Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Fuzzer for Pallet Bags List
  • Loading branch information
emostov committed Sep 24, 2021
commit 30890a3ac1643e3e6cbfd83d91f0b470fed8fbed
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ members = [
"frame/utility",
"frame/vesting",
"frame/bags-list",
"frame/bags-list/fuzzer",
"primitives/api",
"primitives/api/proc-macro",
"primitives/api/test",
Expand Down
9 changes: 9 additions & 0 deletions frame/bags-list/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ sp-core = { version = "4.0.0-dev", path = "../../primitives/core", optional = tr
sp-io = { version = "4.0.0-dev", path = "../../primitives/io", optional = true, default-features = false }
sp-tracing = { version = "4.0.0-dev", path = "../../primitives/tracing", optional = true, default-features = false }

# Optional imports for fuzz
# pallet-balances = { version = "4.0.0-dev", path = "../balances", optional = true }

[dev-dependencies]
sp-core = { version = "4.0.0-dev", path = "../../primitives/core"}
sp-io = { version = "4.0.0-dev", path = "../../primitives/io"}
Expand Down Expand Up @@ -63,4 +66,10 @@ runtime-benchmarks = [
"sp-tracing",
"frame-election-provider-support/runtime-benchmarks",
]
fuzz = [
"sp-core",
"sp-io",
"pallet-balances",
"sp-tracing",
]

2 changes: 2 additions & 0 deletions frame/bags-list/fuzzer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hfuzz_target
hfuzz_workspace
22 changes: 22 additions & 0 deletions frame/bags-list/fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "pallet-bags-list-fuzzer"
version = "4.0.0-dev"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "Fuzzer for FRAME pallet bags list"
readme = "README.md"
publish = false

[dependencies]
honggfuzz = "0.5"
rand = { version = "0.8", features = ["std", "small_rng"] }

pallet-bags-list = { version = "4.0.0-dev", features = ["fuzz"], path = ".." }
frame-election-provider-support = { version = "4.0.0-dev", path = "../../election-provider-support", features = ["runtime-benchmarks"] }

[[bin]]
name = "bags-list"
path = "main.rs"
54 changes: 54 additions & 0 deletions frame/bags-list/fuzzer/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! # Running
//! Running this fuzzer can be done with `cargo hfuzz run bags-list`. `honggfuzz` CLI options can
//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads.
//!
//! # Debugging a panic
//! Once a panic is found, it can be debugged with
//! `cargo hfuzz run-debug fixed_point hfuzz_workspace/bags_list/*.fuzz`.
//!
//! # More information
//! More information about `honggfuzz` can be found
//! [here](https://docs.rs/honggfuzz/).
//!
//! //! MacOS users notethat https://github.com/rust-fuzz/honggfuzz-rs/issues/56 may preclude you from running this locally.

use frame_election_provider_support::{SortedListProvider, VoteWeight};
use honggfuzz::fuzz;
use pallet_bags_list::mock::{AccountId, BagsList, ExtBuilder};

const ID_RANGE: AccountId = 10_000;
const OPTIONS: AccountId = 3;

fn main() {
ExtBuilder::default().build_and_execute(|| loop {
fuzz!(|data: (AccountId, VoteWeight)| {
let (account_id_seed, vote_weight) = data;

let id = account_id_seed % ID_RANGE;

match account_id_seed % OPTIONS {
0 => {
if BagsList::on_insert(id.clone(), vote_weight).is_err() {
// this was a duplicate id, which is ok. We can just update it.
BagsList::on_update(&id, vote_weight);
}
assert!(BagsList::contains(&id));
},
1 => {
if !BagsList::contains(&id) {
// we must insert before updating.
assert!(BagsList::on_insert(id.clone(), vote_weight).is_ok());
}
BagsList::on_update(&id, vote_weight);
assert!(BagsList::contains(&id));
},
_ => {
BagsList::on_remove(&id);
assert!(!BagsList::contains(&id));
},
}

assert!(BagsList::sanity_check().is_ok());
})
});
}
4 changes: 2 additions & 2 deletions frame/bags-list/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ use sp_std::prelude::*;
mod benchmarks;

mod list;
#[cfg(test)]
mod mock;
#[cfg(any(test, feature = "fuzz"))]
pub mod mock;
#[cfg(test)]
mod tests;
pub mod weights;
Expand Down
4 changes: 2 additions & 2 deletions frame/bags-list/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub(crate) const GENESIS_IDS: [(AccountId, VoteWeight); 4] =
[(1, 10), (2, 1_000), (3, 1_000), (4, 1_000)];

#[derive(Default)]
pub(crate) struct ExtBuilder {
pub struct ExtBuilder {
ids: Vec<(AccountId, VoteWeight)>,
}

Expand All @@ -126,7 +126,7 @@ impl ExtBuilder {
ext
}

pub(crate) fn build_and_execute(self, test: impl FnOnce() -> ()) {
pub fn build_and_execute(self, test: impl FnOnce() -> ()) {
self.build().execute_with(|| {
test();
List::<Runtime>::sanity_check().expect("Sanity check post condition failed")
Expand Down