Skip to content

Commit 679c2ec

Browse files
authored
fix: enable edge coverage only when needed (#11041)
* fix: enable edge coverage inspector only if corpus set * Add show edge coveerage setting, enable inspector per invariant test
1 parent 0739d77 commit 679c2ec

File tree

6 files changed

+26
-10
lines changed

6 files changed

+26
-10
lines changed

crates/config/src/invariant.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub struct InvariantConfig {
2626
pub max_assume_rejects: u32,
2727
/// Number of runs to execute and include in the gas report.
2828
pub gas_report_samples: u32,
29-
/// Path where invariant corpus is stored. If not configured then coverage guided fuzzing is
30-
/// disabled.
29+
/// Path where invariant corpus is stored, enables coverage guided fuzzing and edge coverage
30+
/// metrics.
3131
pub corpus_dir: Option<PathBuf>,
3232
/// Whether corpus to use gzip file compression and decompression.
3333
pub corpus_gzip: bool,
@@ -43,6 +43,8 @@ pub struct InvariantConfig {
4343
pub timeout: Option<u32>,
4444
/// Display counterexample as solidity calls.
4545
pub show_solidity: bool,
46+
/// Whether to collect and display edge coverage metrics.
47+
pub show_edge_coverage: bool,
4648
}
4749

4850
impl Default for InvariantConfig {
@@ -64,6 +66,7 @@ impl Default for InvariantConfig {
6466
show_metrics: true,
6567
timeout: None,
6668
show_solidity: false,
69+
show_edge_coverage: false,
6770
}
6871
}
6972
}
@@ -88,6 +91,7 @@ impl InvariantConfig {
8891
show_metrics: true,
8992
timeout: None,
9093
show_solidity: false,
94+
show_edge_coverage: false,
9195
}
9296
}
9397
}

crates/evm/evm/src/executors/invariant/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,10 @@ impl<'a> InvariantExecutor<'a> {
357357
runs < self.config.runs
358358
};
359359

360+
// Invariant runs with edge coverage if corpus dir is set or showing edge coverage.
361+
let edge_coverage_enabled =
362+
self.config.corpus_dir.is_some() || self.config.show_edge_coverage;
363+
360364
'stop: while continue_campaign(runs) {
361365
let initial_seq = corpus_manager.new_sequence(&invariant_test)?;
362366

@@ -407,9 +411,9 @@ impl<'a> InvariantExecutor<'a> {
407411

408412
// Collect line coverage from last fuzzed call.
409413
invariant_test.merge_coverage(call_result.line_coverage.clone());
410-
// If coverage guided fuzzing is enabled then merge edge count with current history
414+
// If running with edge coverage then merge edge count with the current history
411415
// map and set new coverage in current run.
412-
if self.config.corpus_dir.is_some() {
416+
if edge_coverage_enabled {
413417
let (new_coverage, is_edge) =
414418
call_result.merge_edge_coverage(&mut self.history_map);
415419
if new_coverage {
@@ -514,15 +518,14 @@ impl<'a> InvariantExecutor<'a> {
514518

515519
// End current invariant test run.
516520
invariant_test.end_run(current_run, self.config.gas_report_samples as usize);
517-
518521
if let Some(progress) = progress {
519522
// If running with progress then increment completed runs.
520523
progress.inc(1);
521524
// Display metrics in progress bar.
522-
if self.config.corpus_dir.is_some() {
525+
if edge_coverage_enabled {
523526
progress.set_message(format!("{}", &corpus_manager.metrics));
524527
}
525-
} else if self.config.corpus_dir.is_some()
528+
} else if edge_coverage_enabled
526529
&& last_metrics_report.elapsed() > DURATION_BETWEEN_METRICS_REPORT
527530
{
528531
// Display metrics inline if corpus dir set.

crates/evm/evm/src/inspectors/stack.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ impl InspectorStackBuilder {
211211
stack.set_chisel(chisel_state);
212212
}
213213
stack.collect_line_coverage(line_coverage.unwrap_or(false));
214-
stack.collect_edge_coverage(true);
215214
stack.collect_logs(logs.unwrap_or(true));
216215
stack.print(print.unwrap_or(false));
217216
stack.tracing(trace_mode);

crates/forge/src/runner.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,15 @@ impl<'a> FunctionRunner<'a> {
705705
let runner = self.invariant_runner();
706706
let invariant_config = &self.config.invariant;
707707

708+
let mut executor = self.clone_executor();
709+
// Enable edge coverage if running with coverage guided fuzzing or with edge coverage
710+
// metrics (useful for benchmarking the fuzzer).
711+
executor.inspector_mut().collect_edge_coverage(
712+
invariant_config.corpus_dir.is_some() || invariant_config.show_edge_coverage,
713+
);
714+
708715
let mut evm = InvariantExecutor::new(
709-
self.clone_executor(),
716+
executor,
710717
runner,
711718
invariant_config.clone(),
712719
identified_contracts,

crates/forge/tests/cli/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,7 @@ corpus_min_size = 0
11211121
failure_persist_dir = "cache/invariant"
11221122
show_metrics = true
11231123
show_solidity = false
1124+
show_edge_coverage = false
11241125
11251126
[labels]
11261127
@@ -1234,7 +1235,8 @@ exclude = []
12341235
"failure_persist_dir": "cache/invariant",
12351236
"show_metrics": true,
12361237
"timeout": null,
1237-
"show_solidity": false
1238+
"show_solidity": false,
1239+
"show_edge_coverage": false
12381240
},
12391241
"ffi": false,
12401242
"allow_internal_expect_revert": false,

crates/forge/tests/it/test_helpers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ impl ForgeTestProfile {
160160
show_metrics: true,
161161
timeout: None,
162162
show_solidity: false,
163+
show_edge_coverage: false,
163164
};
164165

165166
config.sanitized()

0 commit comments

Comments
 (0)