diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs index 19c8a7c4aa..712e842dfc 100644 --- a/cairo-vm-cli/src/main.rs +++ b/cairo-vm-cli/src/main.rs @@ -48,7 +48,8 @@ fn validate_layout(value: &str) -> Result<(), String> { | "starknet_with_keccak" | "recursive_large_output" | "all_cairo" - | "all_solidity" => Ok(()), + | "all_solidity" + | "dynamic" => Ok(()), _ => Err(format!("{value} is not a valid layout")), } } diff --git a/src/types/instance_definitions/bitwise_instance_def.rs b/src/types/instance_definitions/bitwise_instance_def.rs index 8cea97d21b..a0d68637fe 100644 --- a/src/types/instance_definitions/bitwise_instance_def.rs +++ b/src/types/instance_definitions/bitwise_instance_def.rs @@ -3,19 +3,19 @@ pub(crate) const INPUT_CELLS_PER_BITWISE: u32 = 2; #[derive(Clone, Debug, PartialEq)] pub(crate) struct BitwiseInstanceDef { - pub(crate) ratio: u32, + pub(crate) ratio: Option, pub(crate) total_n_bits: u32, } impl BitwiseInstanceDef { pub(crate) fn default() -> Self { BitwiseInstanceDef { - ratio: 256, + ratio: Some(256), total_n_bits: 251, } } - pub(crate) fn new(ratio: u32) -> Self { + pub(crate) fn new(ratio: Option) -> Self { BitwiseInstanceDef { ratio, total_n_bits: 251, @@ -56,17 +56,17 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { let builtin_instance = BitwiseInstanceDef { - ratio: 8, + ratio: Some(8), total_n_bits: 251, }; - assert_eq!(BitwiseInstanceDef::new(8), builtin_instance); + assert_eq!(BitwiseInstanceDef::new(Some(8)), builtin_instance); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { let builtin_instance = BitwiseInstanceDef { - ratio: 256, + ratio: Some(256), total_n_bits: 251, }; assert_eq!(BitwiseInstanceDef::default(), builtin_instance); diff --git a/src/types/instance_definitions/builtins_instance_def.rs b/src/types/instance_definitions/builtins_instance_def.rs index 1bd0764486..901cd0f7ec 100644 --- a/src/types/instance_definitions/builtins_instance_def.rs +++ b/src/types/instance_definitions/builtins_instance_def.rs @@ -60,10 +60,10 @@ impl BuiltinsInstanceDef { pub(crate) fn recursive() -> BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, - pedersen: Some(PedersenInstanceDef::new(128, 1)), + pedersen: Some(PedersenInstanceDef::new(Some(128), 1)), range_check: Some(RangeCheckInstanceDef::default()), ecdsa: None, - bitwise: Some(BitwiseInstanceDef::new(8)), + bitwise: Some(BitwiseInstanceDef::new(Some(8))), ec_op: None, keccak: None, poseidon: None, @@ -73,11 +73,11 @@ impl BuiltinsInstanceDef { pub(crate) fn starknet() -> BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, - pedersen: Some(PedersenInstanceDef::new(32, 1)), - range_check: Some(RangeCheckInstanceDef::new(16, 8)), - ecdsa: Some(EcdsaInstanceDef::new(2048)), - bitwise: Some(BitwiseInstanceDef::new(64)), - ec_op: Some(EcOpInstanceDef::new(1024)), + pedersen: Some(PedersenInstanceDef::new(Some(32), 1)), + range_check: Some(RangeCheckInstanceDef::new(Some(16), 8)), + ecdsa: Some(EcdsaInstanceDef::new(Some(2048))), + bitwise: Some(BitwiseInstanceDef::new(Some(64))), + ec_op: Some(EcOpInstanceDef::new(Some(1024))), keccak: None, poseidon: Some(PoseidonInstanceDef::default()), } @@ -86,12 +86,12 @@ impl BuiltinsInstanceDef { pub(crate) fn starknet_with_keccak() -> BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, - pedersen: Some(PedersenInstanceDef::new(32, 1)), - range_check: Some(RangeCheckInstanceDef::new(16, 8)), - ecdsa: Some(EcdsaInstanceDef::new(2048)), - bitwise: Some(BitwiseInstanceDef::new(64)), - ec_op: Some(EcOpInstanceDef::new(1024)), - keccak: Some(KeccakInstanceDef::new(2048, vec![200; 8])), + pedersen: Some(PedersenInstanceDef::new(Some(32), 1)), + range_check: Some(RangeCheckInstanceDef::new(Some(16), 8)), + ecdsa: Some(EcdsaInstanceDef::new(Some(2048))), + bitwise: Some(BitwiseInstanceDef::new(Some(64))), + ec_op: Some(EcOpInstanceDef::new(Some(1024))), + keccak: Some(KeccakInstanceDef::new(Some(2048), vec![200; 8])), poseidon: Some(PoseidonInstanceDef::default()), } } @@ -99,10 +99,10 @@ impl BuiltinsInstanceDef { pub(crate) fn recursive_large_output() -> BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, - pedersen: Some(PedersenInstanceDef::new(32, 1)), + pedersen: Some(PedersenInstanceDef::new(Some(32), 1)), range_check: Some(RangeCheckInstanceDef::default()), ecdsa: None, - bitwise: Some(BitwiseInstanceDef::new(8)), + bitwise: Some(BitwiseInstanceDef::new(Some(8))), ec_op: None, keccak: None, poseidon: None, @@ -112,13 +112,13 @@ impl BuiltinsInstanceDef { pub(crate) fn all_cairo() -> BuiltinsInstanceDef { BuiltinsInstanceDef { output: true, - pedersen: Some(PedersenInstanceDef::new(256, 1)), + pedersen: Some(PedersenInstanceDef::new(Some(256), 1)), range_check: Some(RangeCheckInstanceDef::default()), - ecdsa: Some(EcdsaInstanceDef::new(2048)), - bitwise: Some(BitwiseInstanceDef::new(16)), - ec_op: Some(EcOpInstanceDef::new(1024)), - keccak: Some(KeccakInstanceDef::new(2048, vec![200; 8])), - poseidon: Some(PoseidonInstanceDef::new(256)), + ecdsa: Some(EcdsaInstanceDef::new(Some(2048))), + bitwise: Some(BitwiseInstanceDef::new(Some(16))), + ec_op: Some(EcOpInstanceDef::new(Some(1024))), + keccak: Some(KeccakInstanceDef::new(Some(2048), vec![200; 8])), + poseidon: Some(PoseidonInstanceDef::new(Some(256))), } } @@ -134,6 +134,19 @@ impl BuiltinsInstanceDef { poseidon: None, } } + + pub(crate) fn dynamic() -> BuiltinsInstanceDef { + BuiltinsInstanceDef { + output: true, + pedersen: Some(PedersenInstanceDef::new(None, 4)), + range_check: Some(RangeCheckInstanceDef::new(None, 8)), + ecdsa: Some(EcdsaInstanceDef::new(None)), + bitwise: Some(BitwiseInstanceDef::new(None)), + ec_op: Some(EcOpInstanceDef::new(None)), + keccak: None, + poseidon: None, + } + } } #[cfg(test)] diff --git a/src/types/instance_definitions/ec_op_instance_def.rs b/src/types/instance_definitions/ec_op_instance_def.rs index f777589842..ef0dc08f6c 100644 --- a/src/types/instance_definitions/ec_op_instance_def.rs +++ b/src/types/instance_definitions/ec_op_instance_def.rs @@ -3,7 +3,7 @@ pub(crate) const INPUT_CELLS_PER_EC_OP: u32 = 5; #[derive(Clone, Debug, PartialEq)] pub(crate) struct EcOpInstanceDef { - pub(crate) ratio: u32, + pub(crate) ratio: Option, pub(crate) scalar_height: u32, pub(crate) _scalar_bits: u32, } @@ -11,13 +11,13 @@ pub(crate) struct EcOpInstanceDef { impl EcOpInstanceDef { pub(crate) fn default() -> Self { EcOpInstanceDef { - ratio: 256, + ratio: Some(256), scalar_height: 256, _scalar_bits: 252, } } - pub(crate) fn new(ratio: u32) -> Self { + pub(crate) fn new(ratio: Option) -> Self { EcOpInstanceDef { ratio, scalar_height: 256, @@ -59,18 +59,18 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { let builtin_instance = EcOpInstanceDef { - ratio: 8, + ratio: Some(8), scalar_height: 256, _scalar_bits: 252, }; - assert_eq!(EcOpInstanceDef::new(8), builtin_instance); + assert_eq!(EcOpInstanceDef::new(Some(8)), builtin_instance); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { let builtin_instance = EcOpInstanceDef { - ratio: 256, + ratio: Some(256), scalar_height: 256, _scalar_bits: 252, }; diff --git a/src/types/instance_definitions/ecdsa_instance_def.rs b/src/types/instance_definitions/ecdsa_instance_def.rs index 689443f682..15e7360567 100644 --- a/src/types/instance_definitions/ecdsa_instance_def.rs +++ b/src/types/instance_definitions/ecdsa_instance_def.rs @@ -3,7 +3,7 @@ pub(crate) const _INPUTCELLS_PER_SIGNATURE: u32 = 2; #[derive(Debug, PartialEq)] pub(crate) struct EcdsaInstanceDef { - pub(crate) ratio: u32, + pub(crate) ratio: Option, pub(crate) _repetitions: u32, pub(crate) _height: u32, pub(crate) _n_hash_bits: u32, @@ -12,14 +12,14 @@ pub(crate) struct EcdsaInstanceDef { impl EcdsaInstanceDef { pub(crate) fn default() -> Self { EcdsaInstanceDef { - ratio: 512, + ratio: Some(512), _repetitions: 1, _height: 256, _n_hash_bits: 251, } } - pub(crate) fn new(ratio: u32) -> Self { + pub(crate) fn new(ratio: Option) -> Self { EcdsaInstanceDef { ratio, _repetitions: 1, @@ -62,19 +62,19 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { let builtin_instance = EcdsaInstanceDef { - ratio: 8, + ratio: Some(8), _repetitions: 1, _height: 256, _n_hash_bits: 251, }; - assert_eq!(EcdsaInstanceDef::new(8), builtin_instance); + assert_eq!(EcdsaInstanceDef::new(Some(8)), builtin_instance); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { let builtin_instance = EcdsaInstanceDef { - ratio: 512, + ratio: Some(512), _repetitions: 1, _height: 256, _n_hash_bits: 251, diff --git a/src/types/instance_definitions/keccak_instance_def.rs b/src/types/instance_definitions/keccak_instance_def.rs index d01c666622..7ed8bf9bd5 100644 --- a/src/types/instance_definitions/keccak_instance_def.rs +++ b/src/types/instance_definitions/keccak_instance_def.rs @@ -2,7 +2,7 @@ use crate::stdlib::prelude::*; #[derive(Clone, Debug, PartialEq)] pub(crate) struct KeccakInstanceDef { - pub(crate) _ratio: u32, + pub(crate) ratio: Option, pub(crate) _state_rep: Vec, pub(crate) _instance_per_component: u32, } @@ -10,8 +10,8 @@ pub(crate) struct KeccakInstanceDef { impl Default for KeccakInstanceDef { fn default() -> Self { Self { - // _ratio should be equal to 2 ** 11 -> 2048 - _ratio: 2048, + // ratio should be equal to 2 ** 11 -> 2048 + ratio: Some(2048), _state_rep: vec![200; 8], _instance_per_component: 16, } @@ -19,9 +19,9 @@ impl Default for KeccakInstanceDef { } impl KeccakInstanceDef { - pub(crate) fn new(_ratio: u32, _state_rep: Vec) -> Self { + pub(crate) fn new(ratio: Option, _state_rep: Vec) -> Self { Self { - _ratio, + ratio, _state_rep, ..Default::default() } @@ -61,18 +61,21 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { let builtin_instance = KeccakInstanceDef { - _ratio: 2048, + ratio: Some(2048), _state_rep: vec![200; 8], _instance_per_component: 16, }; - assert_eq!(KeccakInstanceDef::new(2048, vec![200; 8]), builtin_instance); + assert_eq!( + KeccakInstanceDef::new(Some(2048), vec![200; 8]), + builtin_instance + ); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { let builtin_instance = KeccakInstanceDef { - _ratio: 2048, + ratio: Some(2048), _state_rep: vec![200; 8], _instance_per_component: 16, }; diff --git a/src/types/instance_definitions/pedersen_instance_def.rs b/src/types/instance_definitions/pedersen_instance_def.rs index dad14cdebb..cca3a89a57 100644 --- a/src/types/instance_definitions/pedersen_instance_def.rs +++ b/src/types/instance_definitions/pedersen_instance_def.rs @@ -5,7 +5,7 @@ pub(crate) const INPUT_CELLS_PER_HASH: u32 = 2; #[derive(Debug, PartialEq)] pub(crate) struct PedersenInstanceDef { - pub(crate) ratio: u32, + pub(crate) ratio: Option, pub(crate) _repetitions: u32, pub(crate) _element_height: u32, pub(crate) _element_bits: u32, @@ -16,7 +16,7 @@ pub(crate) struct PedersenInstanceDef { impl PedersenInstanceDef { pub(crate) fn default() -> Self { PedersenInstanceDef { - ratio: 8, + ratio: Some(8), _repetitions: 4, _element_height: 256, _element_bits: 252, @@ -25,7 +25,7 @@ impl PedersenInstanceDef { } } - pub(crate) fn new(ratio: u32, _repetitions: u32) -> Self { + pub(crate) fn new(ratio: Option, _repetitions: u32) -> Self { PedersenInstanceDef { ratio, _repetitions, @@ -70,21 +70,21 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { let builtin_instance = PedersenInstanceDef { - ratio: 10, + ratio: Some(10), _repetitions: 2, _element_height: 256, _element_bits: 252, _n_inputs: 2, _hash_limit: BigInt::new(Sign::Plus, vec![1, 0, 0, 0, 0, 0, 17, 134217728]), }; - assert_eq!(PedersenInstanceDef::new(10, 2), builtin_instance); + assert_eq!(PedersenInstanceDef::new(Some(10), 2), builtin_instance); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { let builtin_instance = PedersenInstanceDef { - ratio: 8, + ratio: Some(8), _repetitions: 4, _element_height: 256, _element_bits: 252, diff --git a/src/types/instance_definitions/poseidon_instance_def.rs b/src/types/instance_definitions/poseidon_instance_def.rs index 775f46cc75..20b0636075 100644 --- a/src/types/instance_definitions/poseidon_instance_def.rs +++ b/src/types/instance_definitions/poseidon_instance_def.rs @@ -3,15 +3,15 @@ pub(crate) const INPUT_CELLS_PER_POSEIDON: u32 = 3; #[derive(Clone, Debug, PartialEq)] pub(crate) struct PoseidonInstanceDef { - pub(crate) ratio: u32, + pub(crate) ratio: Option, } impl PoseidonInstanceDef { pub(crate) fn default() -> Self { - PoseidonInstanceDef { ratio: 32 } + PoseidonInstanceDef { ratio: Some(32) } } - pub(crate) fn new(ratio: u32) -> Self { + pub(crate) fn new(ratio: Option) -> Self { PoseidonInstanceDef { ratio } } } @@ -22,13 +22,13 @@ mod tests { #[test] fn test_new() { - let builtin_instance = PoseidonInstanceDef { ratio: 8 }; - assert_eq!(PoseidonInstanceDef::new(8), builtin_instance); + let builtin_instance = PoseidonInstanceDef { ratio: Some(8) }; + assert_eq!(PoseidonInstanceDef::new(Some(8)), builtin_instance); } #[test] fn test_default() { - let builtin_instance = PoseidonInstanceDef { ratio: 32 }; + let builtin_instance = PoseidonInstanceDef { ratio: Some(32) }; assert_eq!(PoseidonInstanceDef::default(), builtin_instance); } } diff --git a/src/types/instance_definitions/range_check_instance_def.rs b/src/types/instance_definitions/range_check_instance_def.rs index bc67866e8a..7ed48f7901 100644 --- a/src/types/instance_definitions/range_check_instance_def.rs +++ b/src/types/instance_definitions/range_check_instance_def.rs @@ -2,19 +2,19 @@ pub(crate) const CELLS_PER_RANGE_CHECK: u32 = 1; #[derive(Debug, PartialEq)] pub(crate) struct RangeCheckInstanceDef { - pub(crate) ratio: u32, + pub(crate) ratio: Option, pub(crate) n_parts: u32, } impl RangeCheckInstanceDef { pub(crate) fn default() -> Self { RangeCheckInstanceDef { - ratio: 8, + ratio: Some(8), n_parts: 8, } } - pub(crate) fn new(ratio: u32, n_parts: u32) -> Self { + pub(crate) fn new(ratio: Option, n_parts: u32) -> Self { RangeCheckInstanceDef { ratio, n_parts } } @@ -52,17 +52,17 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_new() { let builtin_instance = RangeCheckInstanceDef { - ratio: 10, + ratio: Some(10), n_parts: 10, }; - assert_eq!(RangeCheckInstanceDef::new(10, 10), builtin_instance); + assert_eq!(RangeCheckInstanceDef::new(Some(10), 10), builtin_instance); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_default() { let builtin_instance = RangeCheckInstanceDef { - ratio: 8, + ratio: Some(8), n_parts: 8, }; assert_eq!(RangeCheckInstanceDef::default(), builtin_instance); diff --git a/src/types/layout.rs b/src/types/layout.rs index 45d7233cd8..e799103ed8 100644 --- a/src/types/layout.rs +++ b/src/types/layout.rs @@ -146,6 +146,20 @@ impl CairoLayout { _cpu_instance_def: CpuInstanceDef::default(), } } + + pub(crate) fn dynamic_instance() -> CairoLayout { + CairoLayout { + _name: String::from("dynamic"), + _cpu_component_step: 1, + rc_units: 16, + builtins: BuiltinsInstanceDef::dynamic(), + _public_memory_fraction: 8, + _memory_units_per_step: 8, + diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()), + _n_trace_colums: 73, + _cpu_instance_def: CpuInstanceDef::default(), + } + } } #[cfg(test)] diff --git a/src/utils.rs b/src/utils.rs index be9d81f290..5df7791258 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -214,7 +214,7 @@ pub mod test_utils { macro_rules! vm_with_range_check { () => {{ let mut vm = VirtualMachine::new(false); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(8, 8, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(8), 8, true).into()]; vm }}; } diff --git a/src/vm/errors/memory_errors.rs b/src/vm/errors/memory_errors.rs index 5bdf7f96fd..697b8c91fa 100644 --- a/src/vm/errors/memory_errors.rs +++ b/src/vm/errors/memory_errors.rs @@ -97,8 +97,6 @@ pub enum MemoryError { pub enum InsufficientAllocatedCellsError { #[error("Number of steps must be at least {0} for the {1} builtin.")] MinStepNotReached(usize, &'static str), - #[error("Failed to get allocated size for builtin {0}, current vm step {1} is not divisible by builtin ratio {2}")] - CurrentStepNotDivisibleByBuiltinRatio(&'static str, usize, usize), #[error("The {0} builtin used {1} cells but the capacity is {2}.")] BuiltinCells(&'static str, usize, usize), #[error("There are only {0} cells to fill the range checks holes, but potentially {1} are required.")] diff --git a/src/vm/runners/builtin_runner/bitwise.rs b/src/vm/runners/builtin_runner/bitwise.rs index 919b1d98bc..ca5f2fa6e3 100644 --- a/src/vm/runners/builtin_runner/bitwise.rs +++ b/src/vm/runners/builtin_runner/bitwise.rs @@ -1,6 +1,5 @@ use crate::stdlib::vec::Vec; use crate::{ - math_utils::safe_div_usize, types::{ instance_definitions::bitwise_instance_def::{ BitwiseInstanceDef, CELLS_PER_BITWISE, INPUT_CELLS_PER_BITWISE, @@ -8,11 +7,7 @@ use crate::{ relocatable::{MaybeRelocatable, Relocatable}, }, vm::{ - errors::{ - memory_errors::{InsufficientAllocatedCellsError, MemoryError}, - runner_errors::RunnerError, - }, - vm_core::VirtualMachine, + errors::{memory_errors::MemoryError, runner_errors::RunnerError}, vm_memory::{memory::Memory, memory_segments::MemorySegmentManager}, }, }; @@ -22,14 +17,14 @@ use super::BITWISE_BUILTIN_NAME; #[derive(Debug, Clone)] pub struct BitwiseBuiltinRunner { - ratio: u32, + ratio: Option, pub base: usize, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, bitwise_builtin: BitwiseInstanceDef, pub(crate) stop_ptr: Option, pub(crate) included: bool, - instances_per_component: u32, + pub(crate) instances_per_component: u32, } impl BitwiseBuiltinRunner { @@ -62,7 +57,7 @@ impl BitwiseBuiltinRunner { self.base } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } @@ -111,12 +106,6 @@ impl BitwiseBuiltinRunner { Ok(None) } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -127,39 +116,6 @@ impl BitwiseBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio * self.instances_per_component as usize; - if vm.current_step < min_step { - Err( - InsufficientAllocatedCellsError::MinStepNotReached(min_step, BITWISE_BUILTIN_NAME) - .into(), - ) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - BITWISE_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - BITWISE_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_used_diluted_check_units(&self, diluted_spacing: u32, diluted_n_bits: u32) -> usize { let total_n_bits = self.bitwise_builtin.total_n_bits; let mut partition = Vec::with_capacity(total_n_bits as usize); @@ -247,7 +203,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { - let builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -266,7 +222,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -290,7 +246,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -318,7 +274,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_notincluded() { - let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), false); + let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), false); let mut vm = vm!(); @@ -342,7 +298,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -367,7 +323,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_test() { let builtin: BuiltinRunner = - BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true).into(); + BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true).into(); let mut vm = vm!(); @@ -413,7 +369,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { - let builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let builtin: BuiltinRunner = + BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true).into(); let mut vm = vm!(); diff --git a/src/vm/runners/builtin_runner/ec_op.rs b/src/vm/runners/builtin_runner/ec_op.rs index e4a852f919..b90e1cf894 100644 --- a/src/vm/runners/builtin_runner/ec_op.rs +++ b/src/vm/runners/builtin_runner/ec_op.rs @@ -1,13 +1,12 @@ -use crate::math_utils::{ec_add, ec_double, safe_div_usize}; +use crate::math_utils::{ec_add, ec_double}; use crate::stdlib::{borrow::Cow, prelude::*}; use crate::stdlib::{cell::RefCell, collections::HashMap}; use crate::types::instance_definitions::ec_op_instance_def::{ EcOpInstanceDef, CELLS_PER_EC_OP, INPUT_CELLS_PER_EC_OP, }; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; -use crate::vm::errors::memory_errors::{InsufficientAllocatedCellsError, MemoryError}; +use crate::vm::errors::memory_errors::MemoryError; use crate::vm::errors::runner_errors::RunnerError; -use crate::vm::vm_core::VirtualMachine; use crate::vm::vm_memory::memory::Memory; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use felt::Felt252; @@ -19,14 +18,14 @@ use super::EC_OP_BUILTIN_NAME; #[derive(Debug, Clone)] pub struct EcOpBuiltinRunner { - ratio: u32, + ratio: Option, pub base: usize, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, ec_op_builtin: EcOpInstanceDef, pub(crate) stop_ptr: Option, pub(crate) included: bool, - instances_per_component: u32, + pub(crate) instances_per_component: u32, cache: RefCell>, } @@ -129,7 +128,7 @@ impl EcOpBuiltinRunner { self.base } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } @@ -229,12 +228,6 @@ impl EcOpBuiltinRunner { } } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -245,39 +238,6 @@ impl EcOpBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio * self.instances_per_component as usize; - if vm.current_step < min_step { - Err( - InsufficientAllocatedCellsError::MinStepNotReached(min_step, EC_OP_BUILTIN_NAME) - .into(), - ) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - EC_OP_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - EC_OP_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_used_instances( &self, segments: &MemorySegmentManager, @@ -364,7 +324,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { - let builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true); + let builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), true); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -375,7 +335,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true); + let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -399,7 +359,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true); + let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -427,7 +387,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_notincluded() { - let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), false); + let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), false); let mut vm = vm!(); @@ -451,7 +411,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true); + let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), true); let mut vm = vm!(); @@ -475,7 +435,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_test() { - let builtin: BuiltinRunner = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true).into(); + let builtin: BuiltinRunner = + EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), true).into(); let mut vm = vm!(); @@ -520,7 +481,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { - let builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true); + let builtin: BuiltinRunner = + EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(10)), true).into(); let mut vm = vm!(); diff --git a/src/vm/runners/builtin_runner/hash.rs b/src/vm/runners/builtin_runner/hash.rs index 7bb505b136..0d75f4e12f 100644 --- a/src/vm/runners/builtin_runner/hash.rs +++ b/src/vm/runners/builtin_runner/hash.rs @@ -1,37 +1,34 @@ use crate::stdlib::{cell::RefCell, prelude::*}; - -use crate::math_utils::safe_div_usize; use crate::types::instance_definitions::pedersen_instance_def::{ CELLS_PER_HASH, INPUT_CELLS_PER_HASH, }; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; -use crate::vm::errors::memory_errors::{InsufficientAllocatedCellsError, MemoryError}; +use crate::vm::errors::memory_errors::MemoryError; use crate::vm::errors::runner_errors::RunnerError; -use crate::vm::vm_core::VirtualMachine; use crate::vm::vm_memory::memory::Memory; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use felt::Felt252; use num_integer::{div_ceil, Integer}; use starknet_crypto::{pedersen_hash, FieldElement}; -use super::EC_OP_BUILTIN_NAME; +use super::HASH_BUILTIN_NAME; #[derive(Debug, Clone)] pub struct HashBuiltinRunner { pub base: usize, - ratio: u32, + ratio: Option, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, pub(crate) stop_ptr: Option, pub(crate) included: bool, - instances_per_component: u32, + pub(crate) instances_per_component: u32, // This act as a cache to optimize calls to deduce_memory_cell // Therefore need interior mutability pub(self) verified_addresses: RefCell>, } impl HashBuiltinRunner { - pub fn new(ratio: u32, included: bool) -> Self { + pub fn new(ratio: Option, included: bool) -> Self { HashBuiltinRunner { base: 0, ratio, @@ -60,7 +57,7 @@ impl HashBuiltinRunner { self.base } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } @@ -114,12 +111,6 @@ impl HashBuiltinRunner { Ok(None) } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -130,39 +121,6 @@ impl HashBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio * self.instances_per_component as usize; - if vm.current_step < min_step { - Err( - InsufficientAllocatedCellsError::MinStepNotReached(min_step, EC_OP_BUILTIN_NAME) - .into(), - ) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - EC_OP_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - EC_OP_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_used_instances( &self, segments: &MemorySegmentManager, @@ -178,14 +136,14 @@ impl HashBuiltinRunner { ) -> Result { if self.included { let stop_pointer_addr = - (pointer - 1).map_err(|_| RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME))?; + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(HASH_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) - .map_err(|_| RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME))?; + .map_err(|_| RunnerError::NoStopPointer(HASH_BUILTIN_NAME))?; if self.base as isize != stop_pointer.segment_index { return Err(RunnerError::InvalidStopPointerIndex( - EC_OP_BUILTIN_NAME, + HASH_BUILTIN_NAME, stop_pointer, self.base, )); @@ -195,7 +153,7 @@ impl HashBuiltinRunner { let used = num_instances * self.cells_per_instance as usize; if stop_ptr != used { return Err(RunnerError::InvalidStopPointer( - EC_OP_BUILTIN_NAME, + HASH_BUILTIN_NAME, Relocatable::from((self.base as isize, used)), Relocatable::from((self.base as isize, stop_ptr)), )); @@ -233,7 +191,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { - let builtin = HashBuiltinRunner::new(10, true); + let builtin = HashBuiltinRunner::new(Some(10), true); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -244,7 +202,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = HashBuiltinRunner::new(10, true); + let mut builtin = HashBuiltinRunner::new(Some(10), true); let mut vm = vm!(); @@ -268,7 +226,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = HashBuiltinRunner::new(10, true); + let mut builtin = HashBuiltinRunner::new(Some(10), true); let mut vm = vm!(); @@ -286,7 +244,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer( - EC_OP_BUILTIN_NAME, + HASH_BUILTIN_NAME, relocatable!(0, 999), relocatable!(0, 0) )) @@ -296,7 +254,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_not_included() { - let mut builtin = HashBuiltinRunner::new(10, false); + let mut builtin = HashBuiltinRunner::new(Some(10), false); let mut vm = vm!(); @@ -320,7 +278,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = HashBuiltinRunner::new(10, true); + let mut builtin = HashBuiltinRunner::new(Some(10), true); let mut vm = vm!(); @@ -337,14 +295,14 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME)) + Err(RunnerError::NoStopPointer(HASH_BUILTIN_NAME)) ); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_test() { - let builtin: BuiltinRunner = HashBuiltinRunner::new(10, true).into(); + let builtin: BuiltinRunner = HashBuiltinRunner::new(Some(10), true).into(); let mut vm = vm!(); @@ -390,7 +348,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { - let builtin = HashBuiltinRunner::new(10, true); + let builtin: BuiltinRunner = HashBuiltinRunner::new(Some(10), true).into(); let mut vm = vm!(); @@ -435,7 +393,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn deduce_memory_cell_pedersen_for_preset_memory_valid() { let memory = memory![((0, 3), 32), ((0, 4), 72), ((0, 5), 0)]; - let builtin = HashBuiltinRunner::new(8, true); + let builtin = HashBuiltinRunner::new(Some(8), true); let result = builtin.deduce_memory_cell(Relocatable::from((0, 5)), &memory); assert_eq!( @@ -454,7 +412,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn deduce_memory_cell_pedersen_for_preset_memory_incorrect_offset() { let memory = memory![((0, 4), 32), ((0, 5), 72), ((0, 6), 0)]; - let builtin = HashBuiltinRunner::new(8, true); + let builtin = HashBuiltinRunner::new(Some(8), true); let result = builtin.deduce_memory_cell(Relocatable::from((0, 6)), &memory); assert_eq!(result, Ok(None)); } @@ -463,7 +421,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn deduce_memory_cell_pedersen_for_preset_memory_no_values_to_hash() { let memory = memory![((0, 4), 72), ((0, 5), 0)]; - let builtin = HashBuiltinRunner::new(8, true); + let builtin = HashBuiltinRunner::new(Some(8), true); let result = builtin.deduce_memory_cell(Relocatable::from((0, 5)), &memory); assert_eq!(result, Ok(None)); } @@ -472,7 +430,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn deduce_memory_cell_pedersen_for_preset_memory_already_computed() { let memory = memory![((0, 3), 32), ((0, 4), 72), ((0, 5), 0)]; - let mut builtin = HashBuiltinRunner::new(8, true); + let mut builtin = HashBuiltinRunner::new(Some(8), true); builtin.verified_addresses = RefCell::new(vec![Relocatable::from((0, 5))]); let result = builtin.deduce_memory_cell(Relocatable::from((0, 5)), &memory); assert_eq!(result, Ok(None)); @@ -481,7 +439,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_segment_addresses() { - let builtin = HashBuiltinRunner::new(256, true); + let builtin = HashBuiltinRunner::new(Some(256), true); assert_eq!(builtin.get_memory_segment_addresses(), (0, None),); } @@ -489,7 +447,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_missing_segment_used_sizes() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let vm = vm!(); assert_eq!( @@ -501,7 +459,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_empty() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -511,7 +469,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -529,7 +487,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_missing_segment_used_sizes() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let vm = vm!(); assert_eq!( @@ -541,7 +499,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_empty() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -551,7 +509,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); diff --git a/src/vm/runners/builtin_runner/keccak.rs b/src/vm/runners/builtin_runner/keccak.rs index bfe251db70..213f0be5a0 100644 --- a/src/vm/runners/builtin_runner/keccak.rs +++ b/src/vm/runners/builtin_runner/keccak.rs @@ -2,7 +2,7 @@ use crate::math_utils::safe_div_usize; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*}; use crate::types::instance_definitions::keccak_instance_def::KeccakInstanceDef; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; -use crate::vm::errors::memory_errors::{InsufficientAllocatedCellsError, MemoryError}; +use crate::vm::errors::memory_errors::MemoryError; use crate::vm::errors::runner_errors::RunnerError; use crate::vm::vm_core::VirtualMachine; use crate::vm::vm_memory::memory::Memory; @@ -18,14 +18,14 @@ const KECCAK_FELT_BYTE_SIZE: usize = 25; // 200 / 8 #[derive(Debug, Clone)] pub struct KeccakBuiltinRunner { - ratio: u32, + ratio: Option, pub base: usize, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, pub(crate) stop_ptr: Option, pub(crate) included: bool, state_rep: Vec, - instances_per_component: u32, + pub(crate) instances_per_component: u32, cache: RefCell>, } @@ -33,7 +33,7 @@ impl KeccakBuiltinRunner { pub(crate) fn new(instance_def: &KeccakInstanceDef, included: bool) -> Self { KeccakBuiltinRunner { base: 0, - ratio: instance_def._ratio, + ratio: instance_def.ratio, n_input_cells: instance_def._state_rep.len() as u32, cells_per_instance: instance_def.cells_per_builtin(), stop_ptr: None, @@ -60,7 +60,7 @@ impl KeccakBuiltinRunner { self.base } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } @@ -127,12 +127,6 @@ impl KeccakBuiltinRunner { Ok(self.cache.borrow().get(&address).map(|x| x.into())) } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -143,39 +137,6 @@ impl KeccakBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio * self.instances_per_component as usize; - if vm.current_step < min_step { - Err( - InsufficientAllocatedCellsError::MinStepNotReached(min_step, KECCAK_BUILTIN_NAME) - .into(), - ) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - KECCAK_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - KECCAK_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_used_instances( &self, segments: &MemorySegmentManager, @@ -293,7 +254,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { let builtin: BuiltinRunner = - KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), true).into(); + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), true).into(); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -304,7 +265,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), true); + let mut builtin = + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), true); let mut vm = vm!(); @@ -328,7 +290,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), true); + let mut builtin = + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), true); let mut vm = vm!(); @@ -356,7 +319,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_not_included() { let mut builtin = - KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), false); + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), false); let mut vm = vm!(); @@ -380,7 +343,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), true); + let mut builtin = + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), true); let mut vm = vm!(); @@ -405,7 +369,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_test() { let builtin: BuiltinRunner = - KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), true).into(); + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), true).into(); let mut vm = vm!(); @@ -436,12 +400,12 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { let builtin: BuiltinRunner = - KeccakBuiltinRunner::new(&KeccakInstanceDef::new(10, vec![200; 8]), true).into(); + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(10), vec![200; 8]), true).into(); let mut vm = vm!(); - vm.current_step = 10; + vm.current_step = 160; - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(16)); + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256)); } #[test] @@ -697,7 +661,7 @@ mod tests { ((0, 35), 0) ]; - let keccak_instance = KeccakInstanceDef::new(2048, vec![1; 8]); + let keccak_instance = KeccakInstanceDef::new(Some(2048), vec![1; 8]); let builtin = KeccakBuiltinRunner::new(&keccak_instance, true); let result = builtin.deduce_memory_cell(Relocatable::from((0, 25)), &memory); diff --git a/src/vm/runners/builtin_runner/mod.rs b/src/vm/runners/builtin_runner/mod.rs index bd6df181ee..41f0110895 100644 --- a/src/vm/runners/builtin_runner/mod.rs +++ b/src/vm/runners/builtin_runner/mod.rs @@ -1,6 +1,7 @@ +use crate::math_utils::safe_div_usize; use crate::stdlib::prelude::*; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; -use crate::vm::errors::memory_errors::{self, MemoryError}; +use crate::vm::errors::memory_errors::{self, InsufficientAllocatedCellsError, MemoryError}; use crate::vm::errors::runner_errors::RunnerError; use crate::vm::errors::vm_errors::VirtualMachineError; use crate::vm::vm_core::VirtualMachine; @@ -115,16 +116,34 @@ impl BuiltinRunner { vm: &VirtualMachine, ) -> Result { match *self { - BuiltinRunner::Bitwise(ref bitwise) => bitwise.get_allocated_memory_units(vm), - BuiltinRunner::EcOp(ref ec) => ec.get_allocated_memory_units(vm), - BuiltinRunner::Hash(ref hash) => hash.get_allocated_memory_units(vm), - BuiltinRunner::Output(ref output) => output.get_allocated_memory_units(vm), - BuiltinRunner::RangeCheck(ref range_check) => { - range_check.get_allocated_memory_units(vm) + BuiltinRunner::Output(_) => Ok(0), + _ => { + match self.ratio() { + None => { + // Dynamic layout has the exact number of instances it needs (up to a power of 2). + let instances: usize = + self.get_used_cells(&vm.segments)? / self.cells_per_instance() as usize; + let components = (instances / self.instances_per_component() as usize) + .next_power_of_two(); + Ok(self.cells_per_instance() as usize + * self.instances_per_component() as usize + * components) + } + Some(ratio) => { + let min_step = (ratio * self.instances_per_component()) as usize; + if vm.current_step < min_step { + return Err(InsufficientAllocatedCellsError::MinStepNotReached( + min_step, + self.name(), + ) + .into()); + }; + let value = safe_div_usize(vm.current_step, ratio as usize) + .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; + Ok(self.cells_per_instance() as usize * value) + } + } } - BuiltinRunner::Keccak(ref keccak) => keccak.get_allocated_memory_units(vm), - BuiltinRunner::Signature(ref signature) => signature.get_allocated_memory_units(vm), - BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_allocated_memory_units(vm), } } @@ -144,14 +163,14 @@ impl BuiltinRunner { pub fn ratio(&self) -> Option { match self { - BuiltinRunner::Bitwise(bitwise) => Some(bitwise.ratio()), - BuiltinRunner::EcOp(ec) => Some(ec.ratio()), - BuiltinRunner::Hash(hash) => Some(hash.ratio()), + BuiltinRunner::Bitwise(bitwise) => bitwise.ratio(), + BuiltinRunner::EcOp(ec) => ec.ratio(), + BuiltinRunner::Hash(hash) => hash.ratio(), BuiltinRunner::Output(_) => None, - BuiltinRunner::RangeCheck(range_check) => Some(range_check.ratio()), - BuiltinRunner::Keccak(keccak) => Some(keccak.ratio()), - BuiltinRunner::Signature(ref signature) => Some(signature.ratio()), - BuiltinRunner::Poseidon(poseidon) => Some(poseidon.ratio()), + BuiltinRunner::RangeCheck(range_check) => range_check.ratio(), + BuiltinRunner::Keccak(keccak) => keccak.ratio(), + BuiltinRunner::Signature(ref signature) => signature.ratio(), + BuiltinRunner::Poseidon(poseidon) => poseidon.ratio(), } } @@ -262,7 +281,8 @@ impl BuiltinRunner { ) -> Result { match self { BuiltinRunner::RangeCheck(range_check) => { - range_check.get_used_perm_range_check_units(vm) + let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?; + Ok(used_cells * range_check.n_parts as usize) } _ => Ok(0), } @@ -306,6 +326,19 @@ impl BuiltinRunner { } } + fn instances_per_component(&self) -> u32 { + match self { + BuiltinRunner::Bitwise(builtin) => builtin.instances_per_component, + BuiltinRunner::EcOp(builtin) => builtin.instances_per_component, + BuiltinRunner::Hash(builtin) => builtin.instances_per_component, + BuiltinRunner::RangeCheck(builtin) => builtin.instances_per_component, + BuiltinRunner::Output(_) => 0, + BuiltinRunner::Keccak(builtin) => builtin.instances_per_component, + BuiltinRunner::Signature(builtin) => builtin.instances_per_component, + BuiltinRunner::Poseidon(builtin) => builtin.instances_per_component, + } + } + pub fn name(&self) -> &'static str { match self { BuiltinRunner::Bitwise(_) => BITWISE_BUILTIN_NAME, @@ -384,18 +417,23 @@ impl BuiltinRunner { vm: &VirtualMachine, ) -> Result<(usize, usize), MemoryError> { match self { - BuiltinRunner::Bitwise(ref bitwise) => bitwise.get_used_cells_and_allocated_size(vm), - BuiltinRunner::EcOp(ref ec) => ec.get_used_cells_and_allocated_size(vm), - BuiltinRunner::Hash(ref hash) => hash.get_used_cells_and_allocated_size(vm), - BuiltinRunner::Output(ref output) => output.get_used_cells_and_allocated_size(vm), - BuiltinRunner::RangeCheck(ref range_check) => { - range_check.get_used_cells_and_allocated_size(vm) + BuiltinRunner::Output(_) => { + let used = self.get_used_cells(&vm.segments)?; + Ok((used, used)) } - BuiltinRunner::Keccak(ref keccak) => keccak.get_used_cells_and_allocated_size(vm), - BuiltinRunner::Signature(ref signature) => { - signature.get_used_cells_and_allocated_size(vm) + _ => { + let used = self.get_used_cells(&vm.segments)?; + let size = self.get_allocated_memory_units(vm)?; + if used > size { + return Err(InsufficientAllocatedCellsError::BuiltinCells( + self.name(), + used, + size, + ) + .into()); + } + Ok((used, size)) } - BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_cells_and_allocated_size(vm), } } @@ -471,6 +509,7 @@ mod tests { use crate::types::instance_definitions::ecdsa_instance_def::EcdsaInstanceDef; use crate::types::instance_definitions::keccak_instance_def::KeccakInstanceDef; use crate::types::program::Program; + use crate::vm::errors::memory_errors::InsufficientAllocatedCellsError; use crate::vm::runners::cairo_runner::CairoRunner; use crate::{ types::instance_definitions::{ @@ -530,7 +569,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_n_input_cells_bitwise() { - let bitwise = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let bitwise = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let builtin: BuiltinRunner = bitwise.clone().into(); assert_eq!(bitwise.n_input_cells, builtin.n_input_cells()) } @@ -538,7 +577,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_n_input_cells_hash() { - let hash = HashBuiltinRunner::new(10, true); + let hash = HashBuiltinRunner::new(Some(10), true); let builtin: BuiltinRunner = hash.clone().into(); assert_eq!(hash.n_input_cells, builtin.n_input_cells()) } @@ -546,7 +585,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_n_input_cells_range_check() { - let range_check = RangeCheckBuiltinRunner::new(10, 10, true); + let range_check = RangeCheckBuiltinRunner::new(Some(10), 10, true); let builtin: BuiltinRunner = range_check.clone().into(); assert_eq!(range_check.n_input_cells, builtin.n_input_cells()) } @@ -562,7 +601,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_n_input_cells_ecdsa() { - let signature = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(10), true); + let signature = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(Some(10)), true); let builtin: BuiltinRunner = signature.clone().into(); assert_eq!(signature.n_input_cells, builtin.n_input_cells()) } @@ -578,7 +617,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_cells_per_instance_bitwise() { - let bitwise = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let bitwise = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let builtin: BuiltinRunner = bitwise.clone().into(); assert_eq!(bitwise.cells_per_instance, builtin.cells_per_instance()) } @@ -586,7 +625,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_cells_per_instance_hash() { - let hash = HashBuiltinRunner::new(10, true); + let hash = HashBuiltinRunner::new(Some(10), true); let builtin: BuiltinRunner = hash.clone().into(); assert_eq!(hash.cells_per_instance, builtin.cells_per_instance()) } @@ -594,7 +633,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_cells_per_instance_range_check() { - let range_check = RangeCheckBuiltinRunner::new(10, 10, true); + let range_check = RangeCheckBuiltinRunner::new(Some(10), 10, true); let builtin: BuiltinRunner = range_check.clone().into(); assert_eq!(range_check.cells_per_instance, builtin.cells_per_instance()) } @@ -610,7 +649,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_cells_per_instance_ecdsa() { - let signature = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(10), true); + let signature = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(Some(10)), true); let builtin: BuiltinRunner = signature.clone().into(); assert_eq!(signature.cells_per_instance, builtin.cells_per_instance()) } @@ -634,7 +673,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_name_bitwise() { - let bitwise = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(10), true); + let bitwise = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(10)), true); let builtin: BuiltinRunner = bitwise.into(); assert_eq!(BITWISE_BUILTIN_NAME, builtin.name()) } @@ -642,7 +681,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_name_hash() { - let hash = HashBuiltinRunner::new(10, true); + let hash = HashBuiltinRunner::new(Some(10), true); let builtin: BuiltinRunner = hash.into(); assert_eq!(HASH_BUILTIN_NAME, builtin.name()) } @@ -650,7 +689,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_name_range_check() { - let range_check = RangeCheckBuiltinRunner::new(10, 10, true); + let range_check = RangeCheckBuiltinRunner::new(Some(10), 10, true); let builtin: BuiltinRunner = range_check.into(); assert_eq!(RANGE_CHECK_BUILTIN_NAME, builtin.name()) } @@ -666,7 +705,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_name_ecdsa() { - let signature = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(10), true); + let signature = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(Some(10)), true); let builtin: BuiltinRunner = signature.into(); assert_eq!(SIGNATURE_BUILTIN_NAME, builtin.name()) } @@ -683,7 +722,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_bitwise_with_items() { let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new( - &BitwiseInstanceDef::new(10), + &BitwiseInstanceDef::new(Some(10)), true, )); @@ -729,7 +768,10 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_ec_op_with_items() { - let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true)); + let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new( + &EcOpInstanceDef::new(Some(10)), + true, + )); let mut vm = vm!(); @@ -773,7 +815,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_hash_with_items() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(10, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(10), true)); let mut vm = vm!(); @@ -817,7 +859,7 @@ 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(10, 12, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(10), 12, true)); let mut vm = vm!(); @@ -862,13 +904,30 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_keccak_with_items() { let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new( - &KeccakInstanceDef::new(10, vec![200; 8]), + &KeccakInstanceDef::new(Some(10), vec![200; 8]), + true, + )); + + let mut vm = vm!(); + vm.current_step = 160; + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256)); + } + + #[test] + fn get_allocated_memory_units_keccak_min_steps_not_reached() { + let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new( + &KeccakInstanceDef::new(Some(10), vec![200; 8]), true, )); let mut vm = vm!(); vm.current_step = 10; - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(16)); + assert_eq!( + builtin.get_allocated_memory_units(&vm), + Err(MemoryError::InsufficientAllocatedCells( + InsufficientAllocatedCellsError::MinStepNotReached(160, KECCAK_BUILTIN_NAME) + )) + ); } #[test] @@ -884,17 +943,19 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_range_check() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(8, 8, true)); - let vm = vm!(); - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); + let mut vm = vm!(); + vm.current_step = 8; + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(1)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units_hash() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(1, true)); - let vm = vm!(); - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), true)); + let mut vm = vm!(); + vm.current_step = 1; + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(3)); } #[test] @@ -904,8 +965,9 @@ mod tests { &BitwiseInstanceDef::default(), true, )); - let vm = vm!(); - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0)); + let mut vm = vm!(); + vm.current_step = 256; + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(5)); } #[test] @@ -913,8 +975,9 @@ mod tests { fn get_allocated_memory_units_ec_op() { let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true)); - let vm = vm!(); - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0)); + let mut vm = vm!(); + vm.current_step = 256; + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(7)); } #[test] @@ -924,16 +987,17 @@ mod tests { &KeccakInstanceDef::default(), true, )); - let vm = vm!(); - assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0)); + let mut vm = vm!(); + vm.current_step = 32768; + assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_range_check() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(8, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 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((1, 4))); + assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4))); } #[test] @@ -947,7 +1011,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_hash() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(256, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)]; assert_eq!(builtin.get_range_check_usage(&memory), None); } @@ -1005,21 +1069,24 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_diluted_check_units_ec_op() { - let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::new(10), true)); + let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new( + &EcOpInstanceDef::new(Some(10)), + true, + )); assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_diluted_check_units_hash() { - let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(16, true)); + let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), true)); assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_diluted_check_units_range_check() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(8, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0); } @@ -1039,12 +1106,12 @@ mod tests { let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true).into(); assert_eq!(ec_op_builtin.get_memory_segment_addresses(), (0, None),); - let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(8, true).into(); + let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into(); 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(8, 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); assert_eq!( range_check_builtin.get_memory_segment_addresses(), (0, None), @@ -1140,7 +1207,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_hash_missing_memory_cells_with_offsets() { - let builtin: BuiltinRunner = HashBuiltinRunner::new(8, true).into(); + let builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into(); let mut vm = vm!(); vm.segments.memory = memory![ @@ -1161,7 +1228,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_security_checks_hash_missing_memory_cells() { - let hash_builtin = HashBuiltinRunner::new(8, true); + let hash_builtin = HashBuiltinRunner::new(Some(8), true); let builtin: BuiltinRunner = hash_builtin.into(); @@ -1180,7 +1247,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(8, 8, true); + let range_check_builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let builtin: BuiltinRunner = range_check_builtin.into(); let mut vm = vm!(); @@ -1205,7 +1272,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(8, 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); let mut vm = vm!(); vm.segments.memory = memory![((0, 1), 1)]; @@ -1221,7 +1288,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(8, 8, true); + let range_check_builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let builtin: BuiltinRunner = range_check_builtin.into(); @@ -1393,7 +1460,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_perm_range_check_units_hash() { - let builtin_runner: BuiltinRunner = HashBuiltinRunner::new(8, true).into(); + let builtin_runner: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into(); let mut vm = vm!(); vm.current_step = 8; @@ -1419,7 +1486,7 @@ 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(8, 8, true).into(); + let builtin_runner: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(8), 8, true).into(); let mut vm = vm!(); vm.current_step = 8; @@ -1436,12 +1503,12 @@ mod tests { let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true).into(); assert_eq!(ec_op_builtin.ratio(), (Some(256)),); - let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(8, true).into(); + let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into(); 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(8, 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); assert_eq!(range_check_builtin.ratio(), (Some(8)),); let keccak_builtin: BuiltinRunner = KeccakBuiltinRunner::new(&KeccakInstanceDef::default(), true).into(); @@ -1476,7 +1543,7 @@ mod tests { let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); - let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(8, true).into(); + let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into(); assert_eq!(hash_builtin.get_used_instances(&vm.segments), Ok(2)); } @@ -1496,7 +1563,7 @@ mod tests { vm.segments.segment_used_sizes = Some(vec![4]); let range_check_builtin: BuiltinRunner = - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(8, 8, true)); + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, true)); assert_eq!(range_check_builtin.get_used_instances(&vm.segments), Ok(4)); } @@ -1509,9 +1576,9 @@ mod tests { false, )), BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), false)), - BuiltinRunner::Hash(HashBuiltinRunner::new(1, false)), + BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)), BuiltinRunner::Output(OutputBuiltinRunner::new(false)), - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(8, 8, false)), + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, false)), BuiltinRunner::Keccak(KeccakBuiltinRunner::new( &KeccakInstanceDef::default(), false, @@ -1537,9 +1604,9 @@ mod tests { false, )), BuiltinRunner::EcOp(EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), false)), - BuiltinRunner::Hash(HashBuiltinRunner::new(1, false)), + BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)), BuiltinRunner::Output(OutputBuiltinRunner::new(false)), - BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(8, 8, false)), + BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(8), 8, false)), BuiltinRunner::Keccak(KeccakBuiltinRunner::new( &KeccakInstanceDef::default(), false, diff --git a/src/vm/runners/builtin_runner/output.rs b/src/vm/runners/builtin_runner/output.rs index 131d23c4ee..5778ab02d7 100644 --- a/src/vm/runners/builtin_runner/output.rs +++ b/src/vm/runners/builtin_runner/output.rs @@ -64,14 +64,6 @@ impl OutputBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let used = self.get_used_cells(&vm.segments)?; - Ok((used, used)) - } - pub fn get_used_instances( &self, segments: &MemorySegmentManager, diff --git a/src/vm/runners/builtin_runner/poseidon.rs b/src/vm/runners/builtin_runner/poseidon.rs index 0ced2d714e..08ab6d5362 100644 --- a/src/vm/runners/builtin_runner/poseidon.rs +++ b/src/vm/runners/builtin_runner/poseidon.rs @@ -1,12 +1,10 @@ -use crate::math_utils::safe_div_usize; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*}; use crate::types::instance_definitions::poseidon_instance_def::{ CELLS_PER_POSEIDON, INPUT_CELLS_PER_POSEIDON, }; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; -use crate::vm::errors::memory_errors::{InsufficientAllocatedCellsError, MemoryError}; +use crate::vm::errors::memory_errors::MemoryError; use crate::vm::errors::runner_errors::RunnerError; -use crate::vm::vm_core::VirtualMachine; use crate::vm::vm_memory::memory::Memory; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use felt::Felt252; @@ -21,16 +19,17 @@ use super::POSEIDON_BUILTIN_NAME; #[derive(Debug, Clone)] pub struct PoseidonBuiltinRunner { pub base: usize, - ratio: u32, + ratio: Option, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, pub(crate) stop_ptr: Option, pub(crate) included: bool, cache: RefCell>, + pub(crate) instances_per_component: u32, } impl PoseidonBuiltinRunner { - pub fn new(ratio: u32, included: bool) -> Self { + pub fn new(ratio: Option, included: bool) -> Self { PoseidonBuiltinRunner { base: 0, ratio, @@ -39,6 +38,7 @@ impl PoseidonBuiltinRunner { stop_ptr: None, included, cache: RefCell::new(HashMap::new()), + instances_per_component: 1, } } @@ -58,7 +58,7 @@ impl PoseidonBuiltinRunner { self.base } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } @@ -110,12 +110,6 @@ impl PoseidonBuiltinRunner { Ok(self.cache.borrow().get(&address).map(|x| x.into())) } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -126,39 +120,6 @@ impl PoseidonBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio /* TODO: Override with change */; - if vm.current_step < min_step { - Err( - InsufficientAllocatedCellsError::MinStepNotReached(min_step, POSEIDON_BUILTIN_NAME) - .into(), - ) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - POSEIDON_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - POSEIDON_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_used_instances( &self, segments: &MemorySegmentManager, @@ -223,7 +184,7 @@ mod tests { #[test] fn get_used_instances() { - let builtin = PoseidonBuiltinRunner::new(10, true); + let builtin = PoseidonBuiltinRunner::new(Some(10), true); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -233,7 +194,7 @@ mod tests { #[test] fn final_stack() { - let mut builtin = PoseidonBuiltinRunner::new(10, true); + let mut builtin = PoseidonBuiltinRunner::new(Some(10), true); let mut vm = vm!(); @@ -256,7 +217,7 @@ mod tests { #[test] fn final_stack_error_stop_pointer() { - let mut builtin = PoseidonBuiltinRunner::new(10, true); + let mut builtin = PoseidonBuiltinRunner::new(Some(10), true); let mut vm = vm!(); @@ -283,7 +244,7 @@ mod tests { #[test] fn final_stack_error_when_not_included() { - let mut builtin = PoseidonBuiltinRunner::new(10, false); + let mut builtin = PoseidonBuiltinRunner::new(Some(10), false); let mut vm = vm!(); @@ -306,7 +267,7 @@ mod tests { #[test] fn final_stack_error_non_relocatable() { - let mut builtin = PoseidonBuiltinRunner::new(10, true); + let mut builtin = PoseidonBuiltinRunner::new(Some(10), true); let mut vm = vm!(); @@ -329,7 +290,7 @@ mod tests { #[test] fn get_used_cells_and_allocated_size_test() { - let builtin: BuiltinRunner = PoseidonBuiltinRunner::new(10, true).into(); + let builtin: BuiltinRunner = PoseidonBuiltinRunner::new(Some(10), true).into(); let mut vm = vm!(); @@ -374,7 +335,7 @@ mod tests { #[test] fn get_allocated_memory_units() { - let builtin = PoseidonBuiltinRunner::new(10, true); + let builtin: BuiltinRunner = PoseidonBuiltinRunner::new(Some(10), true).into(); let mut vm = vm!(); diff --git a/src/vm/runners/builtin_runner/range_check.rs b/src/vm/runners/builtin_runner/range_check.rs index 8f5d372e36..8571db61e6 100644 --- a/src/vm/runners/builtin_runner/range_check.rs +++ b/src/vm/runners/builtin_runner/range_check.rs @@ -5,17 +5,12 @@ use crate::stdlib::{ }; use crate::{ - math_utils::safe_div_usize, types::{ instance_definitions::range_check_instance_def::CELLS_PER_RANGE_CHECK, relocatable::{MaybeRelocatable, Relocatable}, }, vm::{ - errors::{ - memory_errors::{InsufficientAllocatedCellsError, MemoryError}, - runner_errors::RunnerError, - }, - vm_core::VirtualMachine, + errors::{memory_errors::MemoryError, runner_errors::RunnerError}, vm_memory::{ memory::{Memory, ValidationRule}, memory_segments::MemorySegmentManager, @@ -30,7 +25,7 @@ use super::RANGE_CHECK_BUILTIN_NAME; #[derive(Debug, Clone)] pub struct RangeCheckBuiltinRunner { - ratio: u32, + ratio: Option, base: usize, pub(crate) stop_ptr: Option, pub(crate) cells_per_instance: u32, @@ -38,12 +33,12 @@ pub struct RangeCheckBuiltinRunner { inner_rc_bound: usize, pub _bound: Option, pub(crate) included: bool, - n_parts: u32, - instances_per_component: u32, + pub(crate) n_parts: u32, + pub(crate) instances_per_component: u32, } impl RangeCheckBuiltinRunner { - pub fn new(ratio: u32, n_parts: u32, included: bool) -> RangeCheckBuiltinRunner { + pub fn new(ratio: Option, n_parts: u32, included: bool) -> RangeCheckBuiltinRunner { let inner_rc_bound = 1_usize << 16; let bound = Felt252::one().shl(16 * n_parts); @@ -83,7 +78,7 @@ impl RangeCheckBuiltinRunner { self.base } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } @@ -115,12 +110,6 @@ impl RangeCheckBuiltinRunner { Ok(None) } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -131,53 +120,15 @@ impl RangeCheckBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio * self.instances_per_component as usize; - if vm.current_step < min_step { - Err(InsufficientAllocatedCellsError::MinStepNotReached( - min_step, - RANGE_CHECK_BUILTIN_NAME, - ) - .into()) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - RANGE_CHECK_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - RANGE_CHECK_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_range_check_usage(&self, memory: &Memory) -> Option<(usize, usize)> { let mut rc_bounds: Option<(usize, usize)> = None; let range_check_segment = memory.data.get(self.base)?; let inner_rc_bound = Felt252::new(self.inner_rc_bound); for value in range_check_segment { //Split val into n_parts parts. + let mut val = value.as_ref()?.get_value().get_int_ref()?.clone(); for _ in 0..self.n_parts { - let part_val = value - .as_ref()? - .get_value() - .get_int_ref()? - .mod_floor(&inner_rc_bound) - .to_usize()?; + let part_val = val.mod_floor(&inner_rc_bound).to_usize()?; rc_bounds = Some(match rc_bounds { None => (part_val, part_val), Some((rc_min, rc_max)) => { @@ -187,6 +138,7 @@ impl RangeCheckBuiltinRunner { (rc_min, rc_max) } }); + val = val.div_floor(&inner_rc_bound) } } rc_bounds @@ -236,15 +188,6 @@ impl RangeCheckBuiltinRunner { Ok(pointer) } } - - /// Returns the number of range check units used by the builtin. - pub fn get_used_perm_range_check_units( - &self, - vm: &VirtualMachine, - ) -> Result { - let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?; - Ok(used_cells * self.n_parts as usize) - } } #[cfg(test)] @@ -270,7 +213,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_instances() { - let builtin = RangeCheckBuiltinRunner::new(10, 12, true); + let builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![1]); @@ -281,7 +224,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack() { - let mut builtin = RangeCheckBuiltinRunner::new(10, 12, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); let mut vm = vm!(); @@ -305,7 +248,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_stop_pointer() { - let mut builtin = RangeCheckBuiltinRunner::new(10, 12, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); let mut vm = vm!(); @@ -333,7 +276,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_when_notincluded() { - let mut builtin = RangeCheckBuiltinRunner::new(10, 12, false); + let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, false); let mut vm = vm!(); @@ -357,7 +300,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn final_stack_error_non_relocatable() { - let mut builtin = RangeCheckBuiltinRunner::new(10, 12, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(10), 12, true); let mut vm = vm!(); @@ -381,7 +324,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(10, 12, true).into(); + let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(10), 12, true).into(); let mut vm = vm!(); @@ -427,7 +370,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_allocated_memory_units() { - let builtin = RangeCheckBuiltinRunner::new(10, 12, true); + let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(10), 12, true).into(); let mut vm = vm!(); @@ -471,7 +414,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn initialize_segments_for_range_check() { - let mut builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); assert_eq!(builtin.base, 0); @@ -480,7 +423,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(8, 8, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); builtin.base = 1; let initial_stack = builtin.initial_stack(); assert_eq!( @@ -493,7 +436,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_segment_addresses() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); assert_eq!(builtin.get_memory_segment_addresses(), (0, None),); } @@ -501,7 +444,7 @@ 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(256, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); let vm = vm!(); assert_eq!( @@ -513,7 +456,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses_empty() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(256, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -523,7 +466,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_memory_accesses() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(256, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -541,21 +484,21 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_base() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); assert_eq!(builtin.base(), 0); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_ratio() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); - assert_eq!(builtin.ratio(), 8); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 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(256, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); let vm = vm!(); assert_eq!( @@ -567,7 +510,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_empty() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(256, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![0]); @@ -577,7 +520,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells() { - let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(256, 8, true)); + let builtin = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::new(Some(256), 8, true)); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![4]); @@ -587,28 +530,28 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_a() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 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((1, 4))); + assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4))); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_b() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let memory = memory![ ((0, 0), 1465218365), ((0, 1), 2134570341), ((0, 2), 31349610736_i64), ((0, 3), 413468326585859_i64) ]; - assert_eq!(builtin.get_range_check_usage(&memory), Some((6384, 62821))); + assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 62821))); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_usage_succesful_c() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let memory = memory![ ((0, 0), 634834751465218365_i64), ((0, 1), 42876922134570341_i64), @@ -617,13 +560,13 @@ mod tests { ((0, 4), 75346043276073460326_i128), ((0, 5), 87234598724867609478353436890268_i128) ]; - assert_eq!(builtin.get_range_check_usage(&memory), Some((10480, 42341))); + assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 61576))); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_range_check_empty_memory() { - let builtin = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let memory = Memory::new(); assert_eq!(builtin.get_range_check_usage(&memory), None); } @@ -632,7 +575,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_perm_range_check_units() { - let builtin_runner = RangeCheckBuiltinRunner::new(8, 8, true); + let builtin_runner: BuiltinRunner = RangeCheckBuiltinRunner::new(Some(8), 8, true).into(); let mut vm = vm!(); vm.current_step = 8; diff --git a/src/vm/runners/builtin_runner/signature.rs b/src/vm/runners/builtin_runner/signature.rs index 996c9c96e6..6867bdfada 100644 --- a/src/vm/runners/builtin_runner/signature.rs +++ b/src/vm/runners/builtin_runner/signature.rs @@ -1,17 +1,12 @@ use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*, rc::Rc}; use crate::{ - math_utils::safe_div_usize, types::{ instance_definitions::ecdsa_instance_def::EcdsaInstanceDef, relocatable::{MaybeRelocatable, Relocatable}, }, vm::{ - errors::{ - memory_errors::{InsufficientAllocatedCellsError, MemoryError}, - runner_errors::RunnerError, - }, - vm_core::VirtualMachine, + errors::{memory_errors::MemoryError, runner_errors::RunnerError}, vm_memory::{ memory::{Memory, ValidationRule}, memory_segments::MemorySegmentManager, @@ -27,13 +22,13 @@ use super::SIGNATURE_BUILTIN_NAME; #[derive(Debug, Clone)] pub struct SignatureBuiltinRunner { pub(crate) included: bool, - ratio: u32, + ratio: Option, base: usize, pub(crate) cells_per_instance: u32, pub(crate) n_input_cells: u32, _total_n_bits: u32, pub(crate) stop_ptr: Option, - instances_per_component: u32, + pub(crate) instances_per_component: u32, signatures: Rc>>, } @@ -155,16 +150,10 @@ impl SignatureBuiltinRunner { Ok(None) } - pub fn ratio(&self) -> u32 { + pub fn ratio(&self) -> Option { self.ratio } - pub fn get_allocated_memory_units(&self, vm: &VirtualMachine) -> Result { - let value = safe_div_usize(vm.current_step, self.ratio as usize) - .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?; - Ok(self.cells_per_instance as usize * value) - } - pub fn get_memory_segment_addresses(&self) -> (usize, Option) { (self.base, self.stop_ptr) } @@ -175,40 +164,6 @@ impl SignatureBuiltinRunner { .ok_or(MemoryError::MissingSegmentUsedSizes) } - pub fn get_used_cells_and_allocated_size( - &self, - vm: &VirtualMachine, - ) -> Result<(usize, usize), MemoryError> { - let ratio = self.ratio as usize; - let min_step = ratio * self.instances_per_component as usize; - if vm.current_step < min_step { - Err(InsufficientAllocatedCellsError::MinStepNotReached( - min_step, - SIGNATURE_BUILTIN_NAME, - ) - .into()) - } else { - let used = self.get_used_cells(&vm.segments)?; - let size = self.cells_per_instance as usize - * safe_div_usize(vm.current_step, ratio).map_err(|_| { - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - SIGNATURE_BUILTIN_NAME, - vm.current_step, - ratio, - ) - })?; - if used > size { - return Err(InsufficientAllocatedCellsError::BuiltinCells( - SIGNATURE_BUILTIN_NAME, - used, - size, - ) - .into()); - } - Ok((used, size)) - } - } - pub fn get_used_instances( &self, segments: &MemorySegmentManager, @@ -264,7 +219,7 @@ mod tests { types::instance_definitions::ecdsa_instance_def::EcdsaInstanceDef, utils::test_utils::*, vm::{ - errors::memory_errors::MemoryError, + errors::memory_errors::{InsufficientAllocatedCellsError, MemoryError}, runners::builtin_runner::BuiltinRunner, vm_core::VirtualMachine, vm_memory::{memory::Memory, memory_segments::MemorySegmentManager}, @@ -275,24 +230,9 @@ mod tests { use wasm_bindgen_test::*; #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_used_cells_and_allocated_size_min_step_not_reached() { - let builtin = SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true); - let mut vm = vm!(); - vm.current_step = 100; - vm.segments.segment_used_sizes = Some(vec![1]); - assert_eq!( - builtin.get_used_cells_and_allocated_size(&vm), - Err(MemoryError::InsufficientAllocatedCells( - InsufficientAllocatedCellsError::MinStepNotReached(512, SIGNATURE_BUILTIN_NAME) - )) - ); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_valid() { - let builtin = SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(10), true); + let builtin: BuiltinRunner = + SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(Some(10)), true).into(); let mut vm = vm!(); vm.current_step = 110; vm.segments.segment_used_sizes = Some(vec![1]); @@ -527,7 +467,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_ratio() { let builtin = SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true); - assert_eq!(builtin.ratio(), 512); + assert_eq!(builtin.ratio(), Some(512)); } #[test] @@ -556,31 +496,15 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_allocated_memory_units_safe_div_fail() { - let builtin = SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true); + fn get_allocated_memory_min_step_not_reached() { + let builtin: BuiltinRunner = + SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into(); let mut vm = vm!(); vm.current_step = 500; assert_eq!( builtin.get_allocated_memory_units(&vm), - Err(MemoryError::ErrorCalculatingMemoryUnits) - ) - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_used_cells_and_allocated_size_safe_div_fail() { - let builtin = SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true); - let mut vm = vm!(); - vm.segments.segment_used_sizes = Some(vec![600]); - vm.current_step = 551; - assert_eq!( - builtin.get_used_cells_and_allocated_size(&vm), Err(MemoryError::InsufficientAllocatedCells( - InsufficientAllocatedCellsError::CurrentStepNotDivisibleByBuiltinRatio( - SIGNATURE_BUILTIN_NAME, - 551, - builtin.ratio as usize - ) + InsufficientAllocatedCellsError::MinStepNotReached(512, SIGNATURE_BUILTIN_NAME) )) ) } @@ -588,7 +512,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_used_cells_and_allocated_size_insufficient_allocated() { - let builtin = SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true); + let builtin: BuiltinRunner = + SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into(); let mut vm = vm!(); vm.segments.segment_used_sizes = Some(vec![50]); vm.current_step = 512; diff --git a/src/vm/runners/cairo_runner.rs b/src/vm/runners/cairo_runner.rs index 14b6b287ed..4c638cca34 100644 --- a/src/vm/runners/cairo_runner.rs +++ b/src/vm/runners/cairo_runner.rs @@ -105,6 +105,7 @@ impl CairoRunner { "recursive_large_output" => CairoLayout::recursive_large_output_instance(), "all_cairo" => CairoLayout::all_cairo_instance(), "all_solidity" => CairoLayout::all_solidity_instance(), + "dynamic" => CairoLayout::dynamic_instance(), name => return Err(RunnerError::InvalidLayoutName(name.to_string())), }; Ok(CairoRunner { @@ -243,28 +244,29 @@ impl CairoRunner { match name { BuiltinName::pedersen => vm .builtin_runners - .push(HashBuiltinRunner::new(32, true).into()), + .push(HashBuiltinRunner::new(Some(32), true).into()), BuiltinName::range_check => vm .builtin_runners - .push(RangeCheckBuiltinRunner::new(1, 8, true).into()), + .push(RangeCheckBuiltinRunner::new(Some(1), 8, true).into()), BuiltinName::output => vm .builtin_runners .push(OutputBuiltinRunner::new(true).into()), - BuiltinName::ecdsa => vm - .builtin_runners - .push(SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(1), true).into()), - BuiltinName::bitwise => vm - .builtin_runners - .push(BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(1), true).into()), + BuiltinName::ecdsa => vm.builtin_runners.push( + SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(Some(1)), true).into(), + ), + BuiltinName::bitwise => vm.builtin_runners.push( + BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(Some(1)), true).into(), + ), BuiltinName::ec_op => vm .builtin_runners - .push(EcOpBuiltinRunner::new(&EcOpInstanceDef::new(1), true).into()), + .push(EcOpBuiltinRunner::new(&EcOpInstanceDef::new(Some(1)), true).into()), BuiltinName::keccak => vm.builtin_runners.push( - KeccakBuiltinRunner::new(&KeccakInstanceDef::new(1, vec![200; 8]), true).into(), + KeccakBuiltinRunner::new(&KeccakInstanceDef::new(Some(1), vec![200; 8]), true) + .into(), ), BuiltinName::poseidon => vm .builtin_runners - .push(PoseidonBuiltinRunner::new(1, true).into()), + .push(PoseidonBuiltinRunner::new(Some(1), true).into()), } } @@ -984,7 +986,7 @@ impl CairoRunner { /// with the new builtin base as the segment index. pub fn add_additional_hash_builtin(&self, vm: &mut VirtualMachine) -> Relocatable { // Create, initialize and insert the new custom hash runner. - let mut builtin: BuiltinRunner = HashBuiltinRunner::new(32, true).into(); + let mut builtin: BuiltinRunner = HashBuiltinRunner::new(Some(32), true).into(); builtin.initialize_segments(&mut vm.segments); let segment_index = builtin.base() as isize; vm.builtin_runners.push(builtin); @@ -3641,7 +3643,7 @@ mod tests { assert_matches!( cairo_runner.get_perm_range_check_limits(&vm), - Ok(Some((-31440, 16383))) + Ok(Some((1328, 49151))) ); } @@ -3663,11 +3665,11 @@ mod tests { vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(12, 5, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(12), 5, true).into()]; assert_matches!( cairo_runner.get_perm_range_check_limits(&vm), - Ok(Some((-31440, 1328))) + Ok(Some((0, 33023))) ); } @@ -3717,7 +3719,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(8, 8, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(8), 8, true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; @@ -3726,6 +3728,7 @@ mod tests { ap: 0, fp: 0, }]); + vm.segments.compute_effective_sizes(); assert_matches!( cairo_runner.check_range_check_usage(&vm), @@ -3784,7 +3787,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(8, 8, true).into()]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(Some(8), 8, true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; @@ -3793,7 +3796,7 @@ mod tests { ap: 0, fp: 0, }]); - + vm.segments.compute_effective_sizes(); assert_matches!( cairo_runner.check_used_cells(&vm), Err(VirtualMachineError::Memory( @@ -4314,7 +4317,7 @@ mod tests { match builtin { BuiltinRunner::Hash(builtin) => { assert_eq!(builtin.base(), 0); - assert_eq!(builtin.ratio(), 32); + assert_eq!(builtin.ratio(), Some(32)); assert!(builtin.included); } _ => unreachable!(), diff --git a/src/vm/trace/mod.rs b/src/vm/trace/mod.rs index 3e7178296e..142e7661ac 100644 --- a/src/vm/trace/mod.rs +++ b/src/vm/trace/mod.rs @@ -1,3 +1,5 @@ +use core::ops::Shl; + use self::trace_entry::TraceEntry; use super::{ decoding::decoder::decode_instruction, @@ -9,7 +11,7 @@ use crate::types::relocatable::{MaybeRelocatable, Relocatable}; use num_traits::ToPrimitive; pub mod trace_entry; - +const OFFSET_BITS: u32 = 16; /// Return the minimum and maximum values in the perm_range_check component. pub fn get_perm_range_check_limits( trace: &[TraceEntry], @@ -33,9 +35,9 @@ pub fn get_perm_range_check_limits( .transpose()?; let decoded_instruction = decode_instruction(instruction, immediate.as_ref())?; - let off0 = decoded_instruction.off0; - let off1 = decoded_instruction.off1; - let off2 = decoded_instruction.off2; + let off0 = decoded_instruction.off0 + 1_isize.shl(OFFSET_BITS - 1); + let off1 = decoded_instruction.off1 + 1_isize.shl(OFFSET_BITS - 1); + let off2 = decoded_instruction.off2 + 1_isize.shl(OFFSET_BITS - 1); let min_value = off0.min(off1).min(off2); let max_value = off0.max(off1).max(off2); @@ -79,9 +81,12 @@ mod test { }]; let memory = memory![((0, 0), 0xFFFF_8000_0000_u64)]; + // off0 -32768 + // off1 0 + // off2 32767 assert_matches!( get_perm_range_check_limits(trace, &memory), - Ok(Some((-32768, 32767))) + Ok(Some((0, 65535))) ); } @@ -115,7 +120,7 @@ mod test { assert_matches!( get_perm_range_check_limits(trace, &memory), - Ok(Some((-31440, 16383))) + Ok(Some((1328, 49151))) ); } } diff --git a/src/vm/vm_core.rs b/src/vm/vm_core.rs index 49b4557d55..ec2f1610a1 100644 --- a/src/vm/vm_core.rs +++ b/src/vm/vm_core.rs @@ -3207,7 +3207,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn deduce_memory_cell_pedersen_builtin_valid() { let mut vm = vm!(); - let builtin = HashBuiltinRunner::new(8, true); + let builtin = HashBuiltinRunner::new(Some(8), true); vm.builtin_runners.push(builtin.into()); vm.segments = segments![((0, 3), 32), ((0, 4), 72), ((0, 5), 0)]; assert_matches!( @@ -3258,7 +3258,7 @@ mod tests { fp_update: FpUpdate::Regular, opcode: Opcode::AssertEq, }; - let mut builtin = HashBuiltinRunner::new(8, true); + let mut builtin = HashBuiltinRunner::new(Some(8), true); builtin.base = 3; let mut vm = vm!(); vm.builtin_runners.push(builtin.into()); @@ -3645,7 +3645,7 @@ mod tests { end */ fn verify_auto_deductions_pedersen() { - let mut builtin = HashBuiltinRunner::new(8, true); + let mut builtin = HashBuiltinRunner::new(Some(8), true); builtin.base = 3; let mut vm = vm!(); vm.builtin_runners.push(builtin.into()); @@ -3780,7 +3780,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_get_builtin_runners() { let mut vm = vm!(); - let hash_builtin = HashBuiltinRunner::new(8, true); + let hash_builtin = HashBuiltinRunner::new(Some(8), true); let bitwise_builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true); vm.builtin_runners.push(hash_builtin.into()); vm.builtin_runners.push(bitwise_builtin.into()); @@ -4228,7 +4228,10 @@ mod tests { let virtual_machine_builder: VirtualMachineBuilder = VirtualMachineBuilder::default() .run_finished(true) .current_step(12) - .builtin_runners(vec![BuiltinRunner::from(HashBuiltinRunner::new(12, true))]) + .builtin_runners(vec![BuiltinRunner::from(HashBuiltinRunner::new( + Some(12), + true, + ))]) .run_context(RunContext { pc: Relocatable::from((0, 0)), ap: 18, diff --git a/src/vm/vm_memory/memory.rs b/src/vm/vm_memory/memory.rs index b9aa6a7565..f0b9ac096d 100644 --- a/src/vm/vm_memory/memory.rs +++ b/src/vm/vm_memory/memory.rs @@ -656,7 +656,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(8, 8, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); builtin.add_validation_rule(&mut segments.memory); @@ -681,7 +681,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(8, 8, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let mut segments = MemorySegmentManager::new(); segments.add(); builtin.initialize_segments(&mut segments); @@ -771,7 +771,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(8, 8, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let mut segments = MemorySegmentManager::new(); builtin.initialize_segments(&mut segments); segments.memory = memory![((0, 0), (0, 4))]; @@ -786,7 +786,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(8, 8, true); + let mut builtin = RangeCheckBuiltinRunner::new(Some(8), 8, true); let mut segments = MemorySegmentManager::new(); segments.memory = Memory::new(); segments.add();