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_solidity_instance() -> CairoLayout {
136 CairoLayout {
137 name: LayoutName::all_solidity,
138 rc_units: 8,
139 cpu_component_step: DEFAULT_CPU_COMPONENT_STEP,
140 memory_units_per_step: DEFAULT_MEMORY_UNITS_PER_STEP,
141 builtins: BuiltinsInstanceDef::all_solidity(),
142 public_memory_fraction: 8,
143 diluted_pool_instance_def: Some(DilutedPoolInstanceDef::default()),
144 }
145 }
146
147 pub(crate) fn dynamic_instance(params: CairoLayoutParams) -> CairoLayout {
148 CairoLayout {
149 name: LayoutName::dynamic,
150 rc_units: params.rc_units,
151 cpu_component_step: params.cpu_component_step,
152 memory_units_per_step: params.memory_units_per_step,
153 public_memory_fraction: 8,
154 diluted_pool_instance_def: Some(DilutedPoolInstanceDef::from_log_units_per_step(
155 params.log_diluted_units_per_step,
156 )),
157 builtins: BuiltinsInstanceDef::dynamic(params),
158 }
159 }
160}
161
162#[cfg(feature = "test_utils")]
163use arbitrary::{self, Arbitrary};
164
165#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
166#[derive(Deserialize, Debug, Clone, Default)]
167#[serde(try_from = "RawCairoLayoutParams")]
168pub struct CairoLayoutParams {
169 pub rc_units: u32,
170 pub cpu_component_step: u32,
171 pub memory_units_per_step: u32,
172 pub log_diluted_units_per_step: i32,
173 pub pedersen_ratio: u32,
174 pub range_check_ratio: u32,
175 pub ecdsa_ratio: u32,
176 pub bitwise_ratio: u32,
177 pub ec_op_ratio: u32,
178 pub keccak_ratio: u32,
179 pub poseidon_ratio: u32,
180 pub range_check96_ratio: u32,
181 pub range_check96_ratio_den: u32,
182 pub add_mod_ratio: u32,
183 pub add_mod_ratio_den: u32,
184 pub mul_mod_ratio: u32,
185 pub mul_mod_ratio_den: u32,
186}
187
188impl CairoLayoutParams {
189 #[cfg(feature = "std")]
190 pub fn from_file(params_path: &std::path::Path) -> std::io::Result<Self> {
191 let params_file = std::fs::File::open(params_path)?;
192 let params = serde_json::from_reader(params_file)?;
193 Ok(params)
194 }
195}
196
197#[derive(Deserialize, Debug, Default, Clone)]
202pub struct RawCairoLayoutParams {
203 pub rc_units: u32,
204 pub cpu_component_step: u32,
205 pub memory_units_per_step: u32,
206 pub log_diluted_units_per_step: i32,
207 #[serde(deserialize_with = "bool_from_int_or_bool")]
208 pub uses_pedersen_builtin: bool,
209 pub pedersen_ratio: u32,
210 #[serde(deserialize_with = "bool_from_int_or_bool")]
211 pub uses_range_check_builtin: bool,
212 pub range_check_ratio: u32,
213 #[serde(deserialize_with = "bool_from_int_or_bool")]
214 pub uses_ecdsa_builtin: bool,
215 pub ecdsa_ratio: u32,
216 #[serde(deserialize_with = "bool_from_int_or_bool")]
217 pub uses_bitwise_builtin: bool,
218 pub bitwise_ratio: u32,
219 #[serde(deserialize_with = "bool_from_int_or_bool")]
220 pub uses_ec_op_builtin: bool,
221 pub ec_op_ratio: u32,
222 #[serde(deserialize_with = "bool_from_int_or_bool")]
223 pub uses_keccak_builtin: bool,
224 pub keccak_ratio: u32,
225 #[serde(deserialize_with = "bool_from_int_or_bool")]
226 pub uses_poseidon_builtin: bool,
227 pub poseidon_ratio: u32,
228 #[serde(deserialize_with = "bool_from_int_or_bool")]
229 pub uses_range_check96_builtin: bool,
230 pub range_check96_ratio: u32,
231 pub range_check96_ratio_den: u32,
232 #[serde(deserialize_with = "bool_from_int_or_bool")]
233 pub uses_add_mod_builtin: bool,
234 pub add_mod_ratio: u32,
235 pub add_mod_ratio_den: u32,
236 #[serde(deserialize_with = "bool_from_int_or_bool")]
237 pub uses_mul_mod_builtin: bool,
238 pub mul_mod_ratio: u32,
239 pub mul_mod_ratio_den: u32,
240}
241
242impl TryFrom<RawCairoLayoutParams> for CairoLayoutParams {
243 type Error = RunnerError;
244
245 fn try_from(value: RawCairoLayoutParams) -> Result<Self, Self::Error> {
246 if !value.uses_pedersen_builtin && value.pedersen_ratio != 0 {
247 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
248 BuiltinName::pedersen,
249 ));
250 }
251 if !value.uses_range_check_builtin && value.range_check_ratio != 0 {
252 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
253 BuiltinName::range_check,
254 ));
255 }
256 if !value.uses_ecdsa_builtin && value.ecdsa_ratio != 0 {
257 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
258 BuiltinName::ecdsa,
259 ));
260 }
261 if !value.uses_bitwise_builtin && value.bitwise_ratio != 0 {
262 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
263 BuiltinName::bitwise,
264 ));
265 }
266 if !value.uses_ec_op_builtin && value.ec_op_ratio != 0 {
267 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
268 BuiltinName::ec_op,
269 ));
270 }
271 if !value.uses_keccak_builtin && value.keccak_ratio != 0 {
272 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
273 BuiltinName::keccak,
274 ));
275 }
276 if !value.uses_poseidon_builtin && value.poseidon_ratio != 0 {
277 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
278 BuiltinName::poseidon,
279 ));
280 }
281 if !value.uses_range_check96_builtin && value.range_check96_ratio != 0 {
282 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
283 BuiltinName::range_check96,
284 ));
285 }
286 if !value.uses_add_mod_builtin && value.add_mod_ratio != 0 {
287 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
288 BuiltinName::add_mod,
289 ));
290 }
291 if !value.uses_mul_mod_builtin && value.mul_mod_ratio != 0 {
292 return Err(RunnerError::BadDynamicLayoutBuiltinRatio(
293 BuiltinName::mul_mod,
294 ));
295 }
296
297 Ok(CairoLayoutParams {
298 rc_units: value.rc_units,
299 log_diluted_units_per_step: value.log_diluted_units_per_step,
300 cpu_component_step: value.cpu_component_step,
301 memory_units_per_step: value.memory_units_per_step,
302 range_check96_ratio_den: value.range_check96_ratio_den,
303 mul_mod_ratio_den: value.mul_mod_ratio_den,
304 add_mod_ratio_den: value.add_mod_ratio_den,
305 pedersen_ratio: value.pedersen_ratio,
306 range_check_ratio: value.range_check_ratio,
307 ecdsa_ratio: value.ecdsa_ratio,
308 bitwise_ratio: value.bitwise_ratio,
309 ec_op_ratio: value.ec_op_ratio,
310 keccak_ratio: value.keccak_ratio,
311 poseidon_ratio: value.poseidon_ratio,
312 range_check96_ratio: value.range_check96_ratio,
313 add_mod_ratio: value.add_mod_ratio,
314 mul_mod_ratio: value.mul_mod_ratio,
315 })
316 }
317}
318
319fn bool_from_int_or_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
320where
321 D: Deserializer<'de>,
322{
323 #[derive(Deserialize)]
324 #[serde(untagged)]
325 enum IntOrBool {
326 Int(i64),
327 Boolean(bool),
328 }
329
330 match IntOrBool::deserialize(deserializer)? {
331 IntOrBool::Int(0) => Ok(false),
332 IntOrBool::Int(_) => Ok(true),
333 IntOrBool::Boolean(v) => Ok(v),
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340 #[cfg(feature = "mod_builtin")]
341 use crate::types::instance_definitions::mod_instance_def::ModInstanceDef;
342
343 use crate::types::instance_definitions::{
344 bitwise_instance_def::BitwiseInstanceDef, ec_op_instance_def::EcOpInstanceDef,
345 ecdsa_instance_def::EcdsaInstanceDef, keccak_instance_def::KeccakInstanceDef,
346 pedersen_instance_def::PedersenInstanceDef, poseidon_instance_def::PoseidonInstanceDef,
347 range_check_instance_def::RangeCheckInstanceDef, LowRatio,
348 };
349
350 #[cfg(target_arch = "wasm32")]
351 use wasm_bindgen_test::*;
352
353 #[test]
354 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
355 fn get_plain_instance() {
356 let layout = CairoLayout::plain_instance();
357 let builtins = BuiltinsInstanceDef::plain();
358 assert_eq!(layout.name, LayoutName::plain);
359 assert_eq!(layout.rc_units, 16);
360 assert_eq!(layout.builtins, builtins);
361 assert_eq!(layout.public_memory_fraction, 4);
362 assert_eq!(layout.diluted_pool_instance_def, None);
363 }
364
365 #[test]
366 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
367 fn get_small_instance() {
368 let layout = CairoLayout::small_instance();
369 let builtins = BuiltinsInstanceDef::small();
370 assert_eq!(layout.name, LayoutName::small);
371 assert_eq!(layout.rc_units, 16);
372 assert_eq!(layout.builtins, builtins);
373 assert_eq!(layout.public_memory_fraction, 4);
374 assert_eq!(layout.diluted_pool_instance_def, None);
375 }
376
377 #[test]
378 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
379 fn get_dex_instance() {
380 let layout = CairoLayout::dex_instance();
381 let builtins = BuiltinsInstanceDef::dex();
382 assert_eq!(layout.name, LayoutName::dex);
383 assert_eq!(layout.rc_units, 4);
384 assert_eq!(layout.builtins, builtins);
385 assert_eq!(layout.public_memory_fraction, 4);
386 assert_eq!(layout.diluted_pool_instance_def, None);
387 }
388
389 #[test]
390 fn get_recursive_instance() {
391 let layout = CairoLayout::recursive_instance();
392 let builtins = BuiltinsInstanceDef::recursive();
393 assert_eq!(layout.name, LayoutName::recursive);
394 assert_eq!(layout.rc_units, 4);
395 assert_eq!(layout.builtins, builtins);
396 assert_eq!(layout.public_memory_fraction, 8);
397 assert_eq!(
398 layout.diluted_pool_instance_def,
399 Some(DilutedPoolInstanceDef::default())
400 );
401 }
402
403 #[test]
404 fn get_starknet_instance() {
405 let layout = CairoLayout::starknet_instance();
406 let builtins = BuiltinsInstanceDef::starknet();
407 assert_eq!(layout.name, LayoutName::starknet);
408 assert_eq!(layout.rc_units, 4);
409 assert_eq!(layout.builtins, builtins);
410 assert_eq!(layout.public_memory_fraction, 8);
411 assert_eq!(
412 layout.diluted_pool_instance_def,
413 Some(DilutedPoolInstanceDef::new(2, 4, 16))
414 );
415 }
416
417 #[test]
418 fn get_starknet_with_keccak_instance() {
419 let layout = CairoLayout::starknet_with_keccak_instance();
420 let builtins = BuiltinsInstanceDef::starknet_with_keccak();
421 assert_eq!(layout.name, LayoutName::starknet_with_keccak);
422 assert_eq!(layout.rc_units, 4);
423 assert_eq!(layout.builtins, builtins);
424 assert_eq!(layout.public_memory_fraction, 8);
425 assert_eq!(
426 layout.diluted_pool_instance_def,
427 Some(DilutedPoolInstanceDef::default())
428 );
429 }
430
431 #[test]
432 fn get_recursive_large_output_instance() {
433 let layout = CairoLayout::recursive_large_output_instance();
434 let builtins = BuiltinsInstanceDef::recursive_large_output();
435 assert_eq!(layout.name, LayoutName::recursive_large_output);
436 assert_eq!(layout.rc_units, 4);
437 assert_eq!(layout.builtins, builtins);
438 assert_eq!(layout.public_memory_fraction, 8);
439 assert_eq!(
440 layout.diluted_pool_instance_def,
441 Some(DilutedPoolInstanceDef::default())
442 );
443 }
444
445 #[test]
446 fn get_all_cairo_instance() {
447 let layout = CairoLayout::all_cairo_instance();
448 let builtins = BuiltinsInstanceDef::all_cairo();
449 assert_eq!(layout.name, LayoutName::all_cairo);
450 assert_eq!(layout.rc_units, 4);
451 assert_eq!(layout.builtins, builtins);
452 assert_eq!(layout.public_memory_fraction, 8);
453 assert_eq!(
454 layout.diluted_pool_instance_def,
455 Some(DilutedPoolInstanceDef::default())
456 );
457 }
458
459 #[test]
460 fn get_all_solidity_instance() {
461 let layout = CairoLayout::all_solidity_instance();
462 let builtins = BuiltinsInstanceDef::all_solidity();
463 assert_eq!(layout.name, LayoutName::all_solidity);
464 assert_eq!(layout.rc_units, 8);
465 assert_eq!(layout.builtins, builtins);
466 assert_eq!(layout.public_memory_fraction, 8);
467 assert_eq!(
468 layout.diluted_pool_instance_def,
469 Some(DilutedPoolInstanceDef::default())
470 );
471 }
472
473 #[test]
474 fn get_dynamic_instance() {
475 let params = CairoLayoutParams {
477 rc_units: 32,
478 cpu_component_step: 8,
479 memory_units_per_step: 16,
480 log_diluted_units_per_step: 5,
481 pedersen_ratio: 32,
482 range_check_ratio: 32,
483 ecdsa_ratio: 32,
484 bitwise_ratio: 32,
485 ec_op_ratio: 32,
486 keccak_ratio: 32,
487 poseidon_ratio: 0,
488 range_check96_ratio: 8,
489 range_check96_ratio_den: 16,
490 add_mod_ratio: 8,
491 add_mod_ratio_den: 16,
492 mul_mod_ratio: 32,
493 mul_mod_ratio_den: 16,
494 };
495
496 let layout = CairoLayout::dynamic_instance(params);
497
498 assert_eq!(layout.name, LayoutName::dynamic);
499 assert_eq!(layout.rc_units, 32);
500 assert_eq!(layout.cpu_component_step, 8);
501 assert_eq!(layout.memory_units_per_step, 16);
502 assert_eq!(layout.public_memory_fraction, 8); assert_eq!(
504 layout.diluted_pool_instance_def,
505 Some(DilutedPoolInstanceDef {
506 units_per_step: 32,
507 ..DilutedPoolInstanceDef::default() })
509 );
510
511 assert!(layout.builtins.output);
512 assert_eq!(
513 layout.builtins.pedersen,
514 Some(PedersenInstanceDef { ratio: Some(32) })
515 );
516 assert_eq!(
517 layout.builtins.range_check,
518 Some(RangeCheckInstanceDef {
519 ratio: Some(LowRatio::new_int(32))
520 })
521 );
522 assert_eq!(
523 layout.builtins.ecdsa,
524 Some(EcdsaInstanceDef { ratio: Some(32) })
525 );
526 assert_eq!(
527 layout.builtins.bitwise,
528 Some(BitwiseInstanceDef { ratio: Some(32) })
529 );
530 assert_eq!(
531 layout.builtins.ec_op,
532 Some(EcOpInstanceDef { ratio: Some(32) })
533 );
534 assert_eq!(
535 layout.builtins.keccak,
536 Some(KeccakInstanceDef { ratio: Some(32) })
537 );
538 assert_eq!(
539 layout.builtins.poseidon,
540 Some(PoseidonInstanceDef { ratio: Some(0) }),
541 );
542 assert_eq!(
543 layout.builtins.range_check96,
544 Some(RangeCheckInstanceDef {
545 ratio: Some(LowRatio::new(8, 16))
546 })
547 );
548 #[cfg(feature = "mod_builtin")]
549 {
550 assert_eq!(
551 layout.builtins.mul_mod,
552 Some(ModInstanceDef {
553 ratio: Some(LowRatio {
554 numerator: 32,
555 denominator: 16
556 }),
557 word_bit_len: 96, batch_size: 1 }),
560 );
561 assert_eq!(
562 layout.builtins.add_mod,
563 Some(ModInstanceDef {
564 ratio: Some(LowRatio {
565 numerator: 8,
566 denominator: 16
567 }),
568 word_bit_len: 96, batch_size: 1 })
571 );
572 }
573 #[cfg(not(feature = "mod_builtin"))]
574 {
575 assert_eq!(layout.builtins.mul_mod, None,);
576 assert_eq!(layout.builtins.add_mod, None,);
577 }
578 }
579
580 #[test]
581 fn parse_dynamic_instance() {
582 let cairo_layout_params_json = "{\n\
583 \"rc_units\": 4,\n\
584 \"log_diluted_units_per_step\": 4,\n\
585 \"cpu_component_step\": 8,\n\
586 \"memory_units_per_step\": 8,\n\
587 \"uses_pedersen_builtin\": true,\n\
588 \"pedersen_ratio\": 256,\n\
589 \"uses_range_check_builtin\": true,\n\
590 \"range_check_ratio\": 8,\n\
591 \"uses_ecdsa_builtin\": true,\n\
592 \"ecdsa_ratio\": 2048,\n\
593 \"uses_bitwise_builtin\": true,\n\
594 \"bitwise_ratio\": 16,\n\
595 \"uses_ec_op_builtin\": true,\n\
596 \"ec_op_ratio\": 1024,\n\
597 \"uses_keccak_builtin\": true,\n\
598 \"keccak_ratio\": 2048,\n\
599 \"uses_poseidon_builtin\": true,\n\
600 \"poseidon_ratio\": 256,\n\
601 \"uses_range_check96_builtin\": true,\n\
602 \"range_check96_ratio\": 8,\n\
603 \"range_check96_ratio_den\": 1,\n\
604 \"uses_add_mod_builtin\": true,\n\
605 \"add_mod_ratio\": 128,\n\
606 \"add_mod_ratio_den\": 1,\n\
607 \"uses_mul_mod_builtin\": true,\n\
608 \"mul_mod_ratio\": 256,\n\
609 \"mul_mod_ratio_den\": 1\n\
610 }\n\
611 ";
612
613 serde_json::from_str::<CairoLayoutParams>(cairo_layout_params_json).unwrap();
614 }
615}