cairo_vm/types/
layout.rs

1use crate::{types::layout_name::LayoutName, vm::errors::runner_errors::RunnerError};
2
3use super::{
4    builtin_name::BuiltinName,
5    instance_definitions::{
6        builtins_instance_def::BuiltinsInstanceDef,
7        diluted_pool_instance_def::DilutedPoolInstanceDef,
8    },
9};
10
11pub(crate) const DEFAULT_MEMORY_UNITS_PER_STEP: u32 = 8;
12pub(crate) const DEFAULT_CPU_COMPONENT_STEP: u32 = 1;
13
14use serde::{Deserialize, Deserializer, Serialize};
15
16#[derive(Serialize, Debug)]
17pub struct CairoLayout {
18    pub(crate) name: LayoutName,
19    pub(crate) cpu_component_step: u32,
20    pub(crate) rc_units: u32,
21    pub(crate) memory_units_per_step: u32,
22    pub(crate) builtins: BuiltinsInstanceDef,
23    pub(crate) public_memory_fraction: u32,
24    pub(crate) diluted_pool_instance_def: Option<DilutedPoolInstanceDef>,
25}
26
27impl CairoLayout {
28    pub(crate) fn plain_instance() -> CairoLayout {
29        CairoLayout {
30            name: LayoutName::plain,
31            rc_units: 16,
32            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
33            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
34            builtins: BuiltinsInstanceDef::plain(),
35            public_memory_fraction: 4,
36            diluted_pool_instance_def: None,
37        }
38    }
39
40    pub(crate) fn small_instance() -> CairoLayout {
41        CairoLayout {
42            name: LayoutName::small,
43            rc_units: 16,
44            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
45            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
46            builtins: BuiltinsInstanceDef::small(),
47            public_memory_fraction: 4,
48            diluted_pool_instance_def: None,
49        }
50    }
51
52    pub(crate) fn dex_instance() -> CairoLayout {
53        CairoLayout {
54            name: LayoutName::dex,
55            rc_units: 4,
56            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
57            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
58            builtins: BuiltinsInstanceDef::dex(),
59            public_memory_fraction: 4,
60            diluted_pool_instance_def: None,
61        }
62    }
63
64    pub(crate) fn recursive_instance() -> CairoLayout {
65        CairoLayout {
66            name: LayoutName::recursive,
67            rc_units: 4,
68            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
69            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
70            builtins: BuiltinsInstanceDef::recursive(),
71            public_memory_fraction: 8,
72            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
73        }
74    }
75
76    pub(crate) fn starknet_instance() -> CairoLayout {
77        CairoLayout {
78            name: LayoutName::starknet,
79            rc_units: 4,
80            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
81            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
82            builtins: BuiltinsInstanceDef::starknet(),
83            public_memory_fraction: 8,
84            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::new(2, 4, 16)),
85        }
86    }
87
88    pub(crate) fn starknet_with_keccak_instance() -> CairoLayout {
89        CairoLayout {
90            name: LayoutName::starknet_with_keccak,
91            rc_units: 4,
92            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
93            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
94            builtins: BuiltinsInstanceDef::starknet_with_keccak(),
95            public_memory_fraction: 8,
96            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
97        }
98    }
99
100    pub(crate) fn recursive_large_output_instance() -> CairoLayout {
101        CairoLayout {
102            name: LayoutName::recursive_large_output,
103            rc_units: 4,
104            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
105            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
106            builtins: BuiltinsInstanceDef::recursive_large_output(),
107            public_memory_fraction: 8,
108            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
109        }
110    }
111    pub(crate) fn recursive_with_poseidon() -> CairoLayout {
112        CairoLayout {
113            name: LayoutName::recursive_with_poseidon,
114            rc_units: 4,
115            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
116            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
117            builtins: BuiltinsInstanceDef::recursive_with_poseidon(),
118            public_memory_fraction: 8,
119            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::new(8, 4, 16)),
120        }
121    }
122
123    pub(crate) fn all_cairo_instance() -> CairoLayout {
124        CairoLayout {
125            name: LayoutName::all_cairo,
126            rc_units: 4,
127            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
128            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
129            builtins: BuiltinsInstanceDef::all_cairo(),
130            public_memory_fraction: 8,
131            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
132        }
133    }
134
135    pub(crate) fn all_cairo_stwo_instance() -> CairoLayout {
136        CairoLayout {
137            name: LayoutName::all_cairo_stwo,
138            rc_units: 4,
139            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
140            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
141            builtins: BuiltinsInstanceDef::all_cairo_stwo(),
142            public_memory_fraction: 8,
143            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
144        }
145    }
146
147    pub(crate) fn all_solidity_instance() -> CairoLayout {
148        CairoLayout {
149            name: LayoutName::all_solidity,
150            rc_units: 8,
151            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
152            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
153            builtins: BuiltinsInstanceDef::all_solidity(),
154            public_memory_fraction: 8,
155            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
156        }
157    }
158
159    pub(crate) fn dynamic_instance(params: CairoLayoutParams) -> CairoLayout {
160        CairoLayout {
161            name: LayoutName::dynamic,
162            rc_units: params.rc_units,
163            cpu_component_step: params.cpu_component_step,
164            memory_units_per_step: params.memory_units_per_step,
165            public_memory_fraction: 8,
166            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::from_log_units_per_step(
167                params.log_diluted_units_per_step,
168            )),
169            builtins: BuiltinsInstanceDef::dynamic(params),
170        }
171    }
172
173    pub(crate) fn perpetual_instance() -> CairoLayout {
174        CairoLayout {
175            name: LayoutName::perpetual,
176            rc_units: 4,
177            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
178            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
179            builtins: BuiltinsInstanceDef::perpetual(),
180            public_memory_fraction: 4,
181            diluted_pool_instance_def: None,
182        }
183    }
184
185    pub(crate) fn dex_with_bitwise_instance() -> CairoLayout {
186        CairoLayout {
187            name: LayoutName::dex_with_bitwise,
188            rc_units: 4,
189            cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
190            memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
191            builtins: BuiltinsInstanceDef::dex_with_bitwise(),
192            public_memory_fraction: 4,
193            diluted_pool_instance_def: Some(DilutedPoolInstanceDef::new(2, 4, 16)),
194        }
195    }
196}
197
198#[cfg(feature = "test_utils")]
199use arbitrary::{self, Arbitrary};
200
201#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
202#[derive(Deserialize, Debug, Clone, Default)]
203#[serde(try_from = "RawCairoLayoutParams")]
204pub struct CairoLayoutParams {
205    pub rc_units: u32,
206    pub cpu_component_step: u32,
207    pub memory_units_per_step: u32,
208    pub log_diluted_units_per_step: i32,
209    pub pedersen_ratio: u32,
210    pub range_check_ratio: u32,
211    pub ecdsa_ratio: u32,
212    pub bitwise_ratio: u32,
213    pub ec_op_ratio: u32,
214    pub keccak_ratio: u32,
215    pub poseidon_ratio: u32,
216    pub range_check96_ratio: u32,
217    pub range_check96_ratio_den: u32,
218    pub add_mod_ratio: u32,
219    pub add_mod_ratio_den: u32,
220    pub mul_mod_ratio: u32,
221    pub mul_mod_ratio_den: u32,
222}
223
224impl CairoLayoutParams {
225    #[cfg(feature = "std")]
226    pub fn from_file(params_path: &std::path::Path) -> std::io::Result<Self> {
227        let params_file = std::fs::File::open(params_path)?;
228        let params = serde_json::from_reader(params_file)?;
229        Ok(params)
230    }
231}
232
233// The CairoLayoutParams contains aditional constraints that can't be validated by serde alone.
234// To work around this. we use an aditional structure `RawCairoLayoutParams` that gets deserialized by serde
235// and then its tranformed into `CairoLayoutParams`.
236
237#[derive(Deserialize, Debug, Default, Clone)]
238pub struct RawCairoLayoutParams {
239    pub rc_units: u32,
240    pub cpu_component_step: u32,
241    pub memory_units_per_step: u32,
242    pub log_diluted_units_per_step: i32,
243    #[serde(deserialize_with = "bool_from_int_or_bool")]
244    pub uses_pedersen_builtin: bool,
245    pub pedersen_ratio: u32,
246    #[serde(deserialize_with = "bool_from_int_or_bool")]
247    pub uses_range_check_builtin: bool,
248    pub range_check_ratio: u32,
249    #[serde(deserialize_with = "bool_from_int_or_bool")]
250    pub uses_ecdsa_builtin: bool,
251    pub ecdsa_ratio: u32,
252    #[serde(deserialize_with = "bool_from_int_or_bool")]
253    pub uses_bitwise_builtin: bool,
254    pub bitwise_ratio: u32,
255    #[serde(deserialize_with = "bool_from_int_or_bool")]
256    pub uses_ec_op_builtin: bool,
257    pub ec_op_ratio: u32,
258    #[serde(deserialize_with = "bool_from_int_or_bool")]
259    pub uses_keccak_builtin: bool,
260    pub keccak_ratio: u32,
261    #[serde(deserialize_with = "bool_from_int_or_bool")]
262    pub uses_poseidon_builtin: bool,
263    pub poseidon_ratio: u32,
264    #[serde(deserialize_with = "bool_from_int_or_bool")]
265    pub uses_range_check96_builtin: bool,
266    pub range_check96_ratio: u32,
267    pub range_check96_ratio_den: u32,
268    #[serde(deserialize_with = "bool_from_int_or_bool")]
269    pub uses_add_mod_builtin: bool,
270    pub add_mod_ratio: u32,
271    pub add_mod_ratio_den: u32,
272    #[serde(deserialize_with = "bool_from_int_or_bool")]
273    pub uses_mul_mod_builtin: bool,
274    pub mul_mod_ratio: u32,
275    pub mul_mod_ratio_den: u32,
276}
277
278impl TryFrom<RawCairoLayoutParams> for CairoLayoutParams {
279    type Error = RunnerError;
280
281    fn try_from(value: RawCairoLayoutParams) -> Result<Self, Self::Error> {
282        if !value.uses_pedersen_builtin && value.pedersen_ratio != 0 {
283            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
284                BuiltinName::pedersen,
285            ));
286        }
287        if !value.uses_range_check_builtin && value.range_check_ratio != 0 {
288            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
289                BuiltinName::range_check,
290            ));
291        }
292        if !value.uses_ecdsa_builtin && value.ecdsa_ratio != 0 {
293            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
294                BuiltinName::ecdsa,
295            ));
296        }
297        if !value.uses_bitwise_builtin && value.bitwise_ratio != 0 {
298            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
299                BuiltinName::bitwise,
300            ));
301        }
302        if !value.uses_ec_op_builtin && value.ec_op_ratio != 0 {
303            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
304                BuiltinName::ec_op,
305            ));
306        }
307        if !value.uses_keccak_builtin && value.keccak_ratio != 0 {
308            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
309                BuiltinName::keccak,
310            ));
311        }
312        if !value.uses_poseidon_builtin && value.poseidon_ratio != 0 {
313            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
314                BuiltinName::poseidon,
315            ));
316        }
317        if !value.uses_range_check96_builtin && value.range_check96_ratio != 0 {
318            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
319                BuiltinName::range_check96,
320            ));
321        }
322        if !value.uses_add_mod_builtin && value.add_mod_ratio != 0 {
323            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
324                BuiltinName::add_mod,
325            ));
326        }
327        if !value.uses_mul_mod_builtin && value.mul_mod_ratio != 0 {
328            return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
329                BuiltinName::mul_mod,
330            ));
331        }
332
333        Ok(CairoLayoutParams {
334            rc_units: value.rc_units,
335            log_diluted_units_per_step: value.log_diluted_units_per_step,
336            cpu_component_step: value.cpu_component_step,
337            memory_units_per_step: value.memory_units_per_step,
338            range_check96_ratio_den: value.range_check96_ratio_den,
339            mul_mod_ratio_den: value.mul_mod_ratio_den,
340            add_mod_ratio_den: value.add_mod_ratio_den,
341            pedersen_ratio: value.pedersen_ratio,
342            range_check_ratio: value.range_check_ratio,
343            ecdsa_ratio: value.ecdsa_ratio,
344            bitwise_ratio: value.bitwise_ratio,
345            ec_op_ratio: value.ec_op_ratio,
346            keccak_ratio: value.keccak_ratio,
347            poseidon_ratio: value.poseidon_ratio,
348            range_check96_ratio: value.range_check96_ratio,
349            add_mod_ratio: value.add_mod_ratio,
350            mul_mod_ratio: value.mul_mod_ratio,
351        })
352    }
353}
354
355fn bool_from_int_or_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
356where
357    D: Deserializer<'de>,
358{
359    #[derive(Deserialize)]
360    #[serde(untagged)]
361    enum IntOrBool {
362        Int(i64),
363        Boolean(bool),
364    }
365
366    match IntOrBool::deserialize(deserializer)? {
367        IntOrBool::Int(0) => Ok(false),
368        IntOrBool::Int(_) => Ok(true),
369        IntOrBool::Boolean(v) => Ok(v),
370    }
371}
372
373#[cfg(test)]
374mod tests {
375    use super::*;
376    #[cfg(feature = "mod_builtin")]
377    use crate::types::instance_definitions::mod_instance_def::ModInstanceDef;
378
379    use crate::types::instance_definitions::{
380        bitwise_instance_def::BitwiseInstanceDef, ec_op_instance_def::EcOpInstanceDef,
381        ecdsa_instance_def::EcdsaInstanceDef, keccak_instance_def::KeccakInstanceDef,
382        pedersen_instance_def::PedersenInstanceDef, poseidon_instance_def::PoseidonInstanceDef,
383        range_check_instance_def::RangeCheckInstanceDef, LowRatio,
384    };
385
386    #[cfg(target_arch = "wasm32")]
387    use wasm_bindgen_test::*;
388
389    #[test]
390    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
391    fn get_plain_instance() {
392        let layout = CairoLayout::plain_instance();
393        let builtins = BuiltinsInstanceDef::plain();
394        assert_eq!(layout.name, LayoutName::plain);
395        assert_eq!(layout.rc_units, 16);
396        assert_eq!(layout.builtins, builtins);
397        assert_eq!(layout.public_memory_fraction, 4);
398        assert_eq!(layout.diluted_pool_instance_def, None);
399    }
400
401    #[test]
402    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
403    fn get_small_instance() {
404        let layout = CairoLayout::small_instance();
405        let builtins = BuiltinsInstanceDef::small();
406        assert_eq!(layout.name, LayoutName::small);
407        assert_eq!(layout.rc_units, 16);
408        assert_eq!(layout.builtins, builtins);
409        assert_eq!(layout.public_memory_fraction, 4);
410        assert_eq!(layout.diluted_pool_instance_def, None);
411    }
412
413    #[test]
414    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
415    fn get_dex_instance() {
416        let layout = CairoLayout::dex_instance();
417        let builtins = BuiltinsInstanceDef::dex();
418        assert_eq!(layout.name, LayoutName::dex);
419        assert_eq!(layout.rc_units, 4);
420        assert_eq!(layout.builtins, builtins);
421        assert_eq!(layout.public_memory_fraction, 4);
422        assert_eq!(layout.diluted_pool_instance_def, None);
423    }
424
425    #[test]
426    fn get_recursive_instance() {
427        let layout = CairoLayout::recursive_instance();
428        let builtins = BuiltinsInstanceDef::recursive();
429        assert_eq!(layout.name, LayoutName::recursive);
430        assert_eq!(layout.rc_units, 4);
431        assert_eq!(layout.builtins, builtins);
432        assert_eq!(layout.public_memory_fraction, 8);
433        assert_eq!(
434            layout.diluted_pool_instance_def,
435            Some(DilutedPoolInstanceDef::default())
436        );
437    }
438
439    #[test]
440    fn get_starknet_instance() {
441        let layout = CairoLayout::starknet_instance();
442        let builtins = BuiltinsInstanceDef::starknet();
443        assert_eq!(layout.name, LayoutName::starknet);
444        assert_eq!(layout.rc_units, 4);
445        assert_eq!(layout.builtins, builtins);
446        assert_eq!(layout.public_memory_fraction, 8);
447        assert_eq!(
448            layout.diluted_pool_instance_def,
449            Some(DilutedPoolInstanceDef::new(2, 4, 16))
450        );
451    }
452
453    #[test]
454    fn get_starknet_with_keccak_instance() {
455        let layout = CairoLayout::starknet_with_keccak_instance();
456        let builtins = BuiltinsInstanceDef::starknet_with_keccak();
457        assert_eq!(layout.name, LayoutName::starknet_with_keccak);
458        assert_eq!(layout.rc_units, 4);
459        assert_eq!(layout.builtins, builtins);
460        assert_eq!(layout.public_memory_fraction, 8);
461        assert_eq!(
462            layout.diluted_pool_instance_def,
463            Some(DilutedPoolInstanceDef::default())
464        );
465    }
466
467    #[test]
468    fn get_recursive_large_output_instance() {
469        let layout = CairoLayout::recursive_large_output_instance();
470        let builtins = BuiltinsInstanceDef::recursive_large_output();
471        assert_eq!(layout.name, LayoutName::recursive_large_output);
472        assert_eq!(layout.rc_units, 4);
473        assert_eq!(layout.builtins, builtins);
474        assert_eq!(layout.public_memory_fraction, 8);
475        assert_eq!(
476            layout.diluted_pool_instance_def,
477            Some(DilutedPoolInstanceDef::default())
478        );
479    }
480
481    #[test]
482    fn get_all_cairo_instance() {
483        let layout = CairoLayout::all_cairo_instance();
484        let builtins = BuiltinsInstanceDef::all_cairo();
485        assert_eq!(layout.name, LayoutName::all_cairo);
486        assert_eq!(layout.rc_units, 4);
487        assert_eq!(layout.builtins, builtins);
488        assert_eq!(layout.public_memory_fraction, 8);
489        assert_eq!(
490            layout.diluted_pool_instance_def,
491            Some(DilutedPoolInstanceDef::default())
492        );
493    }
494
495    #[test]
496    fn get_all_cairo_stwo_instance() {
497        let layout = CairoLayout::all_cairo_stwo_instance();
498        let builtins = BuiltinsInstanceDef::all_cairo_stwo();
499        assert_eq!(layout.name, LayoutName::all_cairo_stwo);
500        assert_eq!(layout.rc_units, 4);
501        assert_eq!(layout.builtins, builtins);
502        assert_eq!(layout.public_memory_fraction, 8);
503        assert_eq!(
504            layout.diluted_pool_instance_def,
505            Some(DilutedPoolInstanceDef::default())
506        );
507    }
508
509    #[test]
510    fn get_all_solidity_instance() {
511        let layout = CairoLayout::all_solidity_instance();
512        let builtins = BuiltinsInstanceDef::all_solidity();
513        assert_eq!(layout.name, LayoutName::all_solidity);
514        assert_eq!(layout.rc_units, 8);
515        assert_eq!(layout.builtins, builtins);
516        assert_eq!(layout.public_memory_fraction, 8);
517        assert_eq!(
518            layout.diluted_pool_instance_def,
519            Some(DilutedPoolInstanceDef::default())
520        );
521    }
522
523    #[test]
524    fn get_perpetual_instance() {
525        let layout = CairoLayout::perpetual_instance();
526        let builtins = BuiltinsInstanceDef::perpetual();
527        assert_eq!(layout.name, LayoutName::perpetual);
528        assert_eq!(layout.rc_units, 4);
529        assert_eq!(layout.builtins, builtins);
530        assert_eq!(layout.public_memory_fraction, 4);
531        assert_eq!(layout.diluted_pool_instance_def, None);
532    }
533
534    #[test]
535    fn get_dex_with_bitwise_instance() {
536        let layout = CairoLayout::dex_with_bitwise_instance();
537        let builtins = BuiltinsInstanceDef::dex_with_bitwise();
538        assert_eq!(layout.name, LayoutName::dex_with_bitwise);
539        assert_eq!(layout.rc_units, 4);
540        assert_eq!(layout.builtins, builtins);
541        assert_eq!(layout.public_memory_fraction, 4);
542        assert_eq!(
543            layout.diluted_pool_instance_def,
544            Some(DilutedPoolInstanceDef::new(2, 4, 16))
545        );
546    }
547
548    #[test]
549    fn get_dynamic_instance() {
550        // dummy cairo layout params
551        let params = CairoLayoutParams {
552            rc_units: 32,
553            cpu_component_step: 8,
554            memory_units_per_step: 16,
555            log_diluted_units_per_step: 5,
556            pedersen_ratio: 32,
557            range_check_ratio: 32,
558            ecdsa_ratio: 32,
559            bitwise_ratio: 32,
560            ec_op_ratio: 32,
561            keccak_ratio: 32,
562            poseidon_ratio: 0,
563            range_check96_ratio: 8,
564            range_check96_ratio_den: 16,
565            add_mod_ratio: 8,
566            add_mod_ratio_den: 16,
567            mul_mod_ratio: 32,
568            mul_mod_ratio_den: 16,
569        };
570
571        let layout = CairoLayout::dynamic_instance(params);
572
573        assert_eq!(layout.name, LayoutName::dynamic);
574        assert_eq!(layout.rc_units, 32);
575        assert_eq!(layout.cpu_component_step, 8);
576        assert_eq!(layout.memory_units_per_step, 16);
577        assert_eq!(layout.public_memory_fraction, 8); // hardcoded
578        assert_eq!(
579            layout.diluted_pool_instance_def,
580            Some(DilutedPoolInstanceDef {
581                units_per_step: 32,
582                ..DilutedPoolInstanceDef::default() // hardcoded
583            })
584        );
585
586        assert!(layout.builtins.output);
587        assert_eq!(
588            layout.builtins.pedersen,
589            Some(PedersenInstanceDef { ratio: Some(32) })
590        );
591        assert_eq!(
592            layout.builtins.range_check,
593            Some(RangeCheckInstanceDef {
594                ratio: Some(LowRatio::new_int(32))
595            })
596        );
597        assert_eq!(
598            layout.builtins.ecdsa,
599            Some(EcdsaInstanceDef { ratio: Some(32) })
600        );
601        assert_eq!(
602            layout.builtins.bitwise,
603            Some(BitwiseInstanceDef { ratio: Some(32) })
604        );
605        assert_eq!(
606            layout.builtins.ec_op,
607            Some(EcOpInstanceDef { ratio: Some(32) })
608        );
609        assert_eq!(
610            layout.builtins.keccak,
611            Some(KeccakInstanceDef { ratio: Some(32) })
612        );
613        assert_eq!(
614            layout.builtins.poseidon,
615            Some(PoseidonInstanceDef { ratio: Some(0) }),
616        );
617        assert_eq!(
618            layout.builtins.range_check96,
619            Some(RangeCheckInstanceDef {
620                ratio: Some(LowRatio::new(8, 16))
621            })
622        );
623        #[cfg(feature = "mod_builtin")]
624        {
625            assert_eq!(
626                layout.builtins.mul_mod,
627                Some(ModInstanceDef {
628                    ratio: Some(LowRatio {
629                        numerator: 32,
630                        denominator: 16
631                    }),
632                    word_bit_len: 96, // hardcoded
633                    batch_size: 1     // hardcoded
634                }),
635            );
636            assert_eq!(
637                layout.builtins.add_mod,
638                Some(ModInstanceDef {
639                    ratio: Some(LowRatio {
640                        numerator: 8,
641                        denominator: 16
642                    }),
643                    word_bit_len: 96, // hardcoded
644                    batch_size: 1     // hardcoded
645                })
646            );
647        }
648        #[cfg(not(feature = "mod_builtin"))]
649        {
650            assert_eq!(layout.builtins.mul_mod, None,);
651            assert_eq!(layout.builtins.add_mod, None,);
652        }
653    }
654
655    #[test]
656    fn parse_dynamic_instance() {
657        let cairo_layout_params_json = "{\n\
658            \"rc_units\": 4,\n\
659            \"log_diluted_units_per_step\": 4,\n\
660            \"cpu_component_step\": 8,\n\
661            \"memory_units_per_step\": 8,\n\
662            \"uses_pedersen_builtin\": true,\n\
663            \"pedersen_ratio\": 256,\n\
664            \"uses_range_check_builtin\": true,\n\
665            \"range_check_ratio\": 8,\n\
666            \"uses_ecdsa_builtin\": true,\n\
667            \"ecdsa_ratio\": 2048,\n\
668            \"uses_bitwise_builtin\": true,\n\
669            \"bitwise_ratio\": 16,\n\
670            \"uses_ec_op_builtin\": true,\n\
671            \"ec_op_ratio\": 1024,\n\
672            \"uses_keccak_builtin\": true,\n\
673            \"keccak_ratio\": 2048,\n\
674            \"uses_poseidon_builtin\": true,\n\
675            \"poseidon_ratio\": 256,\n\
676            \"uses_range_check96_builtin\": true,\n\
677            \"range_check96_ratio\": 8,\n\
678            \"range_check96_ratio_den\": 1,\n\
679            \"uses_add_mod_builtin\": true,\n\
680            \"add_mod_ratio\": 128,\n\
681            \"add_mod_ratio_den\": 1,\n\
682            \"uses_mul_mod_builtin\": true,\n\
683            \"mul_mod_ratio\": 256,\n\
684            \"mul_mod_ratio_den\": 1\n\
685        }\n\
686        ";
687
688        serde_json::from_str::<CairoLayoutParams>(cairo_layout_params_json).unwrap();
689    }
690}