diff --git a/docs/docs/tooling/fuzzing.md b/docs/docs/tooling/fuzzing.md index c4865bf2a6d..a8660008080 100644 --- a/docs/docs/tooling/fuzzing.md +++ b/docs/docs/tooling/fuzzing.md @@ -78,6 +78,8 @@ Additional fuzzing-specific options include: Only run harnesses that match exactly --timeout Maximum time in seconds to spend fuzzing per harness (default: no timeout) + --max-executions + Maximum number of executions of ACIR and Brillig per harness (default: no limit) `--show-output` and `--oracle-resolver` can be used in the same way as with regular execution and testing. It is recommended to use `--skip-underconstrained-check` to increase compilation speed. diff --git a/tooling/greybox_fuzzer/src/lib.rs b/tooling/greybox_fuzzer/src/lib.rs index 9cf8570285a..a7e028c1346 100644 --- a/tooling/greybox_fuzzer/src/lib.rs +++ b/tooling/greybox_fuzzer/src/lib.rs @@ -278,6 +278,8 @@ pub struct FuzzedExecutorExecutionConfiguration { pub timeout: u64, /// Whether to output progress to stdout or not. pub show_progress: bool, + /// Maximum number of executions of ACIR and Brillig (default: no limit) + pub max_executions: usize, } pub enum FuzzedExecutorFailureConfiguration { @@ -348,6 +350,9 @@ pub struct FuzzedExecutor { /// Maximum time in seconds to spend fuzzing (default: no timeout) timeout: u64, + + /// Maximum number of executions of ACIR and Brillig (default: no limit) + max_executions: usize, } pub struct AcirAndBrilligPrograms { pub acir_program: ProgramArtifact, @@ -412,6 +417,7 @@ impl< ), timeout: fuzz_execution_config.timeout, metrics: Metrics::default(), + max_executions: fuzz_execution_config.max_executions, } } @@ -969,6 +975,12 @@ impl< if self.timeout > 0 && time_tracker.elapsed() >= Duration::from_secs(self.timeout) { return FuzzTestResult::Success; } + // Check if we've exceeded the maximum number of executions + if self.max_executions > 0 + && self.metrics.processed_testcase_count >= self.max_executions + { + return FuzzTestResult::Success; + } } if self.minimize_corpus { diff --git a/tooling/nargo/src/ops/fuzz.rs b/tooling/nargo/src/ops/fuzz.rs index 80fbc484e79..b45bd970d79 100644 --- a/tooling/nargo/src/ops/fuzz.rs +++ b/tooling/nargo/src/ops/fuzz.rs @@ -32,6 +32,8 @@ pub struct FuzzExecutionConfig { pub timeout: u64, /// Whether to output progress to stdout or not. pub show_progress: bool, + /// Maximum number of executions of ACIR and Brillig (default: no limit) + pub max_executions: usize, } /// Folder configuration for fuzzing @@ -208,6 +210,7 @@ where num_threads: fuzz_execution_config.num_threads, timeout: fuzz_execution_config.timeout, show_progress: fuzz_execution_config.show_progress, + max_executions: fuzz_execution_config.max_executions, }, failure_configuration, FuzzedExecutorFolderConfiguration { diff --git a/tooling/nargo_cli/src/cli/fuzz_cmd.rs b/tooling/nargo_cli/src/cli/fuzz_cmd.rs index 1d62c1dabb0..1835e614ede 100644 --- a/tooling/nargo_cli/src/cli/fuzz_cmd.rs +++ b/tooling/nargo_cli/src/cli/fuzz_cmd.rs @@ -70,8 +70,12 @@ pub(crate) struct FuzzCommand { oracle_resolver: Option, /// Maximum time in seconds to spend fuzzing (default: no timeout) - #[arg(long)] - timeout: Option, + #[arg(long, default_value = "0")] + timeout: u64, + + /// Maximum number of executions of ACIR and Brillig per harness (default: no limit) + #[arg(long, default_value = "0")] + max_executions: usize, } impl WorkspaceCommand for FuzzCommand { fn package_selection(&self) -> PackageSelection { @@ -153,9 +157,10 @@ pub(crate) fn run(args: FuzzCommand, workspace: Workspace) -> Result<(), CliErro fuzzing_failure_dir: args.fuzzing_failure_dir, }; let fuzz_execution_config = FuzzExecutionConfig { - timeout: args.timeout.unwrap_or(0), + timeout: args.timeout, num_threads: args.num_threads, show_progress: true, + max_executions: args.max_executions, }; let fuzzing_reports: Vec> = workspace diff --git a/tooling/nargo_cli/src/cli/test_cmd.rs b/tooling/nargo_cli/src/cli/test_cmd.rs index 599c7e37fd0..2897f9e9ca9 100644 --- a/tooling/nargo_cli/src/cli/test_cmd.rs +++ b/tooling/nargo_cli/src/cli/test_cmd.rs @@ -569,6 +569,7 @@ impl<'a> TestRunner<'a> { num_threads: 1, timeout: self.args.fuzz_timeout, show_progress: false, + max_executions: 0, }, };