1use crate::air_private_input::PrivateInput;
2use crate::math_utils::safe_div_usize;
3use crate::stdlib::prelude::*;
4use crate::types::builtin_name::BuiltinName;
5use crate::types::instance_definitions::bitwise_instance_def::{
6 CELLS_PER_BITWISE, INPUT_CELLS_PER_BITWISE,
7};
8use crate::types::instance_definitions::builtins_instance_def::BUILTIN_INSTANCES_PER_COMPONENT;
9use crate::types::instance_definitions::ec_op_instance_def::{
10 CELLS_PER_EC_OP, INPUT_CELLS_PER_EC_OP,
11};
12use crate::types::instance_definitions::ecdsa_instance_def::CELLS_PER_SIGNATURE;
13use crate::types::instance_definitions::keccak_instance_def::{
14 CELLS_PER_KECCAK, INPUT_CELLS_PER_KECCAK, KECCAK_INSTANCES_PER_COMPONENT,
15};
16use crate::types::instance_definitions::mod_instance_def::CELLS_PER_MOD;
17use crate::types::instance_definitions::pedersen_instance_def::{
18 CELLS_PER_HASH, INPUT_CELLS_PER_HASH,
19};
20use crate::types::instance_definitions::poseidon_instance_def::{
21 CELLS_PER_POSEIDON, INPUT_CELLS_PER_POSEIDON,
22};
23use crate::types::instance_definitions::range_check_instance_def::CELLS_PER_RANGE_CHECK;
24use crate::types::relocatable::{MaybeRelocatable, Relocatable};
25use crate::vm::errors::memory_errors::{self, InsufficientAllocatedCellsError, MemoryError};
26use crate::vm::errors::runner_errors::RunnerError;
27use crate::vm::errors::vm_errors::VirtualMachineError;
28use crate::vm::vm_core::VirtualMachine;
29use crate::vm::vm_memory::memory::Memory;
30use crate::vm::vm_memory::memory_segments::MemorySegmentManager;
31
32mod bitwise;
33mod ec_op;
34mod hash;
35mod keccak;
36mod modulo;
37mod output;
38mod poseidon;
39mod range_check;
40mod segment_arena;
41mod signature;
42
43pub use self::keccak::KeccakBuiltinRunner;
44pub(crate) use self::range_check::{RC_N_PARTS_96, RC_N_PARTS_STANDARD};
45use self::segment_arena::ARENA_BUILTIN_SIZE;
46pub use bitwise::BitwiseBuiltinRunner;
47pub use ec_op::EcOpBuiltinRunner;
48pub use hash::HashBuiltinRunner;
49pub use modulo::ModBuiltinRunner;
50use num_integer::{div_ceil, div_floor};
51pub use output::{OutputBuiltinRunner, OutputBuiltinState};
52pub use poseidon::PoseidonBuiltinRunner;
53pub use range_check::RangeCheckBuiltinRunner;
54pub use segment_arena::SegmentArenaBuiltinRunner;
55pub use signature::SignatureBuiltinRunner;
56
57use super::cairo_pie::BuiltinAdditionalData;
58
59const MIN_N_INSTANCES_IN_BUILTIN_SEGMENT: usize = 16;
60
61const _: () = assert!(MIN_N_INSTANCES_IN_BUILTIN_SEGMENT.is_power_of_two());
63
64#[derive(Debug, Clone)]
73pub enum BuiltinRunner {
74 Bitwise(BitwiseBuiltinRunner),
75 EcOp(EcOpBuiltinRunner),
76 Hash(HashBuiltinRunner),
77 Output(OutputBuiltinRunner),
78 RangeCheck(RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>),
79 RangeCheck96(RangeCheckBuiltinRunner<RC_N_PARTS_96>),
80 Keccak(KeccakBuiltinRunner),
81 Signature(SignatureBuiltinRunner),
82 Poseidon(PoseidonBuiltinRunner),
83 SegmentArena(SegmentArenaBuiltinRunner),
84 Mod(ModBuiltinRunner),
85}
86
87impl BuiltinRunner {
88 pub fn initialize_segments(&mut self, segments: &mut MemorySegmentManager) {
90 match *self {
91 BuiltinRunner::Bitwise(ref mut bitwise) => bitwise.initialize_segments(segments),
92 BuiltinRunner::EcOp(ref mut ec) => ec.initialize_segments(segments),
93 BuiltinRunner::Hash(ref mut hash) => hash.initialize_segments(segments),
94 BuiltinRunner::Output(ref mut output) => output.initialize_segments(segments),
95 BuiltinRunner::RangeCheck(ref mut range_check) => {
96 range_check.initialize_segments(segments)
97 }
98 BuiltinRunner::RangeCheck96(ref mut range_check) => {
99 range_check.initialize_segments(segments)
100 }
101 BuiltinRunner::Keccak(ref mut keccak) => keccak.initialize_segments(segments),
102 BuiltinRunner::Signature(ref mut signature) => signature.initialize_segments(segments),
103 BuiltinRunner::Poseidon(ref mut poseidon) => poseidon.initialize_segments(segments),
104 BuiltinRunner::SegmentArena(ref mut segment_arena) => {
105 segment_arena.initialize_segments(segments)
106 }
107 BuiltinRunner::Mod(ref mut modulo) => modulo.initialize_segments(segments),
108 }
109 }
110
111 pub fn initial_stack(&self) -> Vec<MaybeRelocatable> {
112 match *self {
113 BuiltinRunner::Bitwise(ref bitwise) => bitwise.initial_stack(),
114 BuiltinRunner::EcOp(ref ec) => ec.initial_stack(),
115 BuiltinRunner::Hash(ref hash) => hash.initial_stack(),
116 BuiltinRunner::Output(ref output) => output.initial_stack(),
117 BuiltinRunner::RangeCheck(ref range_check) => range_check.initial_stack(),
118 BuiltinRunner::RangeCheck96(ref range_check) => range_check.initial_stack(),
119 BuiltinRunner::Keccak(ref keccak) => keccak.initial_stack(),
120 BuiltinRunner::Signature(ref signature) => signature.initial_stack(),
121 BuiltinRunner::Poseidon(ref poseidon) => poseidon.initial_stack(),
122 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.initial_stack(),
123 BuiltinRunner::Mod(ref modulo) => modulo.initial_stack(),
124 }
125 }
126
127 pub fn final_stack(
129 &mut self,
130 segments: &MemorySegmentManager,
131 pointer: Relocatable,
132 ) -> Result<Relocatable, RunnerError> {
133 if let BuiltinRunner::Output(output) = self {
134 return output.final_stack(segments, pointer);
135 }
136 if self.included() {
137 let stop_pointer_addr =
138 (pointer - 1).map_err(|_| RunnerError::NoStopPointer(Box::new(self.name())))?;
139 let stop_pointer = segments
140 .memory
141 .get_relocatable(stop_pointer_addr)
142 .map_err(|_| RunnerError::NoStopPointer(Box::new(self.name())))?;
143 if self.base() as isize != stop_pointer.segment_index {
144 return Err(RunnerError::InvalidStopPointerIndex(Box::new((
145 self.name(),
146 stop_pointer,
147 self.base(),
148 ))));
149 }
150 let stop_ptr = stop_pointer.offset;
151 let mut num_instances = self.get_used_instances(segments)?;
152 if matches!(self, BuiltinRunner::SegmentArena(_)) {
153 num_instances += 1;
157 }
158 let used = num_instances * self.cells_per_instance() as usize;
159 if stop_ptr != used {
160 return Err(RunnerError::InvalidStopPointer(Box::new((
161 self.name(),
162 Relocatable::from((self.base() as isize, used)),
163 Relocatable::from((self.base() as isize, stop_ptr)),
164 ))));
165 }
166 self.set_stop_ptr(stop_ptr);
167 Ok(stop_pointer_addr)
168 } else {
169 self.set_stop_ptr(0);
170 Ok(pointer)
171 }
172 }
173
174 pub fn get_allocated_memory_units(
176 &self,
177 vm: &VirtualMachine,
178 ) -> Result<usize, memory_errors::MemoryError> {
179 Ok(self.get_allocated_instances(vm)? * self.cells_per_instance() as usize)
180 }
181
182 pub fn get_allocated_instances(
184 &self,
185 vm: &VirtualMachine,
186 ) -> Result<usize, memory_errors::MemoryError> {
187 match *self {
188 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => Ok(0),
189 _ => {
190 match self.ratio() {
191 None => {
192 let instances: usize =
194 self.get_used_cells(&vm.segments)? / self.cells_per_instance() as usize;
195 let needed_components = instances / self.instances_per_component() as usize;
196
197 let components = if needed_components > 0 {
198 needed_components.next_power_of_two()
199 } else {
200 0
201 };
202 Ok(self.instances_per_component() as usize * components)
203 }
204 Some(0) => Ok(0),
206 Some(ratio) => {
207 let min_step_num = (ratio * self.instances_per_component()) as usize;
208 let min_step = if let Some(ratio_den) = self.ratio_den() {
209 div_ceil(min_step_num, ratio_den as usize)
210 } else {
211 min_step_num
212 };
213
214 if vm.current_step < min_step {
215 return Err(InsufficientAllocatedCellsError::MinStepNotReached(
216 Box::new((min_step, self.name())),
217 )
218 .into());
219 };
220
221 let allocated_instances = if let Some(ratio_den) = self.ratio_den() {
222 safe_div_usize(vm.current_step * ratio_den as usize, ratio as usize)
223 .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?
224 } else {
225 safe_div_usize(vm.current_step, ratio as usize)
226 .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?
227 };
228 Ok(allocated_instances)
229 }
230 }
231 }
232 }
233 }
234
235 fn included(&self) -> bool {
237 match *self {
238 BuiltinRunner::Bitwise(ref bitwise) => bitwise.included,
239 BuiltinRunner::EcOp(ref ec) => ec.included,
240 BuiltinRunner::Hash(ref hash) => hash.included,
241 BuiltinRunner::Output(ref output) => output.included,
242 BuiltinRunner::RangeCheck(ref range_check) => range_check.included,
243 BuiltinRunner::RangeCheck96(ref range_check) => range_check.included,
244 BuiltinRunner::Keccak(ref keccak) => keccak.included,
245 BuiltinRunner::Signature(ref signature) => signature.included,
246 BuiltinRunner::Poseidon(ref poseidon) => poseidon.included,
247 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.included,
248 BuiltinRunner::Mod(ref modulo) => modulo.included,
249 }
250 }
251
252 pub fn base(&self) -> usize {
254 match *self {
255 BuiltinRunner::Bitwise(ref bitwise) => bitwise.base(),
256 BuiltinRunner::EcOp(ref ec) => ec.base(),
257 BuiltinRunner::Hash(ref hash) => hash.base(),
258 BuiltinRunner::Output(ref output) => output.base(),
259 BuiltinRunner::RangeCheck(ref range_check) => range_check.base(),
260 BuiltinRunner::RangeCheck96(ref range_check) => range_check.base(),
261 BuiltinRunner::Keccak(ref keccak) => keccak.base(),
262 BuiltinRunner::Signature(ref signature) => signature.base(),
263 BuiltinRunner::Poseidon(ref poseidon) => poseidon.base(),
264 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.base(),
266 BuiltinRunner::Mod(ref modulo) => modulo.base(),
267 }
268 }
269
270 pub fn ratio(&self) -> Option<u32> {
271 match self {
272 BuiltinRunner::Bitwise(bitwise) => bitwise.ratio(),
273 BuiltinRunner::EcOp(ec) => ec.ratio(),
274 BuiltinRunner::Hash(hash) => hash.ratio(),
275 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => None,
276 BuiltinRunner::RangeCheck(range_check) => range_check.ratio(),
277 BuiltinRunner::RangeCheck96(range_check) => range_check.ratio(),
278 BuiltinRunner::Keccak(keccak) => keccak.ratio(),
279 BuiltinRunner::Signature(ref signature) => signature.ratio(),
280 BuiltinRunner::Poseidon(poseidon) => poseidon.ratio(),
281 BuiltinRunner::Mod(ref modulo) => modulo.ratio(),
282 }
283 }
284
285 pub fn ratio_den(&self) -> Option<u32> {
286 match self {
287 BuiltinRunner::RangeCheck(range_check) => range_check.ratio_den(),
288 BuiltinRunner::RangeCheck96(range_check) => range_check.ratio_den(),
289 BuiltinRunner::Mod(modulo) => modulo.ratio_den(),
290 _ => None,
291 }
292 }
293
294 pub fn add_validation_rule(&self, memory: &mut Memory) {
295 match *self {
296 BuiltinRunner::RangeCheck(ref range_check) => range_check.add_validation_rule(memory),
297 BuiltinRunner::RangeCheck96(ref range_check) => range_check.add_validation_rule(memory),
298 BuiltinRunner::Signature(ref signature) => signature.add_validation_rule(memory),
299 BuiltinRunner::Poseidon(ref poseidon) => poseidon.add_validation_rule(memory),
300 _ => {}
301 }
302 }
303
304 pub fn deduce_memory_cell(
305 &self,
306 address: Relocatable,
307 memory: &Memory,
308 ) -> Result<Option<MaybeRelocatable>, RunnerError> {
309 match *self {
310 BuiltinRunner::Bitwise(ref bitwise) => bitwise.deduce_memory_cell(address, memory),
311 BuiltinRunner::EcOp(ref ec) => ec.deduce_memory_cell(address, memory),
312 BuiltinRunner::Hash(ref hash) => hash.deduce_memory_cell(address, memory),
313 BuiltinRunner::Keccak(ref keccak) => keccak.deduce_memory_cell(address, memory),
314 BuiltinRunner::Poseidon(ref poseidon) => poseidon.deduce_memory_cell(address, memory),
315 _ => Ok(None),
316 }
317 }
318
319 pub fn get_memory_segment_addresses(&self) -> (usize, Option<usize>) {
320 (self.base(), self.stop_ptr())
321 }
322
323 pub fn get_used_cells(&self, segments: &MemorySegmentManager) -> Result<usize, MemoryError> {
324 match self {
325 BuiltinRunner::Bitwise(ref bitwise) => bitwise.get_used_cells(segments),
326 BuiltinRunner::EcOp(ref ec) => ec.get_used_cells(segments),
327 BuiltinRunner::Hash(ref hash) => hash.get_used_cells(segments),
328 BuiltinRunner::Output(ref output) => output.get_used_cells(segments),
329 BuiltinRunner::RangeCheck(ref range_check) => range_check.get_used_cells(segments),
330 BuiltinRunner::RangeCheck96(ref range_check) => range_check.get_used_cells(segments),
331 BuiltinRunner::Keccak(ref keccak) => keccak.get_used_cells(segments),
332 BuiltinRunner::Signature(ref signature) => signature.get_used_cells(segments),
333 BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_cells(segments),
334 BuiltinRunner::SegmentArena(ref segment_arena) => {
335 segment_arena.get_used_cells(segments)
336 }
337 BuiltinRunner::Mod(ref modulo) => modulo.get_used_cells(segments),
338 }
339 }
340
341 pub fn get_used_instances(
342 &self,
343 segments: &MemorySegmentManager,
344 ) -> Result<usize, MemoryError> {
345 match self {
346 BuiltinRunner::Bitwise(ref bitwise) => bitwise.get_used_instances(segments),
347 BuiltinRunner::EcOp(ref ec) => ec.get_used_instances(segments),
348 BuiltinRunner::Hash(ref hash) => hash.get_used_instances(segments),
349 BuiltinRunner::Output(ref output) => output.get_used_instances(segments),
350 BuiltinRunner::RangeCheck(ref range_check) => range_check.get_used_instances(segments),
351 BuiltinRunner::RangeCheck96(ref range_check) => {
352 range_check.get_used_instances(segments)
353 }
354 BuiltinRunner::Keccak(ref keccak) => keccak.get_used_instances(segments),
355 BuiltinRunner::Signature(ref signature) => signature.get_used_instances(segments),
356 BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_instances(segments),
357 BuiltinRunner::SegmentArena(ref segment_arena) => {
358 segment_arena.get_used_instances(segments)
359 }
360 BuiltinRunner::Mod(modulo) => modulo.get_used_instances(segments),
361 }
362 }
363
364 pub fn get_range_check_usage(&self, memory: &Memory) -> Option<(usize, usize)> {
365 match self {
366 BuiltinRunner::RangeCheck(ref range_check) => range_check.get_range_check_usage(memory),
367 BuiltinRunner::RangeCheck96(ref range_check) => {
368 range_check.get_range_check_usage(memory)
369 }
370 _ => None,
371 }
372 }
373
374 pub fn get_used_perm_range_check_units(
376 &self,
377 vm: &VirtualMachine,
378 ) -> Result<usize, MemoryError> {
379 match self {
380 BuiltinRunner::RangeCheck(range_check) => {
381 let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?;
382 Ok(used_cells * range_check.n_parts() as usize)
383 }
384 BuiltinRunner::RangeCheck96(range_check) => {
385 let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?;
386 Ok(used_cells * range_check.n_parts() as usize)
387 }
388 _ => Ok(0),
389 }
390 }
391
392 pub fn get_used_diluted_check_units(&self, diluted_spacing: u32, diluted_n_bits: u32) -> usize {
393 match self {
394 BuiltinRunner::Bitwise(ref bitwise) => {
395 bitwise.get_used_diluted_check_units(diluted_spacing, diluted_n_bits)
396 }
397 BuiltinRunner::Keccak(ref keccak) => {
398 keccak.get_used_diluted_check_units(diluted_n_bits)
399 }
400 _ => 0,
401 }
402 }
403
404 pub fn cells_per_instance(&self) -> u32 {
405 match self {
406 BuiltinRunner::Bitwise(_) => CELLS_PER_BITWISE,
407 BuiltinRunner::EcOp(_) => CELLS_PER_EC_OP,
408 BuiltinRunner::Hash(_) => CELLS_PER_HASH,
409 BuiltinRunner::RangeCheck(_) | BuiltinRunner::RangeCheck96(_) => CELLS_PER_RANGE_CHECK,
410 BuiltinRunner::Output(_) => 0,
411 BuiltinRunner::Keccak(_) => CELLS_PER_KECCAK,
412 BuiltinRunner::Signature(_) => CELLS_PER_SIGNATURE,
413 BuiltinRunner::Poseidon(_) => CELLS_PER_POSEIDON,
414 BuiltinRunner::SegmentArena(_) => ARENA_BUILTIN_SIZE,
415 BuiltinRunner::Mod(_) => CELLS_PER_MOD,
416 }
417 }
418
419 fn n_input_cells(&self) -> u32 {
420 match self {
421 BuiltinRunner::Bitwise(_) => INPUT_CELLS_PER_BITWISE,
422 BuiltinRunner::EcOp(_) => INPUT_CELLS_PER_EC_OP,
423 BuiltinRunner::Hash(_) => INPUT_CELLS_PER_HASH,
424 BuiltinRunner::RangeCheck(_) | BuiltinRunner::RangeCheck96(_) => CELLS_PER_RANGE_CHECK,
425 BuiltinRunner::Output(_) => 0,
426 BuiltinRunner::Keccak(_) => INPUT_CELLS_PER_KECCAK,
427 BuiltinRunner::Signature(_) => CELLS_PER_SIGNATURE,
428 BuiltinRunner::Poseidon(_) => INPUT_CELLS_PER_POSEIDON,
429 BuiltinRunner::SegmentArena(_) => ARENA_BUILTIN_SIZE,
430 BuiltinRunner::Mod(_) => CELLS_PER_MOD,
431 }
432 }
433
434 fn instances_per_component(&self) -> u32 {
435 match self {
436 BuiltinRunner::Keccak(_) => KECCAK_INSTANCES_PER_COMPONENT,
437 _ => BUILTIN_INSTANCES_PER_COMPONENT,
438 }
439 }
440
441 pub fn name(&self) -> BuiltinName {
442 match self {
443 BuiltinRunner::Bitwise(_) => BuiltinName::bitwise,
444 BuiltinRunner::EcOp(_) => BuiltinName::ec_op,
445 BuiltinRunner::Hash(_) => BuiltinName::pedersen,
446 BuiltinRunner::RangeCheck(_) => BuiltinName::range_check,
447 BuiltinRunner::RangeCheck96(_) => BuiltinName::range_check96,
448 BuiltinRunner::Output(_) => BuiltinName::output,
449 BuiltinRunner::Keccak(_) => BuiltinName::keccak,
450 BuiltinRunner::Signature(_) => BuiltinName::ecdsa,
451 BuiltinRunner::Poseidon(_) => BuiltinName::poseidon,
452 BuiltinRunner::SegmentArena(_) => BuiltinName::segment_arena,
453 BuiltinRunner::Mod(b) => b.name(),
454 }
455 }
456
457 pub fn run_security_checks(&self, vm: &VirtualMachine) -> Result<(), VirtualMachineError> {
458 if let BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) = self {
459 return Ok(());
460 }
461 if let BuiltinRunner::Mod(modulo) = self {
462 modulo.run_additional_security_checks(vm)?;
463 }
464 let cells_per_instance = self.cells_per_instance() as usize;
465 let n_input_cells = self.n_input_cells() as usize;
466 let builtin_segment_index = self.base();
467 let builtin_segment = match vm.segments.memory.data.get(builtin_segment_index) {
469 Some(segment) if !segment.is_empty() => segment,
470 _ => return Ok(()),
471 };
472 let offset_max = builtin_segment.len().saturating_sub(1);
477 let offset_len = builtin_segment.iter().filter(|x| x.is_some()).count();
479 let n = match offset_len {
480 0 => 0,
481 _ => div_floor(offset_max, cells_per_instance) + 1,
482 };
483 if n > div_floor(offset_len, n_input_cells) {
486 return Err(MemoryError::MissingMemoryCells(Box::new(self.name())).into());
487 }
488 let mut missing_offsets = Vec::with_capacity(n);
490 for i in 0..n {
492 for j in 0..n_input_cells {
493 let offset = cells_per_instance * i + j;
494 if builtin_segment
495 .get(offset)
496 .filter(|x| x.is_some())
497 .is_none()
498 {
499 missing_offsets.push(offset)
500 }
501 }
502 }
503 if !missing_offsets.is_empty() {
504 return Err(MemoryError::MissingMemoryCellsWithOffsets(Box::new((
505 self.name(),
506 missing_offsets,
507 )))
508 .into());
509 }
510 for i in 0..n {
513 for j in n_input_cells..cells_per_instance {
514 let offset = cells_per_instance * i + j;
515 if builtin_segment
516 .get(offset)
517 .filter(|x| x.is_some())
518 .is_none()
519 {
520 vm.verify_auto_deductions_for_addr(
521 Relocatable::from((builtin_segment_index as isize, offset)),
522 self,
523 )?;
524 }
525 }
526 }
527 Ok(())
528 }
529
530 pub fn get_used_cells_and_allocated_size(
531 &self,
532 vm: &VirtualMachine,
533 ) -> Result<(usize, usize), MemoryError> {
534 match self {
535 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => {
536 let used = self.get_used_cells(&vm.segments)?;
537 Ok((used, used))
538 }
539 _ => {
540 let used_cells = self.get_used_cells(&vm.segments)?;
541 if vm.disable_trace_padding {
542 let num_instances = self.get_used_instances(&vm.segments)?;
546 let padded_used_cells = if num_instances > 0 {
547 let padded_num_instances = core::cmp::max(
548 MIN_N_INSTANCES_IN_BUILTIN_SEGMENT,
549 num_instances.next_power_of_two(),
550 );
551 padded_num_instances * self.cells_per_instance() as usize
552 } else {
553 0
554 };
555 Ok((used_cells, padded_used_cells))
556 } else {
557 let size = self.get_allocated_memory_units(vm)?;
558 if used_cells > size {
559 return Err(InsufficientAllocatedCellsError::BuiltinCells(Box::new((
560 self.name(),
561 used_cells,
562 size,
563 )))
564 .into());
565 }
566 Ok((used_cells, size))
567 }
568 }
569 }
570 }
571
572 pub fn get_additional_data(&self) -> BuiltinAdditionalData {
574 match self {
575 BuiltinRunner::Hash(builtin) => builtin.get_additional_data(),
576 BuiltinRunner::Output(builtin) => builtin.get_additional_data(),
577 BuiltinRunner::Signature(builtin) => builtin.get_additional_data(),
578 _ => BuiltinAdditionalData::None,
579 }
580 }
581
582 pub fn extend_additional_data(
585 &mut self,
586 additional_data: &BuiltinAdditionalData,
587 ) -> Result<(), RunnerError> {
588 match self {
589 BuiltinRunner::Hash(builtin) => builtin.extend_additional_data(additional_data),
590 BuiltinRunner::Output(builtin) => builtin.extend_additional_data(additional_data),
591 BuiltinRunner::Signature(builtin) => builtin.extend_additional_data(additional_data),
592 _ => Ok(()),
593 }
594 }
595
596 pub fn air_private_input(&self, segments: &MemorySegmentManager) -> Vec<PrivateInput> {
598 match self {
599 BuiltinRunner::RangeCheck(builtin) => builtin.air_private_input(&segments.memory),
600 BuiltinRunner::RangeCheck96(builtin) => builtin.air_private_input(&segments.memory),
601 BuiltinRunner::Bitwise(builtin) => builtin.air_private_input(&segments.memory),
602 BuiltinRunner::Hash(builtin) => builtin.air_private_input(&segments.memory),
603 BuiltinRunner::EcOp(builtin) => builtin.air_private_input(&segments.memory),
604 BuiltinRunner::Poseidon(builtin) => builtin.air_private_input(&segments.memory),
605 BuiltinRunner::Signature(builtin) => builtin.air_private_input(&segments.memory),
606 BuiltinRunner::Keccak(builtin) => builtin.air_private_input(&segments.memory),
607 BuiltinRunner::Mod(builtin) => builtin.air_private_input(segments),
608 _ => vec![],
609 }
610 }
611
612 pub(crate) fn set_stop_ptr(&mut self, stop_ptr: usize) {
613 match self {
614 BuiltinRunner::Bitwise(ref mut bitwise) => bitwise.stop_ptr = Some(stop_ptr),
615 BuiltinRunner::EcOp(ref mut ec) => ec.stop_ptr = Some(stop_ptr),
616 BuiltinRunner::Hash(ref mut hash) => hash.stop_ptr = Some(stop_ptr),
617 BuiltinRunner::Output(ref mut output) => output.stop_ptr = Some(stop_ptr),
618 BuiltinRunner::RangeCheck(ref mut range_check) => range_check.stop_ptr = Some(stop_ptr),
619 BuiltinRunner::RangeCheck96(ref mut range_check) => {
620 range_check.stop_ptr = Some(stop_ptr)
621 }
622 BuiltinRunner::Keccak(ref mut keccak) => keccak.stop_ptr = Some(stop_ptr),
623 BuiltinRunner::Signature(ref mut signature) => signature.stop_ptr = Some(stop_ptr),
624 BuiltinRunner::Poseidon(ref mut poseidon) => poseidon.stop_ptr = Some(stop_ptr),
625 BuiltinRunner::SegmentArena(ref mut segment_arena) => {
626 segment_arena.stop_ptr = Some(stop_ptr)
627 }
628 BuiltinRunner::Mod(modulo) => modulo.stop_ptr = Some(stop_ptr),
629 }
630 }
631
632 pub(crate) fn stop_ptr(&self) -> Option<usize> {
633 match self {
634 BuiltinRunner::Bitwise(ref bitwise) => bitwise.stop_ptr,
635 BuiltinRunner::EcOp(ref ec) => ec.stop_ptr,
636 BuiltinRunner::Hash(ref hash) => hash.stop_ptr,
637 BuiltinRunner::Output(ref output) => output.stop_ptr,
638 BuiltinRunner::RangeCheck(ref range_check) => range_check.stop_ptr,
639 BuiltinRunner::RangeCheck96(ref range_check) => range_check.stop_ptr,
640 BuiltinRunner::Keccak(ref keccak) => keccak.stop_ptr,
641 BuiltinRunner::Signature(ref signature) => signature.stop_ptr,
642 BuiltinRunner::Poseidon(ref poseidon) => poseidon.stop_ptr,
643 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.stop_ptr,
644 BuiltinRunner::Mod(ref modulo) => modulo.stop_ptr,
645 }
646 }
647}
648
649impl From<KeccakBuiltinRunner> for BuiltinRunner {
650 fn from(runner: KeccakBuiltinRunner) -> Self {
651 BuiltinRunner::Keccak(runner)
652 }
653}
654
655impl From<BitwiseBuiltinRunner> for BuiltinRunner {
656 fn from(runner: BitwiseBuiltinRunner) -> Self {
657 BuiltinRunner::Bitwise(runner)
658 }
659}
660
661impl From<EcOpBuiltinRunner> for BuiltinRunner {
662 fn from(runner: EcOpBuiltinRunner) -> Self {
663 BuiltinRunner::EcOp(runner)
664 }
665}
666
667impl From<HashBuiltinRunner> for BuiltinRunner {
668 fn from(runner: HashBuiltinRunner) -> Self {
669 BuiltinRunner::Hash(runner)
670 }
671}
672
673impl From<OutputBuiltinRunner> for BuiltinRunner {
674 fn from(runner: OutputBuiltinRunner) -> Self {
675 BuiltinRunner::Output(runner)
676 }
677}
678
679impl From<RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>> for BuiltinRunner {
680 fn from(runner: RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>) -> Self {
681 BuiltinRunner::RangeCheck(runner)
682 }
683}
684
685impl From<RangeCheckBuiltinRunner<RC_N_PARTS_96>> for BuiltinRunner {
686 fn from(runner: RangeCheckBuiltinRunner<RC_N_PARTS_96>) -> Self {
687 BuiltinRunner::RangeCheck96(runner)
688 }
689}
690
691impl From<SignatureBuiltinRunner> for BuiltinRunner {
692 fn from(runner: SignatureBuiltinRunner) -> Self {
693 BuiltinRunner::Signature(runner)
694 }
695}
696
697impl From<PoseidonBuiltinRunner> for BuiltinRunner {
698 fn from(runner: PoseidonBuiltinRunner) -> Self {
699 BuiltinRunner::Poseidon(runner)
700 }
701}
702
703impl From<SegmentArenaBuiltinRunner> for BuiltinRunner {
704 fn from(runner: SegmentArenaBuiltinRunner) -> Self {
705 BuiltinRunner::SegmentArena(runner)
706 }
707}
708
709impl From<ModBuiltinRunner> for BuiltinRunner {
710 fn from(runner: ModBuiltinRunner) -> Self {
711 BuiltinRunner::Mod(runner)
712 }
713}
714
715#[cfg(test)]
716mod tests {
717 use super::*;
718 use crate::cairo_run::{cairo_run, CairoRunConfig};
719 use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
720 use crate::relocatable;
721 use crate::types::builtin_name::BuiltinName;
722 use crate::types::instance_definitions::mod_instance_def::ModInstanceDef;
723 use crate::types::instance_definitions::LowRatio;
724 use crate::types::layout_name::LayoutName;
725 use crate::types::program::Program;
726 use crate::utils::test_utils::*;
727 use crate::vm::errors::memory_errors::InsufficientAllocatedCellsError;
728 use crate::vm::vm_memory::memory::MemoryCell;
729 use assert_matches::assert_matches;
730
731 #[cfg(target_arch = "wasm32")]
732 use wasm_bindgen_test::*;
733
734 #[test]
735 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
736 fn get_n_input_cells_bitwise() {
737 let bitwise = BitwiseBuiltinRunner::new(Some(10), true);
738 let builtin: BuiltinRunner = bitwise.clone().into();
739 assert_eq!(INPUT_CELLS_PER_BITWISE, builtin.n_input_cells())
740 }
741
742 #[test]
743 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
744 fn get_n_input_cells_hash() {
745 let hash = HashBuiltinRunner::new(Some(10), true);
746 let builtin: BuiltinRunner = hash.clone().into();
747 assert_eq!(INPUT_CELLS_PER_HASH, builtin.n_input_cells())
748 }
749
750 #[test]
751 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
752 fn get_n_input_cells_ec_op() {
753 let ec_op = EcOpBuiltinRunner::new(Some(256), true);
754 let builtin: BuiltinRunner = ec_op.clone().into();
755 assert_eq!(INPUT_CELLS_PER_EC_OP, builtin.n_input_cells())
756 }
757
758 #[test]
759 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
760 fn get_n_input_cells_ecdsa() {
761 let signature = SignatureBuiltinRunner::new(Some(10), true);
762 let builtin: BuiltinRunner = signature.clone().into();
763 assert_eq!(CELLS_PER_SIGNATURE, builtin.n_input_cells())
764 }
765
766 #[test]
767 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
768 fn get_n_input_cells_output() {
769 let output = OutputBuiltinRunner::new(true);
770 let builtin: BuiltinRunner = output.into();
771 assert_eq!(0, builtin.n_input_cells())
772 }
773
774 #[test]
775 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
776 fn get_cells_per_instance_bitwise() {
777 let bitwise = BitwiseBuiltinRunner::new(Some(10), true);
778 let builtin: BuiltinRunner = bitwise.clone().into();
779 assert_eq!(CELLS_PER_BITWISE, builtin.cells_per_instance())
780 }
781
782 #[test]
783 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
784 fn get_cells_per_instance_hash() {
785 let hash = HashBuiltinRunner::new(Some(10), true);
786 let builtin: BuiltinRunner = hash.clone().into();
787 assert_eq!(CELLS_PER_HASH, builtin.cells_per_instance())
788 }
789
790 #[test]
791 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
792 fn get_cells_per_instance_ec_op() {
793 let ec_op = EcOpBuiltinRunner::new(Some(256), true);
794 let builtin: BuiltinRunner = ec_op.clone().into();
795 assert_eq!(CELLS_PER_EC_OP, builtin.cells_per_instance())
796 }
797
798 #[test]
799 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
800 fn get_cells_per_instance_ecdsa() {
801 let signature = SignatureBuiltinRunner::new(Some(10), true);
802 let builtin: BuiltinRunner = signature.clone().into();
803 assert_eq!(CELLS_PER_SIGNATURE, builtin.cells_per_instance())
804 }
805
806 #[test]
807 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
808 fn get_cells_per_instance_output() {
809 let output = OutputBuiltinRunner::new(true);
810 let builtin: BuiltinRunner = output.into();
811 assert_eq!(0, builtin.cells_per_instance())
812 }
813
814 #[test]
815 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
816 fn get_name_bitwise() {
817 let bitwise = BitwiseBuiltinRunner::new(Some(10), true);
818 let builtin: BuiltinRunner = bitwise.into();
819 assert_eq!(BuiltinName::bitwise, builtin.name())
820 }
821
822 #[test]
823 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
824 fn get_name_hash() {
825 let hash = HashBuiltinRunner::new(Some(10), true);
826 let builtin: BuiltinRunner = hash.into();
827 assert_eq!(BuiltinName::pedersen, builtin.name())
828 }
829
830 #[test]
831 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
832 fn get_name_range_check() {
833 let range_check = RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(10), true);
834 let builtin: BuiltinRunner = range_check.into();
835 assert_eq!(BuiltinName::range_check, builtin.name())
836 }
837
838 #[test]
839 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
840 fn get_name_ec_op() {
841 let ec_op = EcOpBuiltinRunner::new(Some(256), true);
842 let builtin: BuiltinRunner = ec_op.into();
843 assert_eq!(BuiltinName::ec_op, builtin.name())
844 }
845
846 #[test]
847 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
848 fn get_name_ecdsa() {
849 let signature = SignatureBuiltinRunner::new(Some(10), true);
850 let builtin: BuiltinRunner = signature.into();
851 assert_eq!(BuiltinName::ecdsa, builtin.name())
852 }
853
854 #[test]
855 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
856 fn get_name_output() {
857 let output = OutputBuiltinRunner::new(true);
858 let builtin: BuiltinRunner = output.into();
859 assert_eq!(BuiltinName::output, builtin.name())
860 }
861
862 #[test]
863 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
864 fn get_allocated_memory_units_bitwise_with_items() {
865 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(10), true));
866
867 let program = program!(
868 builtins = vec![BuiltinName::bitwise],
869 data = vec_data!(
870 (4612671182993129469_i64),
871 (5189976364521848832_i64),
872 (18446744073709551615_i128),
873 (5199546496550207487_i64),
874 (4612389712311386111_i64),
875 (5198983563776393216_i64),
876 (2),
877 (2345108766317314046_i64),
878 (5191102247248822272_i64),
879 (5189976364521848832_i64),
880 (7),
881 (1226245742482522112_i64),
882 ((
883 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
884 10
885 )),
886 (2345108766317314046_i64)
887 ),
888 main = Some(8),
889 );
890
891 let mut cairo_runner = cairo_runner!(program);
892
893 let mut hint_processor = BuiltinHintProcessor::new_empty();
894
895 let address = cairo_runner.initialize(false).unwrap();
896
897 cairo_runner
898 .run_until_pc(address, &mut hint_processor)
899 .unwrap();
900
901 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(5));
902 }
903
904 #[test]
905 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
906 fn compare_proof_mode_with_and_without_disable_trace_padding() {
907 const PEDERSEN_TEST: &[u8] =
908 include_bytes!("../../../../../cairo_programs/proof_programs/pedersen_test.json");
909 const BIGINT_TEST: &[u8] =
910 include_bytes!("../../../../../cairo_programs/proof_programs/bigint.json");
911 const POSEIDON_HASH_TEST: &[u8] =
912 include_bytes!("../../../../../cairo_programs/proof_programs/poseidon_hash.json");
913
914 let program_files = vec![PEDERSEN_TEST, BIGINT_TEST, POSEIDON_HASH_TEST];
915
916 for program_data in program_files {
917 let config_false = CairoRunConfig {
918 disable_trace_padding: false,
919 proof_mode: true,
920 fill_holes: true,
921 layout: LayoutName::all_cairo,
922 ..Default::default()
923 };
924 let mut hint_processor_false = BuiltinHintProcessor::new_empty();
925 let runner_false =
926 cairo_run(program_data, &config_false, &mut hint_processor_false).unwrap();
927 let last_step_false = runner_false.vm.current_step;
928
929 assert!(last_step_false.is_power_of_two());
930
931 let config_true = CairoRunConfig {
932 disable_trace_padding: true,
933 proof_mode: true,
934 fill_holes: true,
935 layout: LayoutName::all_cairo,
936 ..Default::default()
937 };
938 let mut hint_processor_true = BuiltinHintProcessor::new_empty();
939 let runner_true =
940 cairo_run(program_data, &config_true, &mut hint_processor_true).unwrap();
941 let last_step_true = runner_true.vm.current_step;
942
943 assert!(!last_step_true.is_power_of_two());
945
946 assert!(last_step_true < last_step_false);
947
948 let builtin_runners_false = &runner_false.vm.builtin_runners;
949 let builtin_runners_true = &runner_true.vm.builtin_runners;
950 assert_eq!(builtin_runners_false.len(), builtin_runners_true.len());
951 for (builtin_runner_false, builtin_runner_true) in builtin_runners_false
953 .iter()
954 .zip(builtin_runners_true.iter())
955 {
956 assert_eq!(builtin_runner_false.name(), builtin_runner_true.name());
957 match builtin_runner_false {
958 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => {
959 continue;
960 }
961 _ => {}
962 }
963 let (_, allocated_size_false) = builtin_runner_false
964 .get_used_cells_and_allocated_size(&runner_false.vm)
965 .unwrap();
966 let (used_cells_true, allocated_size_true) = builtin_runner_true
967 .get_used_cells_and_allocated_size(&runner_true.vm)
968 .unwrap();
969 let n_allocated_instances_false = safe_div_usize(
970 allocated_size_false,
971 builtin_runner_false.cells_per_instance() as usize,
972 )
973 .unwrap();
974 let n_allocated_instances_true = safe_div_usize(
975 allocated_size_true,
976 builtin_runner_true.cells_per_instance() as usize,
977 )
978 .unwrap();
979 assert!(
980 n_allocated_instances_false.is_power_of_two()
981 || n_allocated_instances_false == 0
982 );
983 assert!(
984 n_allocated_instances_true.is_power_of_two() || n_allocated_instances_true == 0
985 );
986 assert!(
991 n_allocated_instances_true >= MIN_N_INSTANCES_IN_BUILTIN_SEGMENT
992 || n_allocated_instances_true == 0
993 );
994
995 assert!(
999 n_allocated_instances_true == 0
1000 || n_allocated_instances_true != n_allocated_instances_false
1001 );
1002
1003 let n_output_cells = builtin_runner_true.cells_per_instance() as usize
1008 - builtin_runner_true.n_input_cells() as usize;
1009 assert!(
1010 used_cells_true + n_output_cells
1011 >= (builtin_runner_true.cells_per_instance() as usize)
1012 * builtin_runner_true
1013 .get_used_instances(&runner_true.vm.segments)
1014 .unwrap()
1015 );
1016 }
1017 }
1018 }
1019
1020 #[test]
1021 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1022 fn get_allocated_memory_units_ec_op_with_items() {
1023 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(10), true));
1024
1025 let program = program!(
1026 builtins = vec![BuiltinName::ec_op],
1027 data = vec_data!(
1028 (4612671182993129469_i64),
1029 (5189976364521848832_i64),
1030 (18446744073709551615_i128),
1031 (5199546496550207487_i64),
1032 (4612389712311386111_i64),
1033 (5198983563776393216_i64),
1034 (2),
1035 (2345108766317314046_i64),
1036 (5191102247248822272_i64),
1037 (5189976364521848832_i64),
1038 (7),
1039 (1226245742482522112_i64),
1040 ((
1041 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
1042 10
1043 )),
1044 (2345108766317314046_i64)
1045 ),
1046 main = Some(8),
1047 );
1048
1049 let mut cairo_runner = cairo_runner!(program);
1050
1051 let mut hint_processor = BuiltinHintProcessor::new_empty();
1052
1053 let address = cairo_runner.initialize(false).unwrap();
1054
1055 cairo_runner
1056 .run_until_pc(address, &mut hint_processor)
1057 .unwrap();
1058
1059 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(7));
1060 }
1061
1062 #[test]
1063 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1064 fn get_allocated_memory_units_hash_with_items() {
1065 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(10), true));
1066
1067 let program = program!(
1068 builtins = vec![BuiltinName::pedersen],
1069 data = vec_data!(
1070 (4612671182993129469_i64),
1071 (5189976364521848832_i64),
1072 (18446744073709551615_i128),
1073 (5199546496550207487_i64),
1074 (4612389712311386111_i64),
1075 (5198983563776393216_i64),
1076 (2),
1077 (2345108766317314046_i64),
1078 (5191102247248822272_i64),
1079 (5189976364521848832_i64),
1080 (7),
1081 (1226245742482522112_i64),
1082 ((
1083 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
1084 10
1085 )),
1086 (2345108766317314046_i64)
1087 ),
1088 main = Some(8),
1089 );
1090
1091 let mut cairo_runner = cairo_runner!(program);
1092
1093 let mut hint_processor = BuiltinHintProcessor::new_empty();
1094
1095 let address = cairo_runner.initialize(false).unwrap();
1096
1097 cairo_runner
1098 .run_until_pc(address, &mut hint_processor)
1099 .unwrap();
1100
1101 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(3));
1102 }
1103
1104 #[test]
1105 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1106 fn get_allocated_memory_units_range_check_with_items() {
1107 let builtin = BuiltinRunner::RangeCheck(
1108 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(10), true),
1109 );
1110
1111 let program = program!(
1112 builtins = vec![BuiltinName::range_check],
1113 data = vec_data!(
1114 (4612671182993129469_i64),
1115 (5189976364521848832_i64),
1116 (18446744073709551615_i128),
1117 (5199546496550207487_i64),
1118 (4612389712311386111_i64),
1119 (5198983563776393216_i64),
1120 (2),
1121 (2345108766317314046_i64),
1122 (5191102247248822272_i64),
1123 (5189976364521848832_i64),
1124 (7),
1125 (1226245742482522112_i64),
1126 ((
1127 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
1128 10
1129 )),
1130 (2345108766317314046_i64)
1131 ),
1132 main = Some(8),
1133 );
1134
1135 let mut cairo_runner = cairo_runner!(program);
1136
1137 let mut hint_processor = BuiltinHintProcessor::new_empty();
1138
1139 let address = cairo_runner.initialize(false).unwrap();
1140
1141 cairo_runner
1142 .run_until_pc(address, &mut hint_processor)
1143 .unwrap();
1144
1145 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(1));
1146 }
1147
1148 #[test]
1149 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1150 fn get_allocated_memory_units_keccak_with_items() {
1151 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(10), true));
1152
1153 let mut vm = vm!();
1154 vm.current_step = 160;
1155 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256));
1156 }
1157
1158 #[test]
1159 fn get_allocated_memory_units_keccak_min_steps_not_reached() {
1160 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(10), true));
1161
1162 let mut vm = vm!();
1163 vm.current_step = 10;
1164 assert_eq!(
1165 builtin.get_allocated_memory_units(&vm),
1166 Err(MemoryError::InsufficientAllocatedCells(
1167 InsufficientAllocatedCellsError::MinStepNotReached(Box::new((
1168 160,
1169 BuiltinName::keccak
1170 )))
1171 ))
1172 );
1173 }
1174
1175 #[test]
1176 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1177 fn get_allocated_memory_units_output() {
1178 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1179 let vm = vm!();
1180
1181 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0));
1183 }
1184
1185 #[test]
1186 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1187 fn get_allocated_memory_units_range_check() {
1188 let builtin = BuiltinRunner::RangeCheck(
1189 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1190 );
1191 let mut vm = vm!();
1192 vm.current_step = 8;
1193 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(1));
1194 }
1195
1196 #[test]
1197 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1198 fn get_allocated_memory_units_hash() {
1199 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), true));
1200 let mut vm = vm!();
1201 vm.current_step = 1;
1202 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(3));
1203 }
1204
1205 #[test]
1206 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1207 fn get_allocated_memory_units_bitwise() {
1208 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1209 let mut vm = vm!();
1210 vm.current_step = 256;
1211 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(5));
1212 }
1213
1214 #[test]
1215 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1216 fn get_allocated_memory_units_ec_op() {
1217 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), true));
1218 let mut vm = vm!();
1219 vm.current_step = 256;
1220 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(7));
1221 }
1222
1223 #[test]
1224 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1225 fn get_allocated_memory_units_keccak() {
1226 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), true));
1227 let mut vm = vm!();
1228 vm.current_step = 32768;
1229 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256));
1230 }
1231
1232 #[test]
1233 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1234 fn get_allocated_memory_units_zero_ratio() {
1235 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(0), true));
1236 let vm = vm!();
1237 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0));
1238 }
1239
1240 #[test]
1241 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1242 fn get_allocated_memory_units_none_ratio() {
1243 let mut builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(None, true));
1244 let mut vm = vm!();
1245
1246 builtin.initialize_segments(&mut vm.segments);
1247 vm.compute_segments_effective_sizes();
1248
1249 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0));
1250 }
1251
1252 #[test]
1253 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1254 fn get_range_check_usage_range_check() {
1255 let builtin = BuiltinRunner::RangeCheck(
1256 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1257 );
1258 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1259 assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4)));
1260 }
1261
1262 #[test]
1263 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1264 fn get_range_check_usage_output() {
1265 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1266 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1267 assert_eq!(builtin.get_range_check_usage(&memory), None);
1268 }
1269
1270 #[test]
1271 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1272 fn get_range_check_usage_hash() {
1273 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true));
1274 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1275 assert_eq!(builtin.get_range_check_usage(&memory), None);
1276 }
1277
1278 #[test]
1279 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1280 fn get_range_check_usage_ec_op() {
1281 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), true));
1282 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1283 assert_eq!(builtin.get_range_check_usage(&memory), None);
1284 }
1285
1286 #[test]
1287 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1288 fn get_range_check_usage_bitwise() {
1289 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1290 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1291 assert_eq!(builtin.get_range_check_usage(&memory), None);
1292 }
1293
1294 #[test]
1295 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1296 fn get_used_diluted_check_units_bitwise() {
1297 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1298 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 1255);
1299 }
1300
1301 #[test]
1302 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1303 fn get_used_diluted_check_units_keccak_zero_case() {
1304 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), true));
1305 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1306 }
1307
1308 #[test]
1309 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1310 fn get_used_diluted_check_units_keccak_non_zero_case() {
1311 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), true));
1312 assert_eq!(builtin.get_used_diluted_check_units(0, 8), 32768);
1313 }
1314
1315 #[test]
1316 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1317 fn get_used_diluted_check_units_ec_op() {
1318 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(10), true));
1319 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1320 }
1321
1322 #[test]
1323 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1324 fn get_used_diluted_check_units_hash() {
1325 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), true));
1326 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1327 }
1328
1329 #[test]
1330 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1331 fn get_used_diluted_check_units_range_check() {
1332 let builtin = BuiltinRunner::RangeCheck(
1333 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1334 );
1335 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1336 }
1337
1338 #[test]
1339 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1340 fn get_used_diluted_check_units_output() {
1341 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1342 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1343 }
1344
1345 #[test]
1346 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1347 fn get_memory_segment_addresses_test() {
1348 let bitwise_builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1349 assert_eq!(bitwise_builtin.get_memory_segment_addresses(), (0, None),);
1350 let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1351 assert_eq!(ec_op_builtin.get_memory_segment_addresses(), (0, None),);
1352 let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1353 assert_eq!(hash_builtin.get_memory_segment_addresses(), (0, None),);
1354 let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1355 assert_eq!(output_builtin.get_memory_segment_addresses(), (0, None),);
1356 let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck(
1357 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1358 );
1359 assert_eq!(
1360 range_check_builtin.get_memory_segment_addresses(),
1361 (0, None),
1362 );
1363 }
1364
1365 #[test]
1366 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1367 fn run_security_checks_for_output() {
1368 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1369 let vm = vm!();
1370
1371 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1372 }
1373
1374 #[test]
1375 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1376 fn run_security_checks_empty_memory() {
1377 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1378 let vm = vm!();
1379 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1381 }
1382
1383 #[test]
1384 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1385 fn run_security_checks_empty_offsets() {
1386 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1387 let mut vm = vm!();
1388
1389 vm.segments.memory.data = vec![vec![]];
1390
1391 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1392 }
1393
1394 #[test]
1395 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1396 fn run_security_checks_bitwise_missing_memory_cells_with_offsets() {
1397 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1398 let mut vm = vm!();
1399 vm.segments.memory = memory![
1400 ((0, 1), (0, 1)),
1401 ((0, 2), (0, 2)),
1402 ((0, 3), (0, 3)),
1403 ((0, 4), (0, 4))
1404 ];
1405
1406 assert_matches!(
1407 builtin.run_security_checks(&vm),
1408 Err(VirtualMachineError::Memory(
1409 MemoryError::MissingMemoryCellsWithOffsets(bx)
1410 )) if *bx == (BuiltinName::bitwise, vec![0])
1411 );
1412 }
1413
1414 #[test]
1415 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1416 fn run_security_checks_bitwise_missing_memory_cells() {
1417 let bitwise_builtin = BitwiseBuiltinRunner::new(Some(256), true);
1418
1419 let builtin: BuiltinRunner = bitwise_builtin.into();
1420
1421 let mut vm = vm!();
1422
1423 vm.segments.memory = memory![((0, 4), (0, 5))];
1424
1425 assert_matches!(
1426 builtin.run_security_checks(&vm),
1427 Err(VirtualMachineError::Memory(
1428 MemoryError::MissingMemoryCells(bx)
1429 )) if *bx == BuiltinName::bitwise
1430 );
1431 }
1432
1433 #[test]
1434 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1435 fn run_security_checks_hash_missing_memory_cells_with_offsets() {
1436 let builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1437 let mut vm = vm!();
1438
1439 vm.segments.memory = memory![
1440 ((0, 1), (0, 1)),
1441 ((0, 2), (0, 2)),
1442 ((0, 3), (0, 3)),
1443 ((0, 4), (0, 4)),
1444 ((0, 5), (0, 5))
1445 ];
1446 assert_matches!(
1447 builtin.run_security_checks(&vm),
1448 Err(VirtualMachineError::Memory(
1449 MemoryError::MissingMemoryCellsWithOffsets(bx)
1450 )) if *bx == (BuiltinName::pedersen, vec![0])
1451 );
1452 }
1453
1454 #[test]
1455 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1456 fn run_security_checks_hash_missing_memory_cells() {
1457 let hash_builtin = HashBuiltinRunner::new(Some(8), true);
1458
1459 let builtin: BuiltinRunner = hash_builtin.into();
1460
1461 let mut vm = vm!();
1462
1463 vm.segments.memory = memory![((0, 0), (0, 0))];
1464
1465 assert_matches!(
1466 builtin.run_security_checks(&vm),
1467 Err(VirtualMachineError::Memory(
1468 MemoryError::MissingMemoryCells(bx)
1469 )) if *bx == BuiltinName::pedersen
1470 );
1471 }
1472
1473 #[test]
1474 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1475 fn run_security_checks_range_check_missing_memory_cells_with_offsets() {
1476 let range_check_builtin =
1477 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true);
1478 let builtin: BuiltinRunner = range_check_builtin.into();
1479 let mut vm = vm!();
1480
1481 vm.segments.memory = memory![
1482 ((0, 1), 100),
1483 ((0, 2), 2),
1484 ((0, 3), 3),
1485 ((0, 5), 5),
1486 ((0, 6), 17),
1487 ((0, 7), 22)
1488 ];
1489
1490 assert_matches!(
1491 builtin.run_security_checks(&vm),
1492 Err(VirtualMachineError::Memory(
1493 MemoryError::MissingMemoryCells(bx)
1494 )) if *bx == BuiltinName::range_check
1495 );
1496 }
1497
1498 #[test]
1499 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1500 fn run_security_checks_range_check_missing_memory_cells() {
1501 let builtin: BuiltinRunner = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::<
1502 RC_N_PARTS_STANDARD,
1503 >::new(Some(8), true));
1504 let mut vm = vm!();
1505
1506 vm.segments.memory = memory![((0, 1), 1)];
1507
1508 assert_matches!(
1509 builtin.run_security_checks(&vm),
1510 Err(VirtualMachineError::Memory(
1511 MemoryError::MissingMemoryCells(bx)
1512 )) if *bx == BuiltinName::range_check
1513 );
1514 }
1515
1516 #[test]
1517 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1518 fn run_security_checks_range_check_empty() {
1519 let range_check_builtin =
1520 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true);
1521
1522 let builtin: BuiltinRunner = range_check_builtin.into();
1523
1524 let mut vm = vm!();
1525
1526 vm.segments.memory.data = vec![vec![MemoryCell::NONE, MemoryCell::NONE, MemoryCell::NONE]];
1527
1528 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1529 }
1530
1531 #[test]
1532 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1533 fn run_security_checks_validate_auto_deductions() {
1534 let builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1535
1536 let mut vm = vm!();
1537 vm.segments
1538 .memory
1539 .validated_addresses
1540 .extend(&[relocatable!(0, 2)]);
1541
1542 vm.segments.memory = memory![
1543 ((0, 0), (0, 0)),
1544 ((0, 1), (0, 1)),
1545 ((0, 2), (0, 2)),
1546 ((0, 3), (0, 3)),
1547 ((0, 4), (0, 4))
1548 ];
1549
1550 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1551 }
1552
1553 #[test]
1554 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1555 fn run_security_ec_op_check_memory_empty() {
1556 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1557
1558 let builtin: BuiltinRunner = ec_op_builtin.into();
1559
1560 let mut vm = vm!();
1561 vm.segments.memory.data = vec![vec![]];
1563
1564 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1565 }
1566
1567 #[test]
1568 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1569 fn run_security_ec_op_check_memory_1_element() {
1570 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1571
1572 let builtin: BuiltinRunner = ec_op_builtin.into();
1573
1574 let mut vm = vm!();
1575 vm.segments.memory = memory![((0, 0), 0)];
1577 assert_matches!(
1578 builtin.run_security_checks(&vm),
1579 Err(VirtualMachineError::Memory(
1580 MemoryError::MissingMemoryCells(bx)
1581 )) if *bx == BuiltinName::ec_op
1582 );
1583 }
1584
1585 #[test]
1586 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1587 fn run_security_ec_op_check_memory_3_elements() {
1588 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1589
1590 let builtin: BuiltinRunner = ec_op_builtin.into();
1591
1592 let mut vm = vm!();
1593 vm.segments.memory = memory![((0, 0), 0), ((0, 1), 0), ((0, 2), 0)];
1595
1596 assert_matches!(
1597 builtin.run_security_checks(&vm),
1598 Err(VirtualMachineError::Memory(
1599 MemoryError::MissingMemoryCells(bx)
1600 )) if *bx == BuiltinName::ec_op
1601 );
1602 }
1603
1604 #[test]
1605 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1606 fn run_security_ec_op_missing_memory_cells_with_offsets() {
1607 let builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1608 let mut vm = vm!();
1609 vm.segments.memory = memory![
1610 ((0, 1), (0, 1)),
1611 ((0, 2), (0, 2)),
1612 ((0, 3), (0, 3)),
1613 ((0, 4), (0, 4)),
1614 ((0, 5), (0, 5)),
1615 ((0, 6), (0, 6))
1616 ];
1617
1618 assert_matches!(
1619 builtin.run_security_checks(&vm),
1620 Err(VirtualMachineError::Memory(
1621 MemoryError::MissingMemoryCellsWithOffsets(bx)
1622 )) if *bx == (BuiltinName::ec_op, vec![0])
1623 );
1624 }
1625
1626 #[test]
1627 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1628 fn run_security_ec_op_check_memory_gap() {
1629 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1630
1631 let builtin: BuiltinRunner = ec_op_builtin.into();
1632
1633 let mut vm = vm!();
1634 vm.segments.memory = memory![
1636 ((0, 0), 0),
1637 ((0, 1), 1),
1638 ((0, 2), 2),
1639 ((0, 3), 3),
1640 ((0, 4), 4),
1641 ((0, 5), 5),
1642 ((0, 6), 6),
1643 ((0, 8), 8),
1644 ((0, 9), 9),
1645 ((0, 10), 10),
1646 ((0, 11), 11)
1647 ];
1648
1649 assert_matches!(
1650 builtin.run_security_checks(&vm),
1651 Err(VirtualMachineError::Memory(
1652 MemoryError::MissingMemoryCellsWithOffsets(bx)
1653 )) if *bx == (BuiltinName::ec_op, vec![7])
1654 );
1655 }
1656
1657 #[test]
1660 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1661 fn get_used_perm_range_check_units_bitwise() {
1662 let builtin_runner: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1663 let mut vm = vm!();
1664
1665 vm.current_step = 8;
1666 vm.segments.segment_used_sizes = Some(vec![5]);
1667 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1668 }
1669
1670 #[test]
1673 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1674 fn get_used_perm_range_check_units_ec_op() {
1675 let builtin_runner: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1676 let mut vm = vm!();
1677
1678 vm.current_step = 8;
1679 vm.segments.segment_used_sizes = Some(vec![5]);
1680 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1681 }
1682
1683 #[test]
1686 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1687 fn get_used_perm_range_check_units_hash() {
1688 let builtin_runner: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1689 let mut vm = vm!();
1690
1691 vm.current_step = 8;
1692 vm.segments.segment_used_sizes = Some(vec![5]);
1693 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1694 }
1695
1696 #[test]
1699 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1700 fn get_used_perm_range_check_units_output() {
1701 let builtin_runner: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1702 let mut vm = vm!();
1703
1704 vm.current_step = 8;
1705 vm.segments.segment_used_sizes = Some(vec![5]);
1706 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1707 }
1708
1709 #[test]
1712 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1713 fn get_used_perm_range_check_units_range_check() {
1714 let builtin_runner: BuiltinRunner =
1715 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true).into();
1716 let mut vm = vm!();
1717
1718 vm.current_step = 8;
1719 vm.segments.segment_used_sizes = Some(vec![1]);
1720 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(8));
1721 }
1722
1723 #[test]
1724 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1725 fn get_ratio_tests() {
1726 let bitwise_builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1727 assert_eq!(bitwise_builtin.ratio(), (Some(256)),);
1728 let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1729 assert_eq!(ec_op_builtin.ratio(), (Some(256)),);
1730 let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1731 assert_eq!(hash_builtin.ratio(), (Some(8)),);
1732 let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1733 assert_eq!(output_builtin.ratio(), None,);
1734 let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck(
1735 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1736 );
1737 assert_eq!(range_check_builtin.ratio(), (Some(8)),);
1738 let keccak_builtin: BuiltinRunner = KeccakBuiltinRunner::new(Some(2048), true).into();
1739 assert_eq!(keccak_builtin.ratio(), (Some(2048)),);
1740 }
1741
1742 #[test]
1743 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1744 fn get_ratio_den_tests() {
1745 let rangecheck_builtin: BuiltinRunner =
1746 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new_with_low_ratio(
1747 Some(LowRatio::new(1, 2)),
1748 true,
1749 )
1750 .into();
1751 assert_eq!(rangecheck_builtin.ratio_den(), (Some(2)),);
1752
1753 let rangecheck96_builtin: BuiltinRunner =
1754 RangeCheckBuiltinRunner::<RC_N_PARTS_96>::new_with_low_ratio(
1755 Some(LowRatio::new(1, 4)),
1756 true,
1757 )
1758 .into();
1759 assert_eq!(rangecheck96_builtin.ratio_den(), (Some(4)),);
1760
1761 let mod_builtin: BuiltinRunner =
1762 ModBuiltinRunner::new_add_mod(&ModInstanceDef::new(Some(5), 3, 3), true).into();
1763 assert_eq!(mod_builtin.ratio_den(), (Some(1)),);
1764 }
1765
1766 #[test]
1767 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1768 fn bitwise_get_used_instances_test() {
1769 let mut vm = vm!();
1770 vm.segments.segment_used_sizes = Some(vec![4]);
1771
1772 let bitwise_builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1773 assert_eq!(bitwise_builtin.get_used_instances(&vm.segments), Ok(1));
1774 }
1775
1776 #[test]
1777 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1778 fn ec_op_get_used_instances_test() {
1779 let mut vm = vm!();
1780 vm.segments.segment_used_sizes = Some(vec![4]);
1781
1782 let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1783 assert_eq!(ec_op_builtin.get_used_instances(&vm.segments), Ok(1));
1784 }
1785
1786 #[test]
1787 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1788 fn hash_get_used_instances_test() {
1789 let mut vm = vm!();
1790 vm.segments.segment_used_sizes = Some(vec![4]);
1791
1792 let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1793 assert_eq!(hash_builtin.get_used_instances(&vm.segments), Ok(2));
1794 }
1795
1796 #[test]
1797 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1798 fn output_get_used_instances_test() {
1799 let mut vm = vm!();
1800 vm.segments.segment_used_sizes = Some(vec![4]);
1801
1802 let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1803 assert_eq!(output_builtin.get_used_instances(&vm.segments), Ok(4));
1804 }
1805 #[test]
1806 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1807 fn range_check_get_used_instances_test() {
1808 let mut vm = vm!();
1809 vm.segments.segment_used_sizes = Some(vec![4]);
1810
1811 let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck(
1812 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1813 );
1814 assert_eq!(range_check_builtin.get_used_instances(&vm.segments), Ok(4));
1815 }
1816
1817 #[test]
1818 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1819 fn runners_final_stack() {
1820 let mut builtins = vec![
1821 BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), false)),
1822 BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), false)),
1823 BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)),
1824 BuiltinRunner::Output(OutputBuiltinRunner::new(false)),
1825 BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(
1826 Some(8),
1827 false,
1828 )),
1829 BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), false)),
1830 BuiltinRunner::Signature(SignatureBuiltinRunner::new(Some(512), false)),
1831 ];
1832 let vm = vm!();
1833
1834 for br in builtins.iter_mut() {
1835 assert_eq!(br.final_stack(&vm.segments, vm.get_ap()), Ok(vm.get_ap()));
1836 }
1837 }
1838
1839 #[test]
1840 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1841 fn runners_set_stop_ptr() {
1842 let builtins = vec![
1843 BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), false)),
1844 BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), false)),
1845 BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)),
1846 BuiltinRunner::Output(OutputBuiltinRunner::new(false)),
1847 BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(
1848 Some(8),
1849 false,
1850 )),
1851 BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), false)),
1852 BuiltinRunner::Signature(SignatureBuiltinRunner::new(Some(512), false)),
1853 BuiltinRunner::Poseidon(PoseidonBuiltinRunner::new(Some(32), false)),
1854 BuiltinRunner::SegmentArena(SegmentArenaBuiltinRunner::new(false)),
1855 ];
1856
1857 let ptr = 3;
1858
1859 for mut br in builtins {
1860 br.set_stop_ptr(ptr);
1861 let (_, stop_ptr) = br.get_memory_segment_addresses();
1862 assert_eq!(stop_ptr, Some(ptr));
1863 }
1864 }
1865
1866 #[test]
1867 fn get_additonal_data_none() {
1868 let builtin: BuiltinRunner = PoseidonBuiltinRunner::new(None, true).into();
1869 assert_eq!(builtin.get_additional_data(), BuiltinAdditionalData::None)
1870 }
1871}