Improve Fuzzing runs (#402)

* Update Fuzzing:
* add coverage generation
* fix block numeration error
* fix AFL build error
* add an EVM run

* toml sort

* fix unexistent call
This commit is contained in:
Nikita Khateev
2025-01-14 13:42:29 +04:00
committed by GitHub
parent 3e625f319b
commit 67c2f2b4e8
9 changed files with 117 additions and 24 deletions
+49
View File
@@ -0,0 +1,49 @@
name: EVM Template Fuzzer (Weekly run)
on:
schedule:
# Runs at 00:00 UTC every Sunday
- cron: '0 0 * * 0'
workflow_dispatch:
jobs:
generic-template-fuzzer:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- name: Add target
run: rustup target add wasm32-unknown-unknown
- name: Add dependencies
run: cargo install ziggy cargo-afl honggfuzz grcov
- name: Build AFL config
run: cargo afl config --build
working-directory: evm-template/template-fuzzer
- name: Run Ziggy Fuzzing
run: |
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 timeout 5h cargo ziggy fuzz -t 20 || true
working-directory: evm-template/template-fuzzer
- name: Generate Ziggy Fuzzing Coverage Result
run: |
CARGO_HOME=.cargo cargo ziggy cover
working-directory: evm-template/template-fuzzer
- name: Zip Artifacts
run: zip artifacts.zip evm-template/template-fuzzer/output/* -r
- name: Save Artifacts
uses: actions/upload-artifact@v4
with:
name: fuzzing-artifacts
path: artifacts.zip
@@ -33,6 +33,11 @@ jobs:
run: | run: |
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 timeout 5h cargo ziggy fuzz -t 20 || true AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 timeout 5h cargo ziggy fuzz -t 20 || true
working-directory: generic-template/template-fuzzer working-directory: generic-template/template-fuzzer
- name: Generate Ziggy Fuzzing Coverage Result
run: |
CARGO_HOME=.cargo cargo ziggy cover
working-directory: generic-template/template-fuzzer
- name: Zip Artifacts - name: Zip Artifacts
run: zip artifacts.zip generic-template/template-fuzzer/output/* -r run: zip artifacts.zip generic-template/template-fuzzer/output/* -r
+4 -1
View File
@@ -27,4 +27,7 @@ docs/build
**/zombienet-linux-x64 **/zombienet-linux-x64
**/bin-* **/bin-*
coverage coverage
# fuzzing output
**/template-fuzzer/output
+22
View File
@@ -207,6 +207,15 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
dependencies = [
"derive_arbitrary",
]
[[package]] [[package]]
name = "ark-bls12-377" name = "ark-bls12-377"
version = "0.4.0" version = "0.4.0"
@@ -2579,6 +2588,17 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "derive_arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "0.99.18" version = "0.99.18"
@@ -10657,6 +10677,7 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863"
dependencies = [ dependencies = [
"arbitrary",
"bytes", "bytes",
"rand", "rand",
"ring 0.16.20", "ring 0.16.20",
@@ -14725,6 +14746,7 @@ dependencies = [
"pallet-whitelist", "pallet-whitelist",
"parachains-common", "parachains-common",
"parity-scale-codec", "parity-scale-codec",
"quinn-proto 0.9.6",
"sp-consensus-aura", "sp-consensus-aura",
"sp-runtime", "sp-runtime",
"sp-state-machine", "sp-state-machine",
+1
View File
@@ -15,6 +15,7 @@ workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
quinn-proto = { version = "0.9.6", features = [ "arbitrary" ] }
ziggy = { workspace = true } ziggy = { workspace = true }
evm-runtime-template = { path = "../runtime" } evm-runtime-template = { path = "../runtime" }
+9 -12
View File
@@ -105,7 +105,8 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
continue; continue;
} }
if lapse > 0 { if lapse > 0 {
finalize_block(elapsed); println!("\n time spent: {elapsed:?}");
assert!(elapsed.as_secs() <= 2, "block execution took too much time");
block += u32::from(lapse) * 393; // 393 * 256 = 100608 which nearly corresponds to a week block += u32::from(lapse) * 393; // 393 * 256 = 100608 which nearly corresponds to a week
weight = 0.into(); weight = 0.into();
@@ -126,6 +127,7 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
println!(" call: {extrinsic:?}"); println!(" call: {extrinsic:?}");
let now = Instant::now(); // We get the current time for timing purposes. let now = Instant::now(); // We get the current time for timing purposes.
#[allow(unused_variables)] #[allow(unused_variables)]
let res = extrinsic.dispatch(RuntimeOrigin::signed(origin)); let res = extrinsic.dispatch(RuntimeOrigin::signed(origin));
elapsed += now.elapsed(); elapsed += now.elapsed();
@@ -133,7 +135,7 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
println!(" result: {res:?}"); println!(" result: {res:?}");
} }
finalize_block(elapsed); Executive::finalize_block();
check_invariants(block, initial_total_issuance); check_invariants(block, initial_total_issuance);
}); });
@@ -142,11 +144,14 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
fn initialize_block(block: u32) { fn initialize_block(block: u32) {
println!("\ninitializing block {}", block); println!("\ninitializing block {}", block);
let current_timestamp = u64::from(block) * SLOT_DURATION; let current_timestamp = u64::from(block) * SLOT_DURATION * 2;
let prev_header = match block { let prev_header = match block {
1 => None, 1 => None,
_ => Some(Executive::finalize_block()), _ => {
println!(" finalizing block");
Some(Executive::finalize_block())
}
}; };
let parent_header = &Header::new( let parent_header = &Header::new(
@@ -280,14 +285,6 @@ fn recursive_call_filter(call: &RuntimeCall, origin: usize) -> bool {
} }
} }
fn finalize_block(elapsed: Duration) {
println!("\n time spent: {elapsed:?}");
assert!(elapsed.as_secs() <= 2, "block execution took too much time");
println!(" finalizing block");
Executive::finalize_block();
}
fn check_invariants(block: u32, initial_total_issuance: Balance) { fn check_invariants(block: u32, initial_total_issuance: Balance) {
let mut counted_free = 0; let mut counted_free = 0;
let mut counted_reserved = 0; let mut counted_reserved = 0;
+22
View File
@@ -207,6 +207,15 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
dependencies = [
"derive_arbitrary",
]
[[package]] [[package]]
name = "ark-bls12-377" name = "ark-bls12-377"
version = "0.4.0" version = "0.4.0"
@@ -2553,6 +2562,17 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "derive_arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "0.99.18" version = "0.99.18"
@@ -10091,6 +10111,7 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863"
dependencies = [ dependencies = [
"arbitrary",
"bytes", "bytes",
"rand", "rand",
"ring 0.16.20", "ring 0.16.20",
@@ -13967,6 +13988,7 @@ dependencies = [
"pallet-whitelist", "pallet-whitelist",
"parachains-common", "parachains-common",
"parity-scale-codec", "parity-scale-codec",
"quinn-proto 0.9.6",
"sp-consensus-aura", "sp-consensus-aura",
"sp-runtime", "sp-runtime",
"sp-state-machine", "sp-state-machine",
@@ -15,6 +15,7 @@ workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
quinn-proto = { version = "0.9.6", features = [ "arbitrary" ] }
ziggy = { workspace = true } ziggy = { workspace = true }
generic-runtime-template = { path = "../runtime" } generic-runtime-template = { path = "../runtime" }
+4 -11
View File
@@ -103,7 +103,8 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
} }
if lapse > 0 { if lapse > 0 {
finalize_block(elapsed); println!("\n time spent: {elapsed:?}");
assert!(elapsed.as_secs() <= 2, "block execution took too much time");
block += u32::from(lapse) * 393; // 393 * 256 = 100608 which nearly corresponds to a week block += u32::from(lapse) * 393; // 393 * 256 = 100608 which nearly corresponds to a week
weight = 0.into(); weight = 0.into();
@@ -131,7 +132,7 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
println!(" result: {res:?}"); println!(" result: {res:?}");
} }
finalize_block(elapsed); Executive::finalize_block();
check_invariants(block, initial_total_issuance); check_invariants(block, initial_total_issuance);
}); });
@@ -140,7 +141,7 @@ fn process_input(accounts: &[AccountId], genesis: &Storage, data: &[u8]) {
fn initialize_block(block: u32) { fn initialize_block(block: u32) {
println!("\ninitializing block {}", block); println!("\ninitializing block {}", block);
let current_timestamp = u64::from(block) * SLOT_DURATION; let current_timestamp = u64::from(block) * SLOT_DURATION * 2;
let prev_header = match block { let prev_header = match block {
1 => None, 1 => None,
@@ -207,14 +208,6 @@ fn initialize_block(block: u32) {
// Calls that need to be called before each block starts (init_calls) go here // Calls that need to be called before each block starts (init_calls) go here
} }
fn finalize_block(elapsed: Duration) {
println!("\n time spent: {elapsed:?}");
assert!(elapsed.as_secs() <= 2, "block execution took too much time");
println!(" finalizing block");
Executive::finalize_block();
}
fn check_invariants(block: u32, initial_total_issuance: Balance) { fn check_invariants(block: u32, initial_total_issuance: Balance) {
let mut counted_free = 0; let mut counted_free = 0;
let mut counted_reserved = 0; let mut counted_reserved = 0;