Skip to content

Conversation

@venkkatesh-sekar
Copy link
Member

@venkkatesh-sekar venkkatesh-sekar commented Jan 13, 2026

This PR introduces significant ergonomic improvements to the canfuzz API, making it easier and less verbose to set up new fuzzers.

Key Changes

  1. Builders for Configuration:
    • Introduced CanisterBuilder and FuzzerBuilder to simplify the creation of CanisterInfo and FuzzerState.
    • CanisterBuilder supports a fluent interface for setting properties like Wasm path (file or env var), canister type (coverage/support), and initialization arguments.
  2. Automated Environment Setup:
    • Added FuzzerState::setup_canisters() method. This helper automates the initialization of PocketIc, creation of canisters, and installation of Wasm modules, replacing ~10-15 lines of boilerplate in the init() method of every fuzzer.
  3. Standard Traits & Derive Macro:
    • Replaced the custom FuzzerStateProvider trait with standard AsRef<FuzzerState> and AsMut<FuzzerState> bounds on FuzzerOrchestrator.
    • Introduced a new canfuzz_derive crate (exposed via the derive feature in canfuzz) providing a #[derive(FuzzerState)] macro. This automatically implements the required traits for fuzzer structs wrapping FuzzerState.
  4. Canister Initialization Arguments:
    • Added support for passing initialization arguments to canisters via CanisterBuilder::with_init_args(Option<Vec<u8>>).

Before:

struct MyFuzzer(FuzzerState);
impl FuzzerStateProvider for MyFuzzer {
    fn get_fuzzer_state(&self) -> &FuzzerState { &self.0 }
}
// ... inside FuzzerOrchestrator implementation ...
fn init(&mut self) {
    let test = PocketIcBuilder::new()...build();
    self.0.init_state(test);
    let test = self.get_state_machine();
    // Manual loop to create and install canisters...
}

After:

#[derive(FuzzerState)]
struct MyFuzzer(FuzzerState);
// ... inside FuzzerOrchestrator implementation ...
fn init(&mut self) {
    self.as_mut().setup_canisters();
}
fn main() {
    let target = CanisterBuilder::new("target")
        .with_wasm_path("target.wasm")
        .as_coverage()
        .build();
    
    let state = FuzzerBuilder::new()
        .with_canister(target)
        .build();
        
    MyFuzzer(state).run();
}

@venkkatesh-sekar venkkatesh-sekar changed the title chore: improve fuzzer interface feat(api): Ergonomic improvements and derive macro for FuzzerState Jan 13, 2026
@venkkatesh-sekar venkkatesh-sekar marked this pull request as ready for review January 16, 2026 12:44
@venkkatesh-sekar venkkatesh-sekar requested a review from a team as a code owner January 16, 2026 12:44
@venkkatesh-sekar venkkatesh-sekar merged commit 66ebf2a into main Jan 19, 2026
6 checks passed
@venkkatesh-sekar venkkatesh-sekar deleted the vsekar/ergo branch January 19, 2026 06:28
venkkatesh-sekar added a commit that referenced this pull request Jan 30, 2026
- [feat(api): Ergonomic improvements and derive macro for
FuzzerState](#19)
- [chore: make is_memory64 check
robust](#18)
- [feat: add support for
wasm64](#17)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants