hdp/preprocessor/compile/
module.rs1use crate::cairo_runner::dry_run::DryRunResult;
5use crate::cairo_runner::{cairo_dry_run, input::dry_run::DryRunnerProgramInput};
6use crate::constant::DRY_CAIRO_RUN_OUTPUT_FILE;
7use crate::primitives::processed_types::cairo_format;
8use crate::primitives::task::ExtendedModule;
9use crate::provider::key::categorize_fetch_keys;
10use crate::provider::traits::new_provider_from_config;
11use core::panic;
12
13use std::collections::{HashMap, HashSet};
14use std::path::PathBuf;
15use tracing::info;
16
17use super::config::CompilerConfig;
18use super::{Compilable, CompilationResult, CompileError};
19
20pub type ModuleVec = Vec<ExtendedModule>;
21
22impl Compilable for ModuleVec {
23 async fn compile(
24 &self,
25 compile_config: &CompilerConfig,
26 ) -> Result<CompilationResult, CompileError> {
27 info!("target task: {:#?}", self[0].task);
29 let dry_run_program_path = compile_config.dry_run_program_path.clone();
30
31 let dry_run_input =
33 generate_input(self.to_vec(), PathBuf::from(DRY_CAIRO_RUN_OUTPUT_FILE)).await?;
34 let input_string =
35 serde_json::to_string_pretty(&dry_run_input).expect("Failed to serialize module class");
36
37 info!("2. Running dry-run... ");
39 let dry_run_results: DryRunResult = cairo_dry_run(
40 dry_run_program_path,
41 input_string,
42 compile_config.save_fetch_keys_file.clone(),
43 )?;
44
45 if dry_run_results[0].program_hash != self[0].task.program_hash {
47 return Err(CompileError::ClassHashMismatch);
48 }
49
50 if dry_run_results.len() != 1 {
52 panic!("Multiple Modules are not supported");
53 }
54
55 let dry_run_module = dry_run_results.into_iter().next().unwrap();
57 let commit_results = vec![dry_run_module.result.into()];
58
59 let categorized_keys = categorize_fetch_keys(dry_run_module.fetch_keys);
61
62 let mut accounts_map = HashMap::new();
64 let mut storages_map = HashMap::new();
65 let mut transactions_map = HashMap::new();
66 let mut transaction_receipts_map = HashMap::new();
67 let mut mmr_header_map = HashMap::new();
68
69 info!("3. Fetching proofs from provider...");
70 for (chain_id, keys) in categorized_keys {
72 info!("target provider chain id: {}", chain_id);
73 let target_provider_config = compile_config
74 .provider_config
75 .get(&chain_id)
76 .expect("target task's chain had not been configured.");
77 let provider = new_provider_from_config(target_provider_config);
78
79 let results = provider
81 .fetch_proofs_from_keys(keys)
82 .await?
83 .get_evm_proofs()
84 .unwrap();
85
86 mmr_header_map.insert(
88 chain_id.to_numeric_id(),
89 HashSet::from_iter(results.mmr_with_headers.into_iter()),
90 );
91 accounts_map.insert(
92 chain_id.to_numeric_id(),
93 HashSet::from_iter(results.accounts.into_iter()),
94 );
95 storages_map.insert(
96 chain_id.to_numeric_id(),
97 HashSet::from_iter(results.storages.into_iter()),
98 );
99 transactions_map.insert(
100 chain_id.to_numeric_id(),
101 HashSet::from_iter(results.transactions.into_iter()),
102 );
103 transaction_receipts_map.insert(
104 chain_id.to_numeric_id(),
105 HashSet::from_iter(results.transaction_receipts.into_iter()),
106 );
107 }
108
109 let compiled_result = CompilationResult::new(
111 commit_results,
112 mmr_header_map,
113 accounts_map,
114 storages_map,
115 transactions_map,
116 transaction_receipts_map,
117 );
118 Ok(compiled_result)
119 }
120}
121
122async fn generate_input(
124 extended_modules: Vec<ExtendedModule>,
125 identified_keys_file: PathBuf,
126) -> Result<DryRunnerProgramInput, CompileError> {
127 let mut collected_results = Vec::new();
129 for module in extended_modules {
130 let input_module =
131 cairo_format::DryRunProcessedModule::new(module.task.inputs, module.module_class);
132 collected_results.push(input_module);
133 }
134
135 Ok(DryRunnerProgramInput::new(
136 identified_keys_file,
137 collected_results,
138 ))
139}