Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce fuzzer_runs >= 1 everywhere #1938

Merged
merged 7 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/forge-runner/src/compiled_runnable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::expected_result::ExpectedTestResult;
use cairo_lang_sierra::{ids::GenericTypeId, program::Program};
use serde::Deserialize;
use starknet_api::block::BlockNumber;
use std::num::NonZeroU32;
use url::Url;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -36,6 +37,6 @@ pub struct ValidatedForkConfig {

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct FuzzerConfig {
pub fuzzer_runs: u32,
pub fuzzer_runs: NonZeroU32,
pub fuzzer_seed: u64,
}
63 changes: 34 additions & 29 deletions crates/forge-runner/src/fuzzer.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,66 @@
use crate::fuzzer::arguments::CairoType;
use anyhow::Result;
use anyhow::{Ok, Result};
use rand::rngs::StdRng;
use rand::Rng;

mod arguments;
mod random;

pub use random::RandomFuzzer;
use std::num::NonZeroU32;

#[derive(Debug, Clone)]
pub struct FuzzerArg {
cairo_type: CairoType,
run_with_min_value: u32,
run_with_max_value: u32,
}

#[derive(Debug, Clone)]
pub struct RunParams {
/// Arguments
arguments: Vec<CairoType>,
arguments: Vec<FuzzerArg>,
/// Total number of runs
total_runs: u32,
total_runs: NonZeroU32,
/// Number of already executed runs
executed_runs: u32,
/// Run in which an argument has a min value
/// e.g. `run_with_min_value_argument[0] = 5`
/// means that the first argument will have the lowest possible value in 5th run
run_with_min_value_for_argument: Vec<u32>,
/// Run in which argument has a max value
/// e.g. `run_with_max_value_for_argument[0] = 5`
/// means that the first argument will have the highest possible value in 5th run
run_with_max_value_for_argument: Vec<u32>,
}

impl RunParams {
pub fn from(rng: &mut StdRng, total_runs: u32, arguments: &[&str]) -> Result<Self> {
assert!(total_runs >= 3);

pub fn from(rng: &mut StdRng, total_runs: NonZeroU32, arguments: &[&str]) -> Result<Self> {
let arguments = arguments
.iter()
.map(|arg| CairoType::from_name(arg))
.collect::<Result<Vec<_>>>()?;
.map(|arg| -> Result<FuzzerArg> {
let argument = CairoType::from_name(arg)?;
if total_runs.get() >= 3 {
let run_with_min_value = rng.gen_range(1..=total_runs.get());
let run_with_max_value = rng.gen_range(1..=total_runs.get());

let run_with_min_value_for_argument: Vec<u32> = (0..arguments.len())
.map(|_| rng.gen_range(1..=total_runs))
.collect();
let run_with_max_value_for_argument: Vec<u32> = run_with_min_value_for_argument
.iter()
.map(|&run_with_min| {
let run_with_max = rng.gen_range(1..=total_runs);
if run_with_max == run_with_min {
run_with_min % total_runs + 1
let run_with_max_value = if run_with_max_value == run_with_min_value {
run_with_min_value % total_runs.get() + 1
} else {
run_with_max_value
};

Ok(FuzzerArg {
cairo_type: argument,
run_with_max_value,
run_with_min_value,
})
} else {
run_with_max
Ok(FuzzerArg {
cairo_type: argument,
run_with_max_value: u32::MAX,
run_with_min_value: u32::MAX,
})
}
})
.collect();
.collect::<Result<Vec<_>>>()?;

Ok(Self {
arguments,
total_runs,
executed_runs: 0,
run_with_min_value_for_argument,
run_with_max_value_for_argument,
})
}
}
35 changes: 12 additions & 23 deletions crates/forge-runner/src/fuzzer/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use num_traits::{One, Zero};
use rand::prelude::StdRng;
use std::ops::{Add, Shl, Shr, Sub};

#[derive(Debug, Clone)]
#[derive(Debug, Copy, Clone)]
pub enum CairoType {
U8,
U16,
Expand All @@ -17,35 +17,24 @@ pub enum CairoType {
Felt252,
}

pub trait Argument {
fn low(&self) -> BigUint;
fn high(&self) -> BigUint;
fn gen(&self, rng: &mut StdRng) -> Vec<Felt252>;
fn min(&self) -> Vec<Felt252>;
fn max(&self) -> Vec<Felt252>;
}

impl Argument for CairoType {
fn low(&self) -> BigUint {
impl CairoType {
pub fn low() -> BigUint {
BigUint::zero()
}

fn high(&self) -> BigUint {
pub fn high(self) -> BigUint {
match self {
CairoType::U8 => BigUint::from(u8::MAX).add(BigUint::one()),
CairoType::U16 => BigUint::from(u16::MAX).add(BigUint::one()),
CairoType::U32 => BigUint::from(u32::MAX).add(BigUint::one()),
CairoType::U64 => BigUint::from(u64::MAX).add(BigUint::one()),
CairoType::U128 => BigUint::from(u128::MAX).add(BigUint::one()),
CairoType::U256 => {
let max = BigUint::from(1_u32);
max.shl(256)
}
CairoType::U256 => BigUint::from(1_u32).shl(256),
CairoType::Felt252 => Felt252::prime(),
}
}

fn gen(&self, rng: &mut StdRng) -> Vec<Felt252> {
pub fn gen(self, rng: &mut StdRng) -> Vec<Felt252> {
match self {
CairoType::U8
| CairoType::U16
Expand All @@ -54,29 +43,29 @@ impl Argument for CairoType {
| CairoType::U128
| CairoType::Felt252 => {
vec![Felt252::from(
rng.gen_biguint_range(&self.low(), &self.high()),
rng.gen_biguint_range(&Self::low(), &self.high()),
)]
}
CairoType::U256 => {
let val = rng.gen_biguint_range(&self.low(), &self.high());
let val = rng.gen_biguint_range(&Self::low(), &self.high());
u256_to_felt252(val)
}
}
}

fn min(&self) -> Vec<Felt252> {
pub fn min(self) -> Vec<Felt252> {
match self {
CairoType::U8
| CairoType::U16
| CairoType::U32
| CairoType::U64
| CairoType::U128
| CairoType::Felt252 => vec![Felt252::from(self.low())],
CairoType::U256 => vec![Felt252::from(self.low()), Felt252::from(self.low())],
| CairoType::Felt252 => vec![Felt252::from(Self::low())],
CairoType::U256 => vec![Felt252::from(Self::low()), Felt252::from(Self::low())],
}
}

fn max(&self) -> Vec<Felt252> {
pub fn max(self) -> Vec<Felt252> {
match self {
CairoType::U8
| CairoType::U16
Expand Down
Loading
Loading