use alloy::primitives::U256;
use std::collections::HashMap;
use std::path::PathBuf;
use tracing::info;
use crate::{
cairo_runner::{cairo_dry_run, dry_run::DryRunResult, input::dry_run::DryRunnerProgramInput},
constant::DRY_CAIRO_RUN_OUTPUT_FILE,
primitives::{
processed_types::{block_proofs::ProcessedBlockProofs, cairo_format},
task::ExtendedModule,
ChainId,
},
provider::{key::categorize_fetch_keys, traits::new_provider_from_config},
};
use super::compile::{config::CompilerConfig, CompileError};
#[derive(Debug, Default, PartialEq)]
pub struct ModuleCompilationResult {
pub task_results: Vec<U256>,
pub proofs: HashMap<ChainId, ProcessedBlockProofs>,
}
pub async fn module_compile(
task: ExtendedModule,
compile_config: &CompilerConfig,
) -> Result<ModuleCompilationResult, CompileError> {
info!("target task: {:#?}", task.task);
let dry_run_program_path = compile_config.dry_run_program_path.clone();
let dry_run_input = DryRunnerProgramInput::new(
PathBuf::from(DRY_CAIRO_RUN_OUTPUT_FILE),
vec![cairo_format::DryRunProcessedModule::new(
task.task.inputs,
task.module_class,
)],
);
let input_string =
serde_json::to_string_pretty(&dry_run_input).expect("Failed to serialize module class");
info!("2. Running dry-run... ");
let dry_run_results: DryRunResult = cairo_dry_run(
dry_run_program_path,
input_string,
compile_config.save_fetch_keys_file.clone(),
)?;
if dry_run_results[0].program_hash != task.task.program_hash {
return Err(CompileError::ClassHashMismatch);
}
if dry_run_results.len() != 1 {
panic!("Multiple Modules are not supported");
}
let dry_run_module = dry_run_results.into_iter().next().unwrap();
let task_results = vec![dry_run_module.result.into()];
let categorized_keys = categorize_fetch_keys(dry_run_module.fetch_keys);
let mut proofs_map: std::collections::HashMap<ChainId, ProcessedBlockProofs> = HashMap::new();
info!("3. Fetching proofs from provider...");
for (chain_id, keys) in categorized_keys {
info!("target provider chain id: {}", chain_id);
let target_provider_config = compile_config
.provider_config
.get(&chain_id)
.expect("target task's chain had not been configured.");
let provider = new_provider_from_config(target_provider_config);
let results = provider.fetch_proofs_from_keys(keys).await?;
proofs_map.insert(chain_id, results);
}
Ok(ModuleCompilationResult {
task_results,
proofs: proofs_map,
})
}