cairo_lang_execute_utils/
lib.rs

1use std::collections::HashMap;
2use std::path::PathBuf;
3
4use anyhow::Context;
5use cairo_lang_casm::hints::Hint;
6use cairo_lang_executable::executable::{EntryPointKind, Executable};
7use cairo_lang_runner::{Arg, build_hints_dict};
8use cairo_lang_utils::bigint::BigUintAsHex;
9use cairo_vm::Felt252;
10use cairo_vm::types::program::Program;
11use cairo_vm::types::relocatable::MaybeRelocatable;
12use num_bigint::BigInt;
13
14// Returns a tuple containing:
15/// 1. The Program instance - set according to the type of the required entrypoint.
16/// 2. The hint by string mapping.
17///
18/// This is required for running an executable in the Cairo-VM.
19pub fn program_and_hints_from_executable(
20    executable: &Executable,
21    standalone: bool,
22) -> anyhow::Result<(Program, HashMap<String, Hint>)> {
23    let data: Vec<MaybeRelocatable> =
24        executable.program.bytecode.iter().map(Felt252::from).map(MaybeRelocatable::from).collect();
25    let (hints, string_to_hint) = build_hints_dict(&executable.program.hints);
26    let program = if standalone {
27        let entrypoint = executable
28            .entrypoints
29            .iter()
30            .find(|e| matches!(e.kind, EntryPointKind::Standalone))
31            .with_context(|| "No `Standalone` entrypoint found.")?;
32        Program::new_for_proof(
33            entrypoint.builtins.clone(),
34            data,
35            entrypoint.offset,
36            entrypoint.offset + 4,
37            hints,
38            Default::default(),
39            Default::default(),
40            vec![],
41            None,
42        )
43    } else {
44        let entrypoint = executable
45            .entrypoints
46            .iter()
47            .find(|e| matches!(e.kind, EntryPointKind::Bootloader))
48            .with_context(|| "No `Bootloader` entrypoint found.")?;
49        Program::new(
50            entrypoint.builtins.clone(),
51            data,
52            Some(entrypoint.offset),
53            hints,
54            Default::default(),
55            Default::default(),
56            vec![],
57            None,
58        )
59    }
60    .with_context(|| "Failed setting up program.")?;
61
62    Ok((program, string_to_hint))
63}
64
65/// Returns the user arguments for the program after parsing them from the provided file or list.
66/// `as_file` - The content of a flag with an optional path to a json containing the args as hex
67/// strings.
68/// `as_list` - The content of a flag with the direct numeric value of the list.
69/// Making sure not both are provided should be done by the cli.
70///
71/// This is required for running an executable in the Cairo-VM.
72pub fn user_args_from_flags(
73    as_file: Option<&PathBuf>,
74    as_list: &[BigInt],
75) -> anyhow::Result<Vec<Arg>> {
76    let user_args = if let Some(path) = as_file {
77        let as_vec: Vec<BigUintAsHex> = serde_json::from_reader(std::fs::File::open(path)?)
78            .with_context(|| "Failed reading args file.")?;
79        as_vec.into_iter().map(|v| Arg::Value(v.value.into())).collect()
80    } else {
81        as_list.iter().map(|v| Arg::Value(v.into())).collect()
82    };
83
84    Ok(user_args)
85}