From 4d7343ac4f45b083d27bfa481a0ad718d9b5c5de Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Apr 2024 12:58:52 -0300 Subject: [PATCH 01/11] Admit both types of range_check in range_check_builtin_runner --- Cargo.lock | 1 + vm/src/serde/deserialize_program.rs | 4 +- vm/src/vm/runners/builtin_runner/mod.rs | 5 +- .../vm/runners/builtin_runner/range_check.rs | 46 +++++++++++++++---- vm/src/vm/vm_core.rs | 4 +- 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3cd2a2000..d51294e05e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -973,6 +973,7 @@ dependencies = [ "clap", "itertools 0.11.0", "mimalloc", + "num-traits 0.2.18", "rstest", "thiserror", ] diff --git a/vm/src/serde/deserialize_program.rs b/vm/src/serde/deserialize_program.rs index dda347101a..0a7c163f1a 100644 --- a/vm/src/serde/deserialize_program.rs +++ b/vm/src/serde/deserialize_program.rs @@ -13,7 +13,7 @@ use crate::{ prelude::*, sync::Arc, }, - utils::CAIRO_PRIME, + utils::CAIRO_PRIME, vm::runners::builtin_runner::RANGE_CHECK_96_BUILTIN_NAME, }; use crate::utils::PRIME_STR; @@ -55,6 +55,7 @@ pub enum BuiltinName { ec_op, poseidon, segment_arena, + range_check96, } impl BuiltinName { @@ -69,6 +70,7 @@ impl BuiltinName { BuiltinName::ec_op => EC_OP_BUILTIN_NAME, BuiltinName::poseidon => POSEIDON_BUILTIN_NAME, BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME, + BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME, } } } diff --git a/vm/src/vm/runners/builtin_runner/mod.rs b/vm/src/vm/runners/builtin_runner/mod.rs index 78eed172a2..74f61ae771 100644 --- a/vm/src/vm/runners/builtin_runner/mod.rs +++ b/vm/src/vm/runners/builtin_runner/mod.rs @@ -35,6 +35,7 @@ use super::cairo_pie::BuiltinAdditionalData; pub const OUTPUT_BUILTIN_NAME: &str = "output_builtin"; pub const HASH_BUILTIN_NAME: &str = "pedersen_builtin"; pub const RANGE_CHECK_BUILTIN_NAME: &str = "range_check_builtin"; +pub const RANGE_CHECK_96_BUILTIN_NAME: &str = "range_check_96_builtin"; pub const SIGNATURE_BUILTIN_NAME: &str = "ecdsa_builtin"; pub const BITWISE_BUILTIN_NAME: &str = "bitwise_builtin"; pub const EC_OP_BUILTIN_NAME: &str = "ec_op_builtin"; @@ -315,7 +316,7 @@ impl BuiltinRunner { match self { BuiltinRunner::RangeCheck(range_check) => { let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?; - Ok(used_cells * range_check.n_parts as usize) + Ok(used_cells * range_check.n_parts() as usize) } _ => Ok(0), } @@ -379,7 +380,7 @@ impl BuiltinRunner { BuiltinRunner::Bitwise(_) => BITWISE_BUILTIN_NAME, BuiltinRunner::EcOp(_) => EC_OP_BUILTIN_NAME, BuiltinRunner::Hash(_) => HASH_BUILTIN_NAME, - BuiltinRunner::RangeCheck(_) => RANGE_CHECK_BUILTIN_NAME, + BuiltinRunner::RangeCheck(b) => b.name(), BuiltinRunner::Output(_) => OUTPUT_BUILTIN_NAME, BuiltinRunner::Keccak(_) => KECCAK_BUILTIN_NAME, BuiltinRunner::Signature(_) => SIGNATURE_BUILTIN_NAME, diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index d70e74b9da..7ca4ad94b9 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -23,7 +23,7 @@ use crate::{ use num_traits::Zero; -use super::RANGE_CHECK_BUILTIN_NAME; +use super::{RANGE_CHECK_96_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME}; // NOTE: the current implementation is based on the bound 0x10000 const _INNER_RC_BOUND: u64 = 1u64 << INNER_RC_BOUND_SHIFT; @@ -31,18 +31,25 @@ const INNER_RC_BOUND_SHIFT: u64 = 16; const INNER_RC_BOUND_MASK: u64 = u16::MAX as u64; // TODO: use constant instead of receiving as false parameter -const N_PARTS: u64 = 8; +const N_PARTS_STANDARD: u64 = 8; +const N_PARTS_96: u64 = 6; + +#[derive(Debug, Clone)] +enum RangeCheckType { + Standard, // n_parts = 6 + NinetySix, // n_parts = 8 +} #[derive(Debug, Clone)] pub struct RangeCheckBuiltinRunner { ratio: Option, base: usize, + range_check_type: RangeCheckType, pub(crate) stop_ptr: Option, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, pub _bound: Option, pub(crate) included: bool, - pub(crate) n_parts: u32, pub(crate) instances_per_component: u32, } @@ -58,12 +65,12 @@ impl RangeCheckBuiltinRunner { RangeCheckBuiltinRunner { ratio, base: 0, + range_check_type: if n_parts == N_PARTS_96 as u32 {RangeCheckType::NinetySix} else {RangeCheckType::Standard}, stop_ptr: None, cells_per_instance: CELLS_PER_RANGE_CHECK, n_input_cells: CELLS_PER_RANGE_CHECK, _bound, included, - n_parts, instances_per_component: 1, } } @@ -88,8 +95,22 @@ impl RangeCheckBuiltinRunner { self.ratio } - pub fn add_validation_rule(&self, memory: &mut Memory) { - let rule: ValidationRule = ValidationRule(Box::new( + pub const fn n_parts(&self) -> u64 { + match self.range_check_type { + RangeCheckType::Standard => N_PARTS_STANDARD, + RangeCheckType::NinetySix => N_PARTS_96, + } + } + + pub fn name(&self) -> &str { + match self.range_check_type { + RangeCheckType::Standard => RANGE_CHECK_BUILTIN_NAME, + RangeCheckType::NinetySix => RANGE_CHECK_96_BUILTIN_NAME, + } + } + + fn build_rule() -> ValidationRule { + ValidationRule(Box::new( |memory: &Memory, address: Relocatable| -> Result, MemoryError> { let num = memory .get_integer(address) @@ -99,11 +120,18 @@ impl RangeCheckBuiltinRunner { } else { Err(MemoryError::RangeCheckNumOutOfBounds(Box::new(( num.into_owned(), - Felt252::TWO.pow((N_PARTS * INNER_RC_BOUND_SHIFT) as u128), + Felt252::TWO.pow((N_PARTS_STANDARD * INNER_RC_BOUND_SHIFT) as u128), )))) } }, - )); + )) + } + + pub fn add_validation_rule(&self, memory: &mut Memory) { + let rule = match self.range_check_type { + RangeCheckType::Standard => RangeCheckBuiltinRunner::build_rule::(), + RangeCheckType::NinetySix => RangeCheckBuiltinRunner::build_rule::(), + }; memory.add_validation_rule(self.base, rule); } @@ -144,7 +172,7 @@ impl RangeCheckBuiltinRunner { .rev() .map(move |i| ((digit >> (i * INNER_RC_BOUND_SHIFT)) & INNER_RC_BOUND_MASK)) }) - .take(self.n_parts as usize) + .take(self.n_parts() as usize) .fold(rc_bounds, |mm, x| { (min(mm.0, x as usize), max(mm.1, x as usize)) }); diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 9a20d8887a..626dba0a2e 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -925,7 +925,9 @@ impl VirtualMachine { pub fn get_range_check_builtin(&self) -> Result<&RangeCheckBuiltinRunner, VirtualMachineError> { for builtin in &self.builtin_runners { if let BuiltinRunner::RangeCheck(range_check_builtin) = builtin { - return Ok(range_check_builtin); + if matches!(range_check_builtin.name(), RANGE_CHECK_BUILTIN_NAME) { + return Ok(range_check_builtin); + } }; } Err(VirtualMachineError::NoRangeCheckBuiltin) From c7b4b00cee89e6255f3f2765a61a1280261e5606 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Apr 2024 13:27:26 -0300 Subject: [PATCH 02/11] Add range_check96 to layout + make bound a constant --- .../builtin_hint_processor/math_utils.rs | 75 +++++++------------ .../squash_dict_utils.rs | 5 +- vm/src/serde/deserialize_program.rs | 3 +- .../builtins_instance_def.rs | 11 +++ .../vm/runners/builtin_runner/range_check.rs | 39 +++++----- vm/src/vm/runners/cairo_runner.rs | 18 +++++ vm/src/vm/vm_core.rs | 4 +- 7 files changed, 82 insertions(+), 73 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index 80c326394b..c26396b437 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -45,13 +45,9 @@ pub fn is_nn( ap_tracking: &ApTracking, ) -> Result<(), HintError> { let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?; - let range_check_builtin = vm.get_range_check_builtin()?; + let range_check_bound = vm.get_range_check_builtin()?.bound(); //Main logic (assert a is not negative and within the expected range) - let value = match &range_check_builtin._bound { - Some(bound) if a.as_ref() >= bound => Felt252::ONE, - _ => Felt252::ZERO, - }; - insert_value_into_ap(vm, value) + insert_value_into_ap(vm, Felt252::from(a.as_ref() >= range_check_bound)) } //Implements hint: memory[ap] = 0 if 0 <= ((-ids.a - 1) % PRIME) < range_check_builtin.bound else 1 @@ -62,15 +58,9 @@ pub fn is_nn_out_of_range( ) -> Result<(), HintError> { let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?; let a = a.as_ref(); - let range_check_builtin = vm.get_range_check_builtin()?; + let range_check_bound = vm.get_range_check_builtin()?.bound(); //Main logic (assert a is not negative and within the expected range) - //let value = if (-a - 1usize).mod_floor(vm.get_prime()) < range_check_builtin._bound { - let value = match &range_check_builtin._bound { - Some(bound) if Felt252::ZERO - (a + 1u64) < *bound => Felt252::ZERO, - None => Felt252::ZERO, - _ => Felt252::ONE, - }; - insert_value_into_ap(vm, value) + insert_value_into_ap(vm, Felt252::from(-(a + 1) >= *range_check_bound)) } /* Implements hint:from starkware.cairo.common.math_utils import assert_integer %{ @@ -184,9 +174,9 @@ pub fn assert_le_felt_v_0_8( b.clone().into_owned(), )))); } - let bound = vm.get_range_check_builtin()?._bound.unwrap_or_default(); + let bound = vm.get_range_check_builtin()?.bound(); let small_inputs = - Felt252::from((a.as_ref() < &bound && b.as_ref() - a.as_ref() < bound) as u8); + Felt252::from((a.as_ref() < &bound && b.as_ref() - a.as_ref() < *bound) as u8); insert_value_from_var_name("small_inputs", small_inputs, vm, ids_data, ap_tracking) } @@ -299,11 +289,10 @@ pub fn assert_nn( let range_check_builtin = vm.get_range_check_builtin()?; // assert 0 <= ids.a % PRIME < range_check_builtin.bound // as prime > 0, a % prime will always be > 0 - match &range_check_builtin._bound { - Some(bound) if a.as_ref() >= bound => { - Err(HintError::AssertNNValueOutOfRange(Box::new(a.into_owned()))) - } - _ => Ok(()), + if a.as_ref() >= range_check_builtin.bound() { + Err(HintError::AssertNNValueOutOfRange(Box::new(a.into_owned()))) + } else { + Ok(()) } } @@ -381,14 +370,11 @@ pub fn is_positive( // Avoid using abs so we don't allocate a new BigInt let (sign, abs_value) = value_as_int.into_parts(); //Main logic (assert a is positive) - match &range_check_builtin._bound { - Some(bound) if abs_value > bound.to_biguint() => { - return Err(HintError::ValueOutsideValidRange(Box::new( - value.into_owned(), - ))) - } - _ => {} - }; + if abs_value >= range_check_builtin.bound().to_biguint() { + return Err(HintError::ValueOutsideValidRange(Box::new( + value.into_owned(), + ))); + } let result = Felt252::from((sign == Sign::Plus) as u8); insert_value_from_var_name("is_positive", result, vm, ids_data, ap_tracking) @@ -474,7 +460,7 @@ pub fn signed_div_rem( let bound = get_integer_from_var_name("bound", vm, ids_data, ap_tracking)?; let builtin = vm.get_range_check_builtin()?; - let builtin_bound = &builtin._bound.unwrap_or(Felt252::MAX); + let builtin_bound = builtin.bound(); if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? { return Err(HintError::OutOfValidRange(Box::new(( div.into_owned(), @@ -528,25 +514,14 @@ pub fn unsigned_div_rem( ) -> Result<(), HintError> { let div = get_integer_from_var_name("div", vm, ids_data, ap_tracking)?; let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?; - let builtin = vm.get_range_check_builtin()?; + let builtin_bound = vm.get_range_check_builtin()?.bound(); // Main logic - match &builtin._bound { - Some(builtin_bound) - if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? => - { - return Err(HintError::OutOfValidRange(Box::new(( - div.into_owned(), - *builtin_bound, - )))); - } - None if div.is_zero() => { - return Err(HintError::OutOfValidRange(Box::new(( - div.into_owned(), - Felt252::ZERO - Felt252::ONE, - )))); - } - _ => {} + if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? { + return Err(HintError::OutOfValidRange(Box::new(( + div.into_owned(), + *builtin_bound, + )))); } let (q, r) = value.div_rem(&(*div).try_into().map_err(|_| MathError::DividedByZero)?); @@ -1830,9 +1805,9 @@ mod tests { //Initialize fp vm.run_context.fp = 6; //Insert ids into memory - let bound = vm.get_range_check_builtin().unwrap()._bound; + let bound = vm.get_range_check_builtin().unwrap().bound(); vm.segments = segments![((1, 3), (5)), ((1, 4), 10)]; - vm.insert_value((1, 5).into(), bound.unwrap()).unwrap(); + vm.insert_value((1, 5).into(), bound).unwrap(); //Create ids let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"]; //Execute the hint @@ -1840,7 +1815,7 @@ mod tests { assert_matches!( run_hint!(vm, ids_data, hint_code), Err(HintError::OutOfValidRange(bx)) - if *bx == (bound.unwrap(), builtin_bound.field_div(&Felt252::TWO.try_into().unwrap())) + if *bx == (*bound, builtin_bound.field_div(&Felt252::TWO.try_into().unwrap())) ) } diff --git a/vm/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs b/vm/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs index 32ea9cb253..e86321006c 100644 --- a/vm/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs @@ -247,8 +247,7 @@ pub fn squash_dict( let ptr_diff = get_integer_from_var_name("ptr_diff", vm, ids_data, ap_tracking)?; let n_accesses = get_integer_from_var_name("n_accesses", vm, ids_data, ap_tracking)?; //Get range_check_builtin - let range_check_builtin = vm.get_range_check_builtin()?; - let range_check_bound = range_check_builtin._bound; + let range_check_bound = *vm.get_range_check_builtin()?.bound(); //Main Logic let ptr_diff = ptr_diff .to_usize() @@ -285,7 +284,7 @@ pub fn squash_dict( keys.sort(); keys.reverse(); //Are the keys used bigger than the range_check bound. - let big_keys = if keys[0] >= range_check_bound.unwrap() { + let big_keys = if keys[0] >= range_check_bound { Felt252::ONE } else { Felt252::ZERO diff --git a/vm/src/serde/deserialize_program.rs b/vm/src/serde/deserialize_program.rs index 0a7c163f1a..06b7ba4748 100644 --- a/vm/src/serde/deserialize_program.rs +++ b/vm/src/serde/deserialize_program.rs @@ -13,7 +13,8 @@ use crate::{ prelude::*, sync::Arc, }, - utils::CAIRO_PRIME, vm::runners::builtin_runner::RANGE_CHECK_96_BUILTIN_NAME, + utils::CAIRO_PRIME, + vm::runners::builtin_runner::RANGE_CHECK_96_BUILTIN_NAME, }; use crate::utils::PRIME_STR; diff --git a/vm/src/types/instance_definitions/builtins_instance_def.rs b/vm/src/types/instance_definitions/builtins_instance_def.rs index 10675423f7..22c2cbd3e3 100644 --- a/vm/src/types/instance_definitions/builtins_instance_def.rs +++ b/vm/src/types/instance_definitions/builtins_instance_def.rs @@ -16,6 +16,7 @@ pub(crate) struct BuiltinsInstanceDef { pub(crate) ec_op: Option, pub(crate) keccak: Option, pub(crate) poseidon: Option, + pub(crate) range_check96: Option, } impl BuiltinsInstanceDef { @@ -29,6 +30,7 @@ impl BuiltinsInstanceDef { ec_op: None, keccak: None, poseidon: None, + range_check96: None, } } @@ -42,6 +44,7 @@ impl BuiltinsInstanceDef { ec_op: None, keccak: None, poseidon: None, + range_check96: None, } } @@ -55,6 +58,7 @@ impl BuiltinsInstanceDef { ec_op: None, keccak: None, poseidon: None, + range_check96: None, } } @@ -68,6 +72,7 @@ impl BuiltinsInstanceDef { ec_op: None, keccak: None, poseidon: None, + range_check96: None, } } @@ -81,6 +86,7 @@ impl BuiltinsInstanceDef { ec_op: Some(EcOpInstanceDef::new(Some(1024))), keccak: None, poseidon: Some(PoseidonInstanceDef::default()), + range_check96: None, } } @@ -94,6 +100,7 @@ impl BuiltinsInstanceDef { ec_op: Some(EcOpInstanceDef::new(Some(1024))), keccak: Some(KeccakInstanceDef::new(Some(2048), vec![200; 8])), poseidon: Some(PoseidonInstanceDef::default()), + range_check96: None, } } @@ -107,6 +114,7 @@ impl BuiltinsInstanceDef { ec_op: None, keccak: None, poseidon: Some(PoseidonInstanceDef::new(Some(8))), + range_check96: None, } } @@ -120,6 +128,7 @@ impl BuiltinsInstanceDef { ec_op: Some(EcOpInstanceDef::new(Some(1024))), keccak: Some(KeccakInstanceDef::new(Some(2048), vec![200; 8])), poseidon: Some(PoseidonInstanceDef::new(Some(256))), + range_check96: Some(RangeCheckInstanceDef::new(Some(8), 6)), } } @@ -133,6 +142,7 @@ impl BuiltinsInstanceDef { ec_op: Some(EcOpInstanceDef::default()), keccak: None, poseidon: None, + range_check96: None, } } @@ -146,6 +156,7 @@ impl BuiltinsInstanceDef { ec_op: Some(EcOpInstanceDef::new(None)), keccak: None, poseidon: None, + range_check96: None, } } } diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index 7ca4ad94b9..e3a701f818 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -21,23 +21,26 @@ use crate::{ }, }; -use num_traits::Zero; +use lazy_static::lazy_static; use super::{RANGE_CHECK_96_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME}; -// NOTE: the current implementation is based on the bound 0x10000 -const _INNER_RC_BOUND: u64 = 1u64 << INNER_RC_BOUND_SHIFT; const INNER_RC_BOUND_SHIFT: u64 = 16; const INNER_RC_BOUND_MASK: u64 = u16::MAX as u64; -// TODO: use constant instead of receiving as false parameter const N_PARTS_STANDARD: u64 = 8; const N_PARTS_96: u64 = 6; +lazy_static! { + pub static ref BOUND_STANDARD: Felt252 = + Felt252::TWO.pow(INNER_RC_BOUND_SHIFT * N_PARTS_STANDARD); + pub static ref BOUND_96: Felt252 = Felt252::TWO.pow(INNER_RC_BOUND_SHIFT * N_PARTS_96); +} + #[derive(Debug, Clone)] enum RangeCheckType { - Standard, // n_parts = 6 - NinetySix, // n_parts = 8 + Standard, // range_check, n_parts = 8 + NinetySix, // range_check96, n_parts = 6 } #[derive(Debug, Clone)] @@ -48,28 +51,23 @@ pub struct RangeCheckBuiltinRunner { pub(crate) stop_ptr: Option, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, - pub _bound: Option, pub(crate) included: bool, pub(crate) instances_per_component: u32, } impl RangeCheckBuiltinRunner { pub fn new(ratio: Option, n_parts: u32, included: bool) -> RangeCheckBuiltinRunner { - let bound = Felt252::TWO.pow(16 * n_parts as u128); - let _bound = if n_parts != 0 && bound.is_zero() { - None - } else { - Some(bound) - }; - RangeCheckBuiltinRunner { ratio, base: 0, - range_check_type: if n_parts == N_PARTS_96 as u32 {RangeCheckType::NinetySix} else {RangeCheckType::Standard}, + range_check_type: if n_parts == N_PARTS_96 as u32 { + RangeCheckType::NinetySix + } else { + RangeCheckType::Standard + }, stop_ptr: None, cells_per_instance: CELLS_PER_RANGE_CHECK, n_input_cells: CELLS_PER_RANGE_CHECK, - _bound, included, instances_per_component: 1, } @@ -102,13 +100,20 @@ impl RangeCheckBuiltinRunner { } } - pub fn name(&self) -> &str { + pub fn name(&self) -> &'static str { match self.range_check_type { RangeCheckType::Standard => RANGE_CHECK_BUILTIN_NAME, RangeCheckType::NinetySix => RANGE_CHECK_96_BUILTIN_NAME, } } + pub fn bound(&self) -> &'static Felt252 { + match self.range_check_type { + RangeCheckType::Standard => &BOUND_STANDARD, + RangeCheckType::NinetySix => &BOUND_96, + } + } + fn build_rule() -> ValidationRule { ValidationRule(Box::new( |memory: &Memory, address: Relocatable| -> Result, MemoryError> { diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index af4048697a..7b34c1ac66 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -259,6 +259,7 @@ impl CairoRunner { BuiltinName::ec_op, BuiltinName::keccak, BuiltinName::poseidon, + BuiltinName::range_check96, ]; if !is_subsequence(&self.program.builtins, &builtin_ordered_list) { return Err(RunnerError::DisorderedBuiltins); @@ -329,6 +330,20 @@ impl CairoRunner { .push(PoseidonBuiltinRunner::new(instance_def.ratio, included).into()); } } + + if let Some(instance_def) = self.layout.builtins.range_check96.as_ref() { + let included = program_builtins.remove(&BuiltinName::range_check96); + if included || self.is_proof_mode() { + builtin_runners.push( + RangeCheckBuiltinRunner::new( + instance_def.ratio, + instance_def.n_parts, + included, + ) + .into(), + ); + } + } if !program_builtins.is_empty() && !allow_missing_builtins { return Err(RunnerError::NoBuiltinForInstance(Box::new(( program_builtins.iter().map(|n| n.name()).collect(), @@ -400,6 +415,9 @@ impl CairoRunner { .push(SegmentArenaBuiltinRunner::new(true).into()) } } + BuiltinName::range_check96 => vm + .builtin_runners + .push(RangeCheckBuiltinRunner::new(Some(1), 6, true).into()), } } diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 626dba0a2e..bb902b8bd4 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -32,7 +32,7 @@ use core::num::NonZeroUsize; use num_traits::{ToPrimitive, Zero}; use super::errors::runner_errors::RunnerError; -use super::runners::builtin_runner::OUTPUT_BUILTIN_NAME; +use super::runners::builtin_runner::{OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME}; const MAX_TRACEBACK_ENTRIES: u32 = 20; @@ -925,7 +925,7 @@ impl VirtualMachine { pub fn get_range_check_builtin(&self) -> Result<&RangeCheckBuiltinRunner, VirtualMachineError> { for builtin in &self.builtin_runners { if let BuiltinRunner::RangeCheck(range_check_builtin) = builtin { - if matches!(range_check_builtin.name(), RANGE_CHECK_BUILTIN_NAME) { + if range_check_builtin.name() == RANGE_CHECK_BUILTIN_NAME { return Ok(range_check_builtin); } }; From 44a5e8df222a690c5b946dd9904e93bbb5b0463c Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Apr 2024 13:32:35 -0300 Subject: [PATCH 03/11] Clippy --- vm/src/hint_processor/builtin_hint_processor/math_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index c26396b437..9cb63d265c 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -176,7 +176,7 @@ pub fn assert_le_felt_v_0_8( } let bound = vm.get_range_check_builtin()?.bound(); let small_inputs = - Felt252::from((a.as_ref() < &bound && b.as_ref() - a.as_ref() < *bound) as u8); + Felt252::from((a.as_ref() < bound && b.as_ref() - a.as_ref() < *bound) as u8); insert_value_from_var_name("small_inputs", small_inputs, vm, ids_data, ap_tracking) } From 5d5c9af94a919eee18bc9e193281cc97aaeb4256 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Apr 2024 14:05:23 -0300 Subject: [PATCH 04/11] Add specialized constructors & remove n_parts field from instance def --- .../builtins_instance_def.rs | 8 +- .../range_check_instance_def.rs | 44 ++--------- vm/src/utils.rs | 7 +- vm/src/vm/runners/builtin_runner/mod.rs | 37 ++++++---- .../vm/runners/builtin_runner/range_check.rs | 74 +++++++++++-------- vm/src/vm/runners/cairo_runner.rs | 27 ++----- vm/src/vm/vm_memory/memory.rs | 8 +- 7 files changed, 92 insertions(+), 113 deletions(-) diff --git a/vm/src/types/instance_definitions/builtins_instance_def.rs b/vm/src/types/instance_definitions/builtins_instance_def.rs index 22c2cbd3e3..360b246e59 100644 --- a/vm/src/types/instance_definitions/builtins_instance_def.rs +++ b/vm/src/types/instance_definitions/builtins_instance_def.rs @@ -80,7 +80,7 @@ impl BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, pedersen: Some(PedersenInstanceDef::new(Some(32), 1)), - range_check: Some(RangeCheckInstanceDef::new(Some(16), 8)), + range_check: Some(RangeCheckInstanceDef::new(Some(16))), ecdsa: Some(EcdsaInstanceDef::new(Some(2048))), bitwise: Some(BitwiseInstanceDef::new(Some(64))), ec_op: Some(EcOpInstanceDef::new(Some(1024))), @@ -94,7 +94,7 @@ impl BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, pedersen: Some(PedersenInstanceDef::new(Some(32), 1)), - range_check: Some(RangeCheckInstanceDef::new(Some(16), 8)), + range_check: Some(RangeCheckInstanceDef::new(Some(16))), ecdsa: Some(EcdsaInstanceDef::new(Some(2048))), bitwise: Some(BitwiseInstanceDef::new(Some(64))), ec_op: Some(EcOpInstanceDef::new(Some(1024))), @@ -128,7 +128,7 @@ impl BuiltinsInstanceDef { ec_op: Some(EcOpInstanceDef::new(Some(1024))), keccak: Some(KeccakInstanceDef::new(Some(2048), vec![200; 8])), poseidon: Some(PoseidonInstanceDef::new(Some(256))), - range_check96: Some(RangeCheckInstanceDef::new(Some(8), 6)), + range_check96: Some(RangeCheckInstanceDef::new(Some(8))), } } @@ -150,7 +150,7 @@ impl BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, pedersen: Some(PedersenInstanceDef::new(None, 4)), - range_check: Some(RangeCheckInstanceDef::new(None, 8)), + range_check: Some(RangeCheckInstanceDef::new(None)), ecdsa: Some(EcdsaInstanceDef::new(None)), bitwise: Some(BitwiseInstanceDef::new(None)), ec_op: Some(EcOpInstanceDef::new(None)), diff --git a/vm/src/types/instance_definitions/range_check_instance_def.rs b/vm/src/types/instance_definitions/range_check_instance_def.rs index ad46df54c6..de9fa51da3 100644 --- a/vm/src/types/instance_definitions/range_check_instance_def.rs +++ b/vm/src/types/instance_definitions/range_check_instance_def.rs @@ -4,27 +4,15 @@ pub(crate) const CELLS_PER_RANGE_CHECK: u32 = 1; #[derive(Serialize, Debug, PartialEq)] pub(crate) struct RangeCheckInstanceDef { pub(crate) ratio: Option, - pub(crate) n_parts: u32, } impl RangeCheckInstanceDef { pub(crate) fn default() -> Self { - RangeCheckInstanceDef { - ratio: Some(8), - n_parts: 8, - } + RangeCheckInstanceDef { ratio: Some(8) } } - pub(crate) fn new(ratio: Option, n_parts: u32) -> Self { - RangeCheckInstanceDef { ratio, n_parts } - } - - pub(crate) fn _cells_per_builtin(&self) -> u32 { - CELLS_PER_RANGE_CHECK - } - - pub(crate) fn _range_check_units_per_builtin(&self) -> u32 { - self.n_parts + pub(crate) fn new(ratio: Option) -> Self { + RangeCheckInstanceDef { ratio } } } @@ -35,37 +23,17 @@ mod tests { #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_range_check_units_per_builtin() { - let builtin_instance = RangeCheckInstanceDef::default(); - assert_eq!(builtin_instance._range_check_units_per_builtin(), 8); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_cells_per_builtin() { - let builtin_instance = RangeCheckInstanceDef::default(); - assert_eq!(builtin_instance._cells_per_builtin(), 1); - } - #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { - let builtin_instance = RangeCheckInstanceDef { - ratio: Some(10), - n_parts: 10, - }; - assert_eq!(RangeCheckInstanceDef::new(Some(10), 10), builtin_instance); + let builtin_instance = RangeCheckInstanceDef { ratio: Some(10) }; + assert_eq!(RangeCheckInstanceDef::new(Some(10)), builtin_instance); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { - let builtin_instance = RangeCheckInstanceDef { - ratio: Some(8), - n_parts: 8, - }; + let builtin_instance = RangeCheckInstanceDef { ratio: Some(8) }; assert_eq!(RangeCheckInstanceDef::default(), builtin_instance); } } diff --git a/vm/src/utils.rs b/vm/src/utils.rs index 8432a5cd79..bcd644519f 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -236,8 +236,11 @@ pub mod test_utils { () => {{ let mut vm = VirtualMachine::new(false); vm.builtin_runners = vec![ - $crate::vm::runners::builtin_runner::RangeCheckBuiltinRunner::new(Some(8), 8, true) - .into(), + $crate::vm::runners::builtin_runner::RangeCheckBuiltinRunner::new_standard( + Some(8), + true, + ) + .into(), ]; vm }}; diff --git a/vm/src/vm/runners/builtin_runner/mod.rs b/vm/src/vm/runners/builtin_runner/mod.rs index 74f61ae771..9a93ce0400 100644 --- a/vm/src/vm/runners/builtin_runner/mod.rs +++ b/vm/src/vm/runners/builtin_runner/mod.rs @@ -656,7 +656,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_n_input_cells_range_check() { - let range_check = RangeCheckBuiltinRunner::new(Some(10), 10, true); + let range_check = RangeCheckBuiltinRunner::new_standard(Some(10), true); let builtin: BuiltinRunner = range_check.clone().into(); assert_eq!(range_check.n_input_cells, builtin.n_input_cells()) } @@ -704,7 +704,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_cells_per_instance_range_check() { - let range_check = RangeCheckBuiltinRunner::new(Some(10), 10, true); + let range_check = RangeCheckBuiltinRunner::new_standard(Some(10), true); let builtin: BuiltinRunner = range_check.clone().into(); assert_eq!(range_check.cells_per_instance, builtin.cells_per_instance()) } @@ -760,7 +760,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_name_range_check() { - let range_check = RangeCheckBuiltinRunner::new(Some(10), 10, true); + let range_check = RangeCheckBuiltinRunner::new_standard(Some(10), true); let builtin: BuiltinRunner = range_check.into(); assert_eq!(RANGE_CHECK_BUILTIN_NAME, builtin.name()) } @@ -930,7 +930,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_range_check_with_items() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(10), 12, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(10), true)); let mut vm = vm!(); @@ -1017,7 +1018,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_range_check() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); let mut vm = vm!(); vm.current_step = 8; assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(1)); @@ -1069,7 +1071,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_range_check() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)]; assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4))); } @@ -1160,7 +1163,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_diluted_check_units_range_check() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0); } @@ -1185,7 +1189,7 @@ mod tests { let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into(); assert_eq!(output_builtin.get_memory_segment_addresses(), (0, None),); let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); assert_eq!( range_check_builtin.get_memory_segment_addresses(), (0, None), @@ -1321,7 +1325,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_range_check_missing_memory_cells_with_offsets() { - let range_check_builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let range_check_builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let builtin: BuiltinRunner = range_check_builtin.into(); let mut vm = vm!(); @@ -1346,7 +1350,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_range_check_missing_memory_cells() { let builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); let mut vm = vm!(); vm.segments.memory = memory![((0, 1), 1)]; @@ -1362,7 +1366,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_range_check_empty() { - let range_check_builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let range_check_builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let builtin: BuiltinRunner = range_check_builtin.into(); @@ -1560,7 +1564,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_perm_range_check_units_range_check() { - let builtin_runner: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(8), 8, true).into(); + let builtin_runner: BuiltinRunner = + RangeCheckBuiltinRunner::new_standard(Some(8), true).into(); let mut vm = vm!(); vm.current_step = 8; @@ -1582,7 +1587,7 @@ mod tests { let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into(); assert_eq!(output_builtin.ratio(), None,); let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); assert_eq!(range_check_builtin.ratio(), (Some(8)),); let keccak_builtin: BuiltinRunner = KeccakBuiltinRunner::new(&KeccakInstanceDef::default(), true).into(); @@ -1637,7 +1642,7 @@ mod tests { vm.segments.segment_used_sizes = Some(vec![4]); let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); assert_eq!(range_check_builtin.get_used_instances(&vm.segments), Ok(4)); } @@ -1652,7 +1657,7 @@ mod tests { BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), false)), BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)), BuiltinRunner::Output(OutputBuiltinRunner::new(false)), - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, false)), + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), false)), BuiltinRunner::Keccak(KeccakBuiltinRunner::new( &KeccakInstanceDef::default(), false, @@ -1680,7 +1685,7 @@ mod tests { BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), false)), BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)), BuiltinRunner::Output(OutputBuiltinRunner::new(false)), - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, false)), + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), false)), BuiltinRunner::Keccak(KeccakBuiltinRunner::new( &KeccakInstanceDef::default(), false, diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index e3a701f818..9059ca9e4f 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -56,15 +56,22 @@ pub struct RangeCheckBuiltinRunner { } impl RangeCheckBuiltinRunner { - pub fn new(ratio: Option, n_parts: u32, included: bool) -> RangeCheckBuiltinRunner { + pub fn new_standard(ratio: Option, included: bool) -> RangeCheckBuiltinRunner { + RangeCheckBuiltinRunner::new(ratio, RangeCheckType::Standard, included) + } + pub fn new_96(ratio: Option, included: bool) -> RangeCheckBuiltinRunner { + RangeCheckBuiltinRunner::new(ratio, RangeCheckType::NinetySix, included) + } + + fn new( + ratio: Option, + range_check_type: RangeCheckType, + included: bool, + ) -> RangeCheckBuiltinRunner { RangeCheckBuiltinRunner { ratio, base: 0, - range_check_type: if n_parts == N_PARTS_96 as u32 { - RangeCheckType::NinetySix - } else { - RangeCheckType::Standard - }, + range_check_type, stop_ptr: None, cells_per_instance: CELLS_PER_RANGE_CHECK, n_input_cells: CELLS_PER_RANGE_CHECK, @@ -264,7 +271,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { - let builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -275,7 +282,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); let mut vm = vm!(); @@ -299,7 +306,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); let mut vm = vm!(); @@ -327,7 +334,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_notincluded() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, false); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), false); let mut vm = vm!(); @@ -351,7 +358,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); let mut vm = vm!(); @@ -377,7 +384,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_test() { - let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(10), 12, true).into(); + let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new_standard(Some(10), true).into(); let mut vm = vm!(); @@ -423,7 +430,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { - let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(10), 12, true).into(); + let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new_standard(Some(10), true).into(); let mut vm = vm!(); @@ -467,7 +474,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn initialize_segments_for_range_check() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); assert_eq!(builtin.base, 0); @@ -476,7 +483,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_initial_stack_for_range_check_with_base() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); builtin.base = 1; let initial_stack = builtin.initial_stack(); assert_eq!( @@ -489,7 +496,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_segment_addresses() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); assert_eq!(builtin.get_memory_segment_addresses(), (0, None),); } @@ -497,7 +504,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_missing_segment_used_sizes() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); let vm = vm!(); assert_eq!( @@ -509,7 +517,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_empty() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -519,7 +528,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -537,21 +547,22 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_base() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); assert_eq!(builtin.base(), 0); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_ratio() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); assert_eq!(builtin.ratio(), Some(8)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_missing_segment_used_sizes() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); let vm = vm!(); assert_eq!( @@ -563,7 +574,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_empty() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -573,7 +585,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); + let builtin = + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -583,7 +596,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_a() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)]; assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4))); } @@ -591,7 +604,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_b() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let memory = memory![ ((0, 0), 1465218365), ((0, 1), 2134570341), @@ -604,7 +617,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_c() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let memory = memory![ ((0, 0), 634834751465218365_i64), ((0, 1), 42876922134570341_i64), @@ -619,7 +632,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_empty_memory() { - let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let memory = Memory::new(); assert_eq!(builtin.get_range_check_usage(&memory), None); } @@ -628,7 +641,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_perm_range_check_units() { - let builtin_runner: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(8), 8, true).into(); + let builtin_runner: BuiltinRunner = + RangeCheckBuiltinRunner::new_standard(Some(8), true).into(); let mut vm = vm!(); vm.current_step = 8; @@ -639,7 +653,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_air_private_input() { - let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new(None, 4, true).into(); + let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new_standard(None, true).into(); let memory = memory![((0, 0), 0), ((0, 1), 1), ((0, 2), 2)]; assert_eq!( diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 7b34c1ac66..a3b119c574 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -285,12 +285,7 @@ impl CairoRunner { let included = program_builtins.remove(&BuiltinName::range_check); if included || self.is_proof_mode() { builtin_runners.push( - RangeCheckBuiltinRunner::new( - instance_def.ratio, - instance_def.n_parts, - included, - ) - .into(), + RangeCheckBuiltinRunner::new_standard(instance_def.ratio, included).into(), ); } } @@ -334,14 +329,8 @@ impl CairoRunner { if let Some(instance_def) = self.layout.builtins.range_check96.as_ref() { let included = program_builtins.remove(&BuiltinName::range_check96); if included || self.is_proof_mode() { - builtin_runners.push( - RangeCheckBuiltinRunner::new( - instance_def.ratio, - instance_def.n_parts, - included, - ) - .into(), - ); + builtin_runners + .push(RangeCheckBuiltinRunner::new_96(instance_def.ratio, included).into()); } } if !program_builtins.is_empty() && !allow_missing_builtins { @@ -389,7 +378,7 @@ impl CairoRunner { .push(HashBuiltinRunner::new(Some(32), true).into()), BuiltinName::range_check => vm .builtin_runners - .push(RangeCheckBuiltinRunner::new(Some(1), 8, true).into()), + .push(RangeCheckBuiltinRunner::new_standard(Some(1), true).into()), BuiltinName::output => vm .builtin_runners .push(OutputBuiltinRunner::new(true).into()), @@ -417,7 +406,7 @@ impl CairoRunner { } BuiltinName::range_check96 => vm .builtin_runners - .push(RangeCheckBuiltinRunner::new(Some(1), 6, true).into()), + .push(RangeCheckBuiltinRunner::new_96(Some(1), true).into()), } } @@ -4093,7 +4082,7 @@ mod tests { vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(12), 5, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new_standard(Some(12), true).into()]; assert_matches!( cairo_runner.get_perm_range_check_limits(&vm), @@ -4147,7 +4136,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(8), 8, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new_standard(Some(8), true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; @@ -4214,7 +4203,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(8), 8, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new_standard(Some(8), true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs index f50d5c11cd..5d4c26a20f 100644 --- a/vm/src/vm/vm_memory/memory.rs +++ b/vm/src/vm/vm_memory/memory.rs @@ -779,7 +779,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_within_bounds() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); builtin.add_validation_rule(&mut segments.memory); @@ -804,7 +804,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_outside_bounds() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let mut segments = MemorySegmentManager::new(); segments.add(); builtin.initialize_segments(&mut segments); @@ -895,7 +895,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_relocatable_value() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); segments.memory = memory![((0, 0), (0, 4))]; @@ -912,7 +912,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_out_of_bounds_diff_segment() { - let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); + let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); let mut segments = MemorySegmentManager::new(); segments.memory = Memory::new(); segments.add(); From 5bb49022df0ed7108b0d1947e5f94c08c297c1ae Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Apr 2024 14:18:57 -0300 Subject: [PATCH 05/11] Add changelog entry --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0619cbc798..1057c17c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ #### Upcoming Changes +* feat(BREAKING): Add range_check96 builtin[#1698](https://github.com/lambdaclass/cairo-vm/pull/1698) + * Add the new `range_check96` builtin to the `all_cairo` layout. + * `RangeCheckBuiltinRunner` changes: + * Method `new` is now private, `new_standard` & `new_96` were added to replace its functionality, these methods no longer allow the caller to set a value for `n_parts` and instead rely on constants based on the range_check variant. + * Remove field `_bound`, replacing it with public method `bound`. + * Add public methods `name` & `n_parts`. + * BREAKING: Remove `CairoRunner::add_additional_hash_builtin` & `VirtualMachine::disable_trace`[#1658](https://github.com/lambdaclass/cairo-vm/pull/1658) * feat: output builtin add_attribute method [#1691](https://github.com/lambdaclass/cairo-vm/pull/1691) From 9cb59a916182e9a07dfba60b0b76e877651e112c Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Apr 2024 16:57:09 -0300 Subject: [PATCH 06/11] fmt --- vm/src/vm/vm_core.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 5c8597ebd9..9dccf59757 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -32,7 +32,9 @@ use core::num::NonZeroUsize; use num_traits::{ToPrimitive, Zero}; use super::errors::runner_errors::RunnerError; -use super::runners::builtin_runner::{OutputBuiltinRunner, OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME}; +use super::runners::builtin_runner::{ + OutputBuiltinRunner, OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, +}; const MAX_TRACEBACK_ENTRIES: u32 = 20; From c0617abe06de94fba440509f582d3cfc7d1ebe1d Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 5 Apr 2024 16:13:43 -0300 Subject: [PATCH 07/11] Use const generic to differentiate between RangeCheck and RangeCheck96 --- CHANGELOG.md | 3 +- vm/src/utils.rs | 2 +- vm/src/vm/runners/builtin_runner/mod.rs | 115 ++++++++++---- .../vm/runners/builtin_runner/range_check.rs | 140 ++++++++---------- vm/src/vm/runners/cairo_runner.rs | 33 +++-- vm/src/vm/vm_core.rs | 10 +- vm/src/vm/vm_memory/memory.rs | 12 +- 7 files changed, 184 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ff9ef375d..a4e06a0061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ * feat(BREAKING): Add range_check96 builtin[#1698](https://github.com/lambdaclass/cairo-vm/pull/1698) * Add the new `range_check96` builtin to the `all_cairo` layout. * `RangeCheckBuiltinRunner` changes: - * Method `new` is now private, `new_standard` & `new_96` were added to replace its functionality, these methods no longer allow the caller to set a value for `n_parts` and instead rely on constants based on the range_check variant. + * Remove field `n_parts`, replacing it with const generic `N_PARTS`. + * Remome `n_parts` argument form method `new`. * Remove field `_bound`, replacing it with public method `bound`. * Add public methods `name` & `n_parts`. diff --git a/vm/src/utils.rs b/vm/src/utils.rs index bcd644519f..4ec902dcfb 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -236,7 +236,7 @@ pub mod test_utils { () => {{ let mut vm = VirtualMachine::new(false); vm.builtin_runners = vec![ - $crate::vm::runners::builtin_runner::RangeCheckBuiltinRunner::new_standard( + $crate::vm::runners::builtin_runner::RangeCheckBuiltinRunner::<8>::new( Some(8), true, ) diff --git a/vm/src/vm/runners/builtin_runner/mod.rs b/vm/src/vm/runners/builtin_runner/mod.rs index 9a93ce0400..1df25cea36 100644 --- a/vm/src/vm/runners/builtin_runner/mod.rs +++ b/vm/src/vm/runners/builtin_runner/mod.rs @@ -21,6 +21,7 @@ mod signature; pub use self::keccak::KeccakBuiltinRunner; pub use self::poseidon::PoseidonBuiltinRunner; +pub(crate) use self::range_check::{RC_N_PARTS_96, RC_N_PARTS_STANDARD}; pub use self::segment_arena::SegmentArenaBuiltinRunner; pub use bitwise::BitwiseBuiltinRunner; pub use ec_op::EcOpBuiltinRunner; @@ -57,7 +58,8 @@ pub enum BuiltinRunner { EcOp(EcOpBuiltinRunner), Hash(HashBuiltinRunner), Output(OutputBuiltinRunner), - RangeCheck(RangeCheckBuiltinRunner), + RangeCheck(RangeCheckBuiltinRunner), + RangeCheck96(RangeCheckBuiltinRunner), Keccak(KeccakBuiltinRunner), Signature(SignatureBuiltinRunner), Poseidon(PoseidonBuiltinRunner), @@ -75,6 +77,9 @@ impl BuiltinRunner { BuiltinRunner::RangeCheck(ref mut range_check) => { range_check.initialize_segments(segments) } + BuiltinRunner::RangeCheck96(ref mut range_check) => { + range_check.initialize_segments(segments) + } BuiltinRunner::Keccak(ref mut keccak) => keccak.initialize_segments(segments), BuiltinRunner::Signature(ref mut signature) => signature.initialize_segments(segments), BuiltinRunner::Poseidon(ref mut poseidon) => poseidon.initialize_segments(segments), @@ -91,6 +96,7 @@ impl BuiltinRunner { BuiltinRunner::Hash(ref hash) => hash.initial_stack(), BuiltinRunner::Output(ref output) => output.initial_stack(), BuiltinRunner::RangeCheck(ref range_check) => range_check.initial_stack(), + BuiltinRunner::RangeCheck96(ref range_check) => range_check.initial_stack(), BuiltinRunner::Keccak(ref keccak) => keccak.initial_stack(), BuiltinRunner::Signature(ref signature) => signature.initial_stack(), BuiltinRunner::Poseidon(ref poseidon) => poseidon.initial_stack(), @@ -112,6 +118,9 @@ impl BuiltinRunner { BuiltinRunner::RangeCheck(ref mut range_check) => { range_check.final_stack(segments, stack_pointer) } + BuiltinRunner::RangeCheck96(ref mut range_check) => { + range_check.final_stack(segments, stack_pointer) + } BuiltinRunner::Keccak(ref mut keccak) => keccak.final_stack(segments, stack_pointer), BuiltinRunner::Signature(ref mut signature) => { signature.final_stack(segments, stack_pointer) @@ -169,6 +178,7 @@ impl BuiltinRunner { BuiltinRunner::Hash(ref hash) => hash.base(), BuiltinRunner::Output(ref output) => output.base(), BuiltinRunner::RangeCheck(ref range_check) => range_check.base(), + BuiltinRunner::RangeCheck96(ref range_check) => range_check.base(), BuiltinRunner::Keccak(ref keccak) => keccak.base(), BuiltinRunner::Signature(ref signature) => signature.base(), BuiltinRunner::Poseidon(ref poseidon) => poseidon.base(), @@ -184,6 +194,7 @@ impl BuiltinRunner { BuiltinRunner::Hash(hash) => hash.ratio(), BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => None, BuiltinRunner::RangeCheck(range_check) => range_check.ratio(), + BuiltinRunner::RangeCheck96(range_check) => range_check.ratio(), BuiltinRunner::Keccak(keccak) => keccak.ratio(), BuiltinRunner::Signature(ref signature) => signature.ratio(), BuiltinRunner::Poseidon(poseidon) => poseidon.ratio(), @@ -197,6 +208,7 @@ impl BuiltinRunner { BuiltinRunner::Hash(ref hash) => hash.add_validation_rule(memory), BuiltinRunner::Output(ref output) => output.add_validation_rule(memory), BuiltinRunner::RangeCheck(ref range_check) => range_check.add_validation_rule(memory), + BuiltinRunner::RangeCheck96(ref range_check) => range_check.add_validation_rule(memory), BuiltinRunner::Keccak(ref keccak) => keccak.add_validation_rule(memory), BuiltinRunner::Signature(ref signature) => signature.add_validation_rule(memory), BuiltinRunner::Poseidon(ref poseidon) => poseidon.add_validation_rule(memory), @@ -219,6 +231,9 @@ impl BuiltinRunner { BuiltinRunner::RangeCheck(ref range_check) => { range_check.deduce_memory_cell(address, memory) } + BuiltinRunner::RangeCheck96(ref range_check) => { + range_check.deduce_memory_cell(address, memory) + } BuiltinRunner::Keccak(ref keccak) => keccak.deduce_memory_cell(address, memory), BuiltinRunner::Signature(ref signature) => { signature.deduce_memory_cell(address, memory) @@ -257,6 +272,9 @@ impl BuiltinRunner { BuiltinRunner::RangeCheck(ref range_check) => { range_check.get_memory_segment_addresses() } + BuiltinRunner::RangeCheck96(ref range_check) => { + range_check.get_memory_segment_addresses() + } BuiltinRunner::Keccak(ref keccak) => keccak.get_memory_segment_addresses(), BuiltinRunner::Signature(ref signature) => signature.get_memory_segment_addresses(), BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_memory_segment_addresses(), @@ -273,6 +291,7 @@ impl BuiltinRunner { BuiltinRunner::Hash(ref hash) => hash.get_used_cells(segments), BuiltinRunner::Output(ref output) => output.get_used_cells(segments), BuiltinRunner::RangeCheck(ref range_check) => range_check.get_used_cells(segments), + BuiltinRunner::RangeCheck96(ref range_check) => range_check.get_used_cells(segments), BuiltinRunner::Keccak(ref keccak) => keccak.get_used_cells(segments), BuiltinRunner::Signature(ref signature) => signature.get_used_cells(segments), BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_cells(segments), @@ -292,6 +311,9 @@ impl BuiltinRunner { BuiltinRunner::Hash(ref hash) => hash.get_used_instances(segments), BuiltinRunner::Output(ref output) => output.get_used_instances(segments), BuiltinRunner::RangeCheck(ref range_check) => range_check.get_used_instances(segments), + BuiltinRunner::RangeCheck96(ref range_check) => { + range_check.get_used_instances(segments) + } BuiltinRunner::Keccak(ref keccak) => keccak.get_used_instances(segments), BuiltinRunner::Signature(ref signature) => signature.get_used_instances(segments), BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_instances(segments), @@ -304,6 +326,9 @@ impl BuiltinRunner { pub fn get_range_check_usage(&self, memory: &Memory) -> Option<(usize, usize)> { match self { BuiltinRunner::RangeCheck(ref range_check) => range_check.get_range_check_usage(memory), + BuiltinRunner::RangeCheck96(ref range_check) => { + range_check.get_range_check_usage(memory) + } _ => None, } } @@ -318,6 +343,10 @@ impl BuiltinRunner { let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?; Ok(used_cells * range_check.n_parts() as usize) } + BuiltinRunner::RangeCheck96(range_check) => { + let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?; + Ok(used_cells * range_check.n_parts() as usize) + } _ => Ok(0), } } @@ -340,6 +369,7 @@ impl BuiltinRunner { BuiltinRunner::EcOp(builtin) => builtin.cells_per_instance, BuiltinRunner::Hash(builtin) => builtin.cells_per_instance, BuiltinRunner::RangeCheck(builtin) => builtin.cells_per_instance, + BuiltinRunner::RangeCheck96(builtin) => builtin.cells_per_instance, BuiltinRunner::Output(_) => 0, BuiltinRunner::Keccak(builtin) => builtin.cells_per_instance, BuiltinRunner::Signature(builtin) => builtin.cells_per_instance, @@ -354,6 +384,7 @@ impl BuiltinRunner { BuiltinRunner::EcOp(builtin) => builtin.n_input_cells, BuiltinRunner::Hash(builtin) => builtin.n_input_cells, BuiltinRunner::RangeCheck(builtin) => builtin.n_input_cells, + BuiltinRunner::RangeCheck96(builtin) => builtin.n_input_cells, BuiltinRunner::Output(_) => 0, BuiltinRunner::Keccak(builtin) => builtin.n_input_cells, BuiltinRunner::Signature(builtin) => builtin.n_input_cells, @@ -368,6 +399,7 @@ impl BuiltinRunner { BuiltinRunner::EcOp(builtin) => builtin.instances_per_component, BuiltinRunner::Hash(builtin) => builtin.instances_per_component, BuiltinRunner::RangeCheck(builtin) => builtin.instances_per_component, + BuiltinRunner::RangeCheck96(builtin) => builtin.instances_per_component, BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => 1, BuiltinRunner::Keccak(builtin) => builtin.instances_per_component, BuiltinRunner::Signature(builtin) => builtin.instances_per_component, @@ -380,7 +412,8 @@ impl BuiltinRunner { BuiltinRunner::Bitwise(_) => BITWISE_BUILTIN_NAME, BuiltinRunner::EcOp(_) => EC_OP_BUILTIN_NAME, BuiltinRunner::Hash(_) => HASH_BUILTIN_NAME, - BuiltinRunner::RangeCheck(b) => b.name(), + BuiltinRunner::RangeCheck(_) => RANGE_CHECK_BUILTIN_NAME, + BuiltinRunner::RangeCheck96(_) => RANGE_CHECK_96_BUILTIN_NAME, BuiltinRunner::Output(_) => OUTPUT_BUILTIN_NAME, BuiltinRunner::Keccak(_) => KECCAK_BUILTIN_NAME, BuiltinRunner::Signature(_) => SIGNATURE_BUILTIN_NAME, @@ -489,6 +522,7 @@ impl BuiltinRunner { pub fn air_private_input(&self, memory: &Memory) -> Vec { match self { BuiltinRunner::RangeCheck(builtin) => builtin.air_private_input(memory), + BuiltinRunner::RangeCheck96(builtin) => builtin.air_private_input(memory), BuiltinRunner::Bitwise(builtin) => builtin.air_private_input(memory), BuiltinRunner::Hash(builtin) => builtin.air_private_input(memory), BuiltinRunner::EcOp(builtin) => builtin.air_private_input(memory), @@ -507,6 +541,9 @@ impl BuiltinRunner { BuiltinRunner::Hash(ref mut hash) => hash.stop_ptr = Some(stop_ptr), BuiltinRunner::Output(ref mut output) => output.stop_ptr = Some(stop_ptr), BuiltinRunner::RangeCheck(ref mut range_check) => range_check.stop_ptr = Some(stop_ptr), + BuiltinRunner::RangeCheck96(ref mut range_check) => { + range_check.stop_ptr = Some(stop_ptr) + } BuiltinRunner::Keccak(ref mut keccak) => keccak.stop_ptr = Some(stop_ptr), BuiltinRunner::Signature(ref mut signature) => signature.stop_ptr = Some(stop_ptr), BuiltinRunner::Poseidon(ref mut poseidon) => poseidon.stop_ptr = Some(stop_ptr), @@ -547,12 +584,18 @@ impl From for BuiltinRunner { } } -impl From for BuiltinRunner { - fn from(runner: RangeCheckBuiltinRunner) -> Self { +impl From> for BuiltinRunner { + fn from(runner: RangeCheckBuiltinRunner) -> Self { BuiltinRunner::RangeCheck(runner) } } +impl From> for BuiltinRunner { + fn from(runner: RangeCheckBuiltinRunner) -> Self { + BuiltinRunner::RangeCheck96(runner) + } +} + impl From for BuiltinRunner { fn from(runner: SignatureBuiltinRunner) -> Self { BuiltinRunner::Signature(runner) @@ -656,7 +699,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_n_input_cells_range_check() { - let range_check = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let range_check = RangeCheckBuiltinRunner::::new(Some(10), true); let builtin: BuiltinRunner = range_check.clone().into(); assert_eq!(range_check.n_input_cells, builtin.n_input_cells()) } @@ -704,7 +747,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_cells_per_instance_range_check() { - let range_check = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let range_check = RangeCheckBuiltinRunner::::new(Some(10), true); let builtin: BuiltinRunner = range_check.clone().into(); assert_eq!(range_check.cells_per_instance, builtin.cells_per_instance()) } @@ -760,7 +803,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_name_range_check() { - let range_check = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let range_check = RangeCheckBuiltinRunner::::new(Some(10), true); let builtin: BuiltinRunner = range_check.into(); assert_eq!(RANGE_CHECK_BUILTIN_NAME, builtin.name()) } @@ -930,8 +973,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_range_check_with_items() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(10), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(10), true), + ); let mut vm = vm!(); @@ -1018,8 +1062,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_range_check() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(8), true), + ); let mut vm = vm!(); vm.current_step = 8; assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(1)); @@ -1071,8 +1116,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_range_check() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(8), true), + ); let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)]; assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4))); } @@ -1163,8 +1209,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_diluted_check_units_range_check() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(8), true), + ); assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0); } @@ -1188,8 +1235,9 @@ mod tests { assert_eq!(hash_builtin.get_memory_segment_addresses(), (0, None),); let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into(); assert_eq!(output_builtin.get_memory_segment_addresses(), (0, None),); - let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(8), true), + ); assert_eq!( range_check_builtin.get_memory_segment_addresses(), (0, None), @@ -1325,7 +1373,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_range_check_missing_memory_cells_with_offsets() { - let range_check_builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let range_check_builtin = + RangeCheckBuiltinRunner::::new(Some(8), true); let builtin: BuiltinRunner = range_check_builtin.into(); let mut vm = vm!(); @@ -1349,8 +1398,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_range_check_missing_memory_cells() { - let builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let builtin: BuiltinRunner = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::< + RC_N_PARTS_STANDARD, + >::new(Some(8), true)); let mut vm = vm!(); vm.segments.memory = memory![((0, 1), 1)]; @@ -1366,7 +1416,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_range_check_empty() { - let range_check_builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let range_check_builtin = + RangeCheckBuiltinRunner::::new(Some(8), true); let builtin: BuiltinRunner = range_check_builtin.into(); @@ -1565,7 +1616,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_perm_range_check_units_range_check() { let builtin_runner: BuiltinRunner = - RangeCheckBuiltinRunner::new_standard(Some(8), true).into(); + RangeCheckBuiltinRunner::::new(Some(8), true).into(); let mut vm = vm!(); vm.current_step = 8; @@ -1586,8 +1637,9 @@ mod tests { assert_eq!(hash_builtin.ratio(), (Some(8)),); let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into(); assert_eq!(output_builtin.ratio(), None,); - let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(8), true), + ); assert_eq!(range_check_builtin.ratio(), (Some(8)),); let keccak_builtin: BuiltinRunner = KeccakBuiltinRunner::new(&KeccakInstanceDef::default(), true).into(); @@ -1641,8 +1693,9 @@ mod tests { let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); - let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), true)); + let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(8), true), + ); assert_eq!(range_check_builtin.get_used_instances(&vm.segments), Ok(4)); } @@ -1657,7 +1710,10 @@ mod tests { BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), false)), BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)), BuiltinRunner::Output(OutputBuiltinRunner::new(false)), - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), false)), + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::::new( + Some(8), + false, + )), BuiltinRunner::Keccak(KeccakBuiltinRunner::new( &KeccakInstanceDef::default(), false, @@ -1685,7 +1741,10 @@ mod tests { BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), false)), BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)), BuiltinRunner::Output(OutputBuiltinRunner::new(false)), - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(8), false)), + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::::new( + Some(8), + false, + )), BuiltinRunner::Keccak(KeccakBuiltinRunner::new( &KeccakInstanceDef::default(), false, diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index 9059ca9e4f..2f821e1533 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -28,26 +28,19 @@ use super::{RANGE_CHECK_96_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME}; const INNER_RC_BOUND_SHIFT: u64 = 16; const INNER_RC_BOUND_MASK: u64 = u16::MAX as u64; -const N_PARTS_STANDARD: u64 = 8; -const N_PARTS_96: u64 = 6; +pub const RC_N_PARTS_STANDARD: u64 = 8; +pub const RC_N_PARTS_96: u64 = 6; lazy_static! { pub static ref BOUND_STANDARD: Felt252 = - Felt252::TWO.pow(INNER_RC_BOUND_SHIFT * N_PARTS_STANDARD); - pub static ref BOUND_96: Felt252 = Felt252::TWO.pow(INNER_RC_BOUND_SHIFT * N_PARTS_96); + Felt252::TWO.pow(INNER_RC_BOUND_SHIFT * RC_N_PARTS_STANDARD); + pub static ref BOUND_96: Felt252 = Felt252::TWO.pow(INNER_RC_BOUND_SHIFT * RC_N_PARTS_96); } #[derive(Debug, Clone)] -enum RangeCheckType { - Standard, // range_check, n_parts = 8 - NinetySix, // range_check96, n_parts = 6 -} - -#[derive(Debug, Clone)] -pub struct RangeCheckBuiltinRunner { +pub struct RangeCheckBuiltinRunner { ratio: Option, base: usize, - range_check_type: RangeCheckType, pub(crate) stop_ptr: Option, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, @@ -55,23 +48,11 @@ pub struct RangeCheckBuiltinRunner { pub(crate) instances_per_component: u32, } -impl RangeCheckBuiltinRunner { - pub fn new_standard(ratio: Option, included: bool) -> RangeCheckBuiltinRunner { - RangeCheckBuiltinRunner::new(ratio, RangeCheckType::Standard, included) - } - pub fn new_96(ratio: Option, included: bool) -> RangeCheckBuiltinRunner { - RangeCheckBuiltinRunner::new(ratio, RangeCheckType::NinetySix, included) - } - - fn new( - ratio: Option, - range_check_type: RangeCheckType, - included: bool, - ) -> RangeCheckBuiltinRunner { +impl RangeCheckBuiltinRunner { + pub fn new(ratio: Option, included: bool) -> RangeCheckBuiltinRunner { RangeCheckBuiltinRunner { ratio, base: 0, - range_check_type, stop_ptr: None, cells_per_instance: CELLS_PER_RANGE_CHECK, n_input_cells: CELLS_PER_RANGE_CHECK, @@ -100,29 +81,26 @@ impl RangeCheckBuiltinRunner { self.ratio } - pub const fn n_parts(&self) -> u64 { - match self.range_check_type { - RangeCheckType::Standard => N_PARTS_STANDARD, - RangeCheckType::NinetySix => N_PARTS_96, + pub fn name(&self) -> &'static str { + match N_PARTS { + RC_N_PARTS_96 => RANGE_CHECK_96_BUILTIN_NAME, + _ => RANGE_CHECK_BUILTIN_NAME, } } - pub fn name(&self) -> &'static str { - match self.range_check_type { - RangeCheckType::Standard => RANGE_CHECK_BUILTIN_NAME, - RangeCheckType::NinetySix => RANGE_CHECK_96_BUILTIN_NAME, - } + pub fn n_parts(&self) -> u64 { + N_PARTS } pub fn bound(&self) -> &'static Felt252 { - match self.range_check_type { - RangeCheckType::Standard => &BOUND_STANDARD, - RangeCheckType::NinetySix => &BOUND_96, + match N_PARTS { + RC_N_PARTS_96 => &BOUND_96, + _ => &BOUND_STANDARD, } } - fn build_rule() -> ValidationRule { - ValidationRule(Box::new( + pub fn add_validation_rule(&self, memory: &mut Memory) { + let rule = ValidationRule(Box::new( |memory: &Memory, address: Relocatable| -> Result, MemoryError> { let num = memory .get_integer(address) @@ -132,18 +110,11 @@ impl RangeCheckBuiltinRunner { } else { Err(MemoryError::RangeCheckNumOutOfBounds(Box::new(( num.into_owned(), - Felt252::TWO.pow((N_PARTS_STANDARD * INNER_RC_BOUND_SHIFT) as u128), + Felt252::TWO.pow((N_PARTS * INNER_RC_BOUND_SHIFT) as u128), )))) } }, - )) - } - - pub fn add_validation_rule(&self, memory: &mut Memory) { - let rule = match self.range_check_type { - RangeCheckType::Standard => RangeCheckBuiltinRunner::build_rule::(), - RangeCheckType::NinetySix => RangeCheckBuiltinRunner::build_rule::(), - }; + )); memory.add_validation_rule(self.base, rule); } @@ -184,7 +155,7 @@ impl RangeCheckBuiltinRunner { .rev() .map(move |i| ((digit >> (i * INNER_RC_BOUND_SHIFT)) & INNER_RC_BOUND_MASK)) }) - .take(self.n_parts() as usize) + .take(N_PARTS as usize) .fold(rc_bounds, |mm, x| { (min(mm.0, x as usize), max(mm.1, x as usize)) }); @@ -271,7 +242,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(10), true); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -282,7 +253,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(10), true); let mut vm = vm!(); @@ -306,7 +277,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(10), true); let mut vm = vm!(); @@ -334,7 +305,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_notincluded() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), false); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(10), false); let mut vm = vm!(); @@ -358,7 +329,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(10), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(10), true); let mut vm = vm!(); @@ -384,7 +355,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_test() { - let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new_standard(Some(10), true).into(); + let builtin: BuiltinRunner = + RangeCheckBuiltinRunner::::new(Some(10), true).into(); let mut vm = vm!(); @@ -430,7 +402,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { - let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new_standard(Some(10), true).into(); + let builtin: BuiltinRunner = + RangeCheckBuiltinRunner::::new(Some(10), true).into(); let mut vm = vm!(); @@ -474,7 +447,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn initialize_segments_for_range_check() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); assert_eq!(builtin.base, 0); @@ -483,7 +456,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_initial_stack_for_range_check_with_base() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(8), true); builtin.base = 1; let initial_stack = builtin.initial_stack(); assert_eq!( @@ -496,7 +469,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_segment_addresses() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); assert_eq!(builtin.get_memory_segment_addresses(), (0, None),); } @@ -504,8 +477,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_missing_segment_used_sizes() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(256), true), + ); let vm = vm!(); assert_eq!( @@ -517,8 +491,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_empty() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(256), true), + ); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -528,8 +503,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(256), true), + ); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -547,22 +523,23 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_base() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); assert_eq!(builtin.base(), 0); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_ratio() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); assert_eq!(builtin.ratio(), Some(8)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_missing_segment_used_sizes() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(256), true), + ); let vm = vm!(); assert_eq!( @@ -574,8 +551,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_empty() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(256), true), + ); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -585,8 +563,9 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells() { - let builtin = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new_standard(Some(256), true)); + let builtin = BuiltinRunner::RangeCheck( + RangeCheckBuiltinRunner::::new(Some(256), true), + ); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -596,7 +575,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_a() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)]; assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4))); } @@ -604,7 +583,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_b() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let memory = memory![ ((0, 0), 1465218365), ((0, 1), 2134570341), @@ -617,7 +596,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_c() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let memory = memory![ ((0, 0), 634834751465218365_i64), ((0, 1), 42876922134570341_i64), @@ -632,7 +611,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_empty_memory() { - let builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let memory = Memory::new(); assert_eq!(builtin.get_range_check_usage(&memory), None); } @@ -642,7 +621,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_perm_range_check_units() { let builtin_runner: BuiltinRunner = - RangeCheckBuiltinRunner::new_standard(Some(8), true).into(); + RangeCheckBuiltinRunner::::new(Some(8), true).into(); let mut vm = vm!(); vm.current_step = 8; @@ -653,7 +632,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_air_private_input() { - let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new_standard(None, true).into(); + let builtin: BuiltinRunner = + RangeCheckBuiltinRunner::::new(None, true).into(); let memory = memory![((0, 0), 0), ((0, 1), 1), ((0, 2), 2)]; assert_eq!( diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index a3b119c574..3440e78493 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -55,7 +55,9 @@ use num_traits::{ToPrimitive, Zero}; use serde::{Deserialize, Serialize}; use super::{ - builtin_runner::{KeccakBuiltinRunner, PoseidonBuiltinRunner}, + builtin_runner::{ + KeccakBuiltinRunner, PoseidonBuiltinRunner, RC_N_PARTS_96, RC_N_PARTS_STANDARD, + }, cairo_pie::{self, CairoPie, CairoPieMetadata, CairoPieVersion}, }; @@ -285,7 +287,11 @@ impl CairoRunner { let included = program_builtins.remove(&BuiltinName::range_check); if included || self.is_proof_mode() { builtin_runners.push( - RangeCheckBuiltinRunner::new_standard(instance_def.ratio, included).into(), + RangeCheckBuiltinRunner::::new( + instance_def.ratio, + included, + ) + .into(), ); } } @@ -329,8 +335,10 @@ impl CairoRunner { if let Some(instance_def) = self.layout.builtins.range_check96.as_ref() { let included = program_builtins.remove(&BuiltinName::range_check96); if included || self.is_proof_mode() { - builtin_runners - .push(RangeCheckBuiltinRunner::new_96(instance_def.ratio, included).into()); + builtin_runners.push( + RangeCheckBuiltinRunner::::new(instance_def.ratio, included) + .into(), + ); } } if !program_builtins.is_empty() && !allow_missing_builtins { @@ -376,9 +384,9 @@ impl CairoRunner { BuiltinName::pedersen => vm .builtin_runners .push(HashBuiltinRunner::new(Some(32), true).into()), - BuiltinName::range_check => vm - .builtin_runners - .push(RangeCheckBuiltinRunner::new_standard(Some(1), true).into()), + BuiltinName::range_check => vm.builtin_runners.push( + RangeCheckBuiltinRunner::::new(Some(1), true).into(), + ), BuiltinName::output => vm .builtin_runners .push(OutputBuiltinRunner::new(true).into()), @@ -406,7 +414,7 @@ impl CairoRunner { } BuiltinName::range_check96 => vm .builtin_runners - .push(RangeCheckBuiltinRunner::new_96(Some(1), true).into()), + .push(RangeCheckBuiltinRunner::::new(Some(1), true).into()), } } @@ -4082,7 +4090,8 @@ mod tests { vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new_standard(Some(12), true).into()]; + vm.builtin_runners = + vec![RangeCheckBuiltinRunner::::new(Some(12), true).into()]; assert_matches!( cairo_runner.get_perm_range_check_limits(&vm), @@ -4136,7 +4145,8 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new_standard(Some(8), true).into()]; + vm.builtin_runners = + vec![RangeCheckBuiltinRunner::::new(Some(8), true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; @@ -4203,7 +4213,8 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new_standard(Some(8), true).into()]; + vm.builtin_runners = + vec![RangeCheckBuiltinRunner::::new(Some(8), true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 9dccf59757..7cf773af43 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -33,7 +33,7 @@ use num_traits::{ToPrimitive, Zero}; use super::errors::runner_errors::RunnerError; use super::runners::builtin_runner::{ - OutputBuiltinRunner, OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, + OutputBuiltinRunner, OUTPUT_BUILTIN_NAME, RC_N_PARTS_STANDARD, }; const MAX_TRACEBACK_ENTRIES: u32 = 20; @@ -924,12 +924,12 @@ impl VirtualMachine { self.segments.memory.get_integer_range(addr, size) } - pub fn get_range_check_builtin(&self) -> Result<&RangeCheckBuiltinRunner, VirtualMachineError> { + pub fn get_range_check_builtin( + &self, + ) -> Result<&RangeCheckBuiltinRunner, VirtualMachineError> { for builtin in &self.builtin_runners { if let BuiltinRunner::RangeCheck(range_check_builtin) = builtin { - if range_check_builtin.name() == RANGE_CHECK_BUILTIN_NAME { - return Ok(range_check_builtin); - } + return Ok(range_check_builtin); }; } Err(VirtualMachineError::NoRangeCheckBuiltin) diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs index 5d4c26a20f..18fc1d02a0 100644 --- a/vm/src/vm/vm_memory/memory.rs +++ b/vm/src/vm/vm_memory/memory.rs @@ -608,7 +608,9 @@ mod memory_tests { types::instance_definitions::ecdsa_instance_def::EcdsaInstanceDef, utils::test_utils::*, vm::{ - runners::builtin_runner::{RangeCheckBuiltinRunner, SignatureBuiltinRunner}, + runners::builtin_runner::{ + RangeCheckBuiltinRunner, SignatureBuiltinRunner, RC_N_PARTS_STANDARD, + }, vm_memory::memory_segments::MemorySegmentManager, }, }; @@ -779,7 +781,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_within_bounds() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); builtin.add_validation_rule(&mut segments.memory); @@ -804,7 +806,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_outside_bounds() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let mut segments = MemorySegmentManager::new(); segments.add(); builtin.initialize_segments(&mut segments); @@ -895,7 +897,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_relocatable_value() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); segments.memory = memory![((0, 0), (0, 4))]; @@ -912,7 +914,7 @@ mod memory_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn validate_existing_memory_for_range_check_out_of_bounds_diff_segment() { - let mut builtin = RangeCheckBuiltinRunner::new_standard(Some(8), true); + let mut builtin = RangeCheckBuiltinRunner::::new(Some(8), true); let mut segments = MemorySegmentManager::new(); segments.memory = Memory::new(); segments.add(); From dd5dec917779b7d05536ad8a724cb35819bd9c70 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 5 Apr 2024 17:22:46 -0300 Subject: [PATCH 08/11] Fix --- cairo1-run/src/cairo_run.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index f0d2c2df43..9a88f3a4f9 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -496,7 +496,10 @@ fn create_entry_code( BuiltinName::ec_op => EcOpType::ID, BuiltinName::poseidon => PoseidonType::ID, BuiltinName::segment_arena => SegmentArenaType::ID, - BuiltinName::keccak | BuiltinName::ecdsa | BuiltinName::output => return fp_loc, + BuiltinName::keccak + | BuiltinName::ecdsa + | BuiltinName::output + | BuiltinName::range_check96 => return fp_loc, }; signature .ret_types From d63c64272223334fc9a51bb6b8ea919a89d8361f Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Apr 2024 17:05:40 -0300 Subject: [PATCH 09/11] fmt --- .../builtin_hint_processor/math_utils.rs | 12 +++--------- vm/src/vm/vm_core.rs | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index 2413e2f361..a0fa71dddb 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -169,8 +169,7 @@ pub fn assert_le_felt_v_0_8( return Err(HintError::NonLeFelt252(Box::new((*a, *b)))); } let bound = vm.get_range_check_builtin()?.bound(); - let small_inputs = - Felt252::from((a < bound && b - a < *bound) as u8); + let small_inputs = Felt252::from((a < bound && b - a < *bound) as u8); insert_value_from_var_name("small_inputs", small_inputs, vm, ids_data, ap_tracking) } @@ -365,9 +364,7 @@ pub fn is_positive( let (sign, abs_value) = value_as_int.into_parts(); //Main logic (assert a is positive) if abs_value >= range_check_builtin.bound().to_biguint() { - return Err(HintError::ValueOutsideValidRange(Box::new( - value, - ))); + return Err(HintError::ValueOutsideValidRange(Box::new(value))); } let result = Felt252::from((sign == Sign::Plus) as u8); @@ -506,10 +503,7 @@ pub fn unsigned_div_rem( // Main logic if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? { - return Err(HintError::OutOfValidRange(Box::new(( - div, - *builtin_bound, - )))); + return Err(HintError::OutOfValidRange(Box::new((div, *builtin_bound)))); } let (q, r) = value.div_rem(&(div).try_into().map_err(|_| MathError::DividedByZero)?); diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 9adbf79670..dc8818e81d 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -35,8 +35,8 @@ use num_traits::{ToPrimitive, Zero}; use super::errors::runner_errors::RunnerError; use super::runners::builtin_runner::{ - ModBuiltinRunner, ADD_MOD_BUILTIN_NAME, MUL_MOD_BUILTIN_NAME, - OUTPUT_BUILTIN_NAME, RC_N_PARTS_STANDARD, + ModBuiltinRunner, ADD_MOD_BUILTIN_NAME, MUL_MOD_BUILTIN_NAME, OUTPUT_BUILTIN_NAME, + RC_N_PARTS_STANDARD, }; const MAX_TRACEBACK_ENTRIES: u32 = 20; From d64075d92f15433029e7072951da9a093cb70685 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Apr 2024 18:34:00 -0300 Subject: [PATCH 10/11] Update relocated ptr values to account for added segment --- vm/src/vm/runners/builtin_runner/modulo.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/vm/src/vm/runners/builtin_runner/modulo.rs b/vm/src/vm/runners/builtin_runner/modulo.rs index 8e74113096..ef4a9fa473 100644 --- a/vm/src/vm/runners/builtin_runner/modulo.rs +++ b/vm/src/vm/runners/builtin_runner/modulo.rs @@ -739,8 +739,8 @@ mod tests { p1: Felt252::ONE, p2: Felt252::ZERO, p3: Felt252::ZERO, - values_ptr: 18927, - offsets_ptr: 18959, + values_ptr: 23023 + offsets_ptr: 23055 n: 2, batch: BTreeMap::from([( 0, @@ -769,8 +769,8 @@ mod tests { p1: Felt252::ONE, p2: Felt252::ZERO, p3: Felt252::ZERO, - values_ptr: 18927, - offsets_ptr: 18962, + values_ptr: 23023, + offsets_ptr: 23058, n: 1, batch: BTreeMap::from([( 0, @@ -794,7 +794,7 @@ mod tests { ),]) } ], - zero_value_address: 18027 + zero_value_address: 22123 }) ); assert_eq!( @@ -807,8 +807,8 @@ mod tests { p1: Felt252::ONE, p2: Felt252::ZERO, p3: Felt252::ZERO, - values_ptr: 18927, - offsets_ptr: 18965, + values_ptr: 23023, + offsets_ptr: 23061, n: 3, batch: BTreeMap::from([( 0, @@ -837,8 +837,8 @@ mod tests { p1: Felt252::ONE, p2: Felt252::ZERO, p3: Felt252::ZERO, - values_ptr: 18927, - offsets_ptr: 18968, + values_ptr: 23023, + offsets_ptr: 23064, n: 2, batch: BTreeMap::from([( 0, @@ -867,8 +867,8 @@ mod tests { p1: Felt252::ONE, p2: Felt252::ZERO, p3: Felt252::ZERO, - values_ptr: 18927, - offsets_ptr: 18971, + values_ptr: 23023, + offsets_ptr: 23067, n: 1, batch: BTreeMap::from([( 0, From 6500201172fdbcacf990c629185f0b7331fcab20 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Apr 2024 18:39:14 -0300 Subject: [PATCH 11/11] Fix --- vm/src/vm/runners/builtin_runner/modulo.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/src/vm/runners/builtin_runner/modulo.rs b/vm/src/vm/runners/builtin_runner/modulo.rs index ef4a9fa473..dc4e69f8c1 100644 --- a/vm/src/vm/runners/builtin_runner/modulo.rs +++ b/vm/src/vm/runners/builtin_runner/modulo.rs @@ -739,8 +739,8 @@ mod tests { p1: Felt252::ONE, p2: Felt252::ZERO, p3: Felt252::ZERO, - values_ptr: 23023 - offsets_ptr: 23055 + values_ptr: 23023, + offsets_ptr: 23055, n: 2, batch: BTreeMap::from([( 0, @@ -892,7 +892,7 @@ mod tests { ),]) } ], - zero_value_address: 18027 + zero_value_address: 22123 }) ) }