Hi ZCG team, Zebra maintainers, and Zcash community,
I’m happy to share the delivery for Milestone 2 of the Zebra coverage-guided fuzzing grant.
Milestone 2
Building on Milestone 1, this milestone delivers the second set of coverage-guided
fuzz targets for Zebra, together with continuous-fuzzing infrastructure on GitHub
Actions and a public, auto-updating coverage dashboard.
Deliverables (all complete)
1. RPC interface input handling — rpc_handler_fuzz and jsonrpsee_envelope_fuzz,
exercising zebra-rpc’s methods.rs (34% region coverage).
2. Script & transparent/shielded address parsing — script_verify_fuzz and
script_flag_matrix_fuzz drive transparent-script verification through the zcash_script
C/C++ library via FFI (sanitizer-coverage does not instrument the C side, so these provide
crash detection rather than Rust region coverage); address_fuzz drives
transparent/address.rs (63% region coverage).
3. Note-commitment tree insert/remove — note_commitment_tree_fuzz, exercising
orchard/tree.rs (54% region coverage).
4. Equihash solution verification — equihash_fuzz, exercising work/equihash.rs
(65% region coverage).
That is 7 new operational targets, meeting the proposal’s “7+ targets” criterion and
covering the full deliverable family. Combined with Milestone 1’s 5 block/P2P-deserialization
targets, the suite now runs 12 targets in one cumulative repository.
Continuous fuzzing (ClusterFuzzLite on GitHub Actions)
-
Pull-request fuzzing — short code-change runs with AddressSanitizer + SARIF output
-
Batch fuzzing every 6 hours — accumulates newly-discovered inputs into the corpus
-
Daily coverage report + corpus pruning
Coverage
Per-subject-under-test region coverage is reported per source file. (A whole-report total
is not meaningful here — it averages in the Rust standard library and every third-party
dependency, none of which the fuzzers target.) Beyond the headline files above, **90+
Zebra source files are exercised at ≥5% region coverage**. These are seed-corpus baselines
and grow with sustained fuzzing.
No crashes found to date across the 12 targets.
Corpus
The seed corpus is mainnet-derived public data — real blocks, transactions, headers and
P2P messages dumped from a fully-synced Zcash node — plus a small set of hand-constructed
protocol seeds. The CI corpus accumulates and is periodically pruned/minimized.
Repositories (public, fully reproducible)
-
Fuzzing suite & harnesses: GitHub - robustfengbin/zebra-fuzz-m2: Continuous fuzzing suite for the Zebra Zcash node — 12 libFuzzer targets, mainnet-derived corpus, ClusterFuzzLite CI with coverage dashboard. · GitHub
-
Corpus & live coverage dashboard: Zebra Fuzzing — Coverage Overview
The vendored crates are upstream Zebra v5.0.0, byte-identical except for two fuzzing-only
cfg gates that expose otherwise-private modules to the harnesses. Anyone can clone, build
and run (cargo +nightly fuzz build/run --fuzz-dir zebra-fuzz/fuzz <target>), and the
coverage report rebuilds automatically every night in CI.