Skip to content

feat(fuzz): add fuzzing harness for LocalChain with CI job - #2239

Open
erickcestari wants to merge 3 commits into
bitcoindevkit:masterfrom
erickcestari:fuzz-bdk
Open

feat(fuzz): add fuzzing harness for LocalChain with CI job#2239
erickcestari wants to merge 3 commits into
bitcoindevkit:masterfrom
erickcestari:fuzz-bdk

Conversation

@erickcestari

@erickcestari erickcestari commented Jul 9, 2026

Copy link
Copy Markdown

Description

Adds an initial fuzzing harness for bdk_chain and a CI job that runs it.

Two fuzz targets in a new fuzz/ crate:

  • local_chain_apply_update: builds a LocalChain<BlockHash> and applies random sequences of apply_update, insert_block, disconnect_from, apply_header(_connected_to), including updates derived from the chain's own tip to hit the merge_chains eq_ptr fast path.
  • local_chain_apply_update_header: fuzzes LocalChain<Header>, exercising placeholder resolution in apply_update and CheckPoint::entry_iter via a virtual chain of linked headers with random reorgs.

After every operation, the harness asserts that a successful op's changeset reconstructs the post-state from the pre-state, a failed op leaves the chain untouched, and chain invariants hold (strictly decreasing heights, genesis present, is_block_in_chain consistency).

Supports AFL, honggfuzz, and libFuzzer via cargo features. The CI job runs each fuzzer on each target for 5 minutes as a smoke test.

Notes to the reviewers

  • The fuzz crate is its own workspace (publish = false) so fuzzer deps don't affect the main workspace.

Changelog notice

  • Added a fuzzing harness for LocalChain (AFL, honggfuzz, libFuzzer) with a CI job.

Coverage report

image

cc @oleonardolima

erickcestari and others added 2 commits July 8, 2026 21:06
Co-authored-by: Leonardo Lima <oleonardolima@users.noreply.github.com>
Co-authored-by: Leonardo Lima <oleonardolima@users.noreply.github.com>
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.65%. Comparing base (6d03fc3) to head (86fdfd8).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2239   +/-   ##
=======================================
  Coverage   78.65%   78.65%           
=======================================
  Files          30       30           
  Lines        5909     5909           
  Branches      279      279           
=======================================
  Hits         4648     4648           
  Misses       1185     1185           
  Partials       76       76           
Flag Coverage Δ
rust 78.65% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@luisschwab luisschwab moved this to Needs Review in BDK Chain Jul 9, 2026
@oleonardolima oleonardolima moved this from Needs Review to In Progress in BDK Chain Jul 10, 2026
- Move input generators into arbitrary module, generic over the
  checkpoint data type
- Move differential changeset and checkpoint-order assertions into
  checks module
- Add fuzz_main! macro generating AFL/honggfuzz/libFuzzer entry points
  and a corpus-replay fallback main
- Replace integer op dispatch with explicit Op enums
- Remove leftover debug println
@oleonardolima

Copy link
Copy Markdown
Contributor

It's still missing an updated CI, fixing the conflicts and running each target+harness for an x cycles instead of time, also it requires a proper README.md for users on how to run the fuzzer, and how to add new targets.

Comment on lines +12 to +27
enum Op {
/// `apply_update` with an independently constructed chain as the update.
ApplyUpdate,
/// `insert_block` with an arbitrary height and hash.
InsertBlock,
/// `disconnect_from` an existing checkpoint or an arbitrary block id.
DisconnectFrom,
/// `apply_header` with a header that usually connects to an existing checkpoint.
ApplyHeader,
/// `apply_header_connected_to` with an arbitrarily picked connection point.
ApplyHeaderConnectedTo,
/// `apply_update` with an update derived by mutating the chain's own tip, so the
/// update shares `Arc` nodes with the original and exercises `merge_chains`'
/// `eq_ptr` fast path.
ApplyDerivedUpdate,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erickcestari we probably should also add coverage for the changeset operations/APIs.

@luisschwab

Copy link
Copy Markdown
Member

@erickcestari needs rebase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants