use cairo_lang_sierra::program::Program;
use cairo_lang_starknet_classes::compiler_version::VersionId;
use cairo_lang_starknet_classes::contract_class::ContractEntryPoints;
use starknet_types_core::felt::Felt;
use std::sync::Arc;
use crate::error::{Error, Result};
use crate::execution_result::ContractExecutionResult;
use crate::starknet::StarknetSyscallHandler;
use crate::utils::BuiltinCosts;
#[derive(Debug, Clone)]
pub struct EmuContractExecutor {
pub program: Arc<Program>,
pub entry_points: ContractEntryPoints,
pub sierra_version: VersionId,
}
impl EmuContractExecutor {
pub fn run(
&self,
selector: Felt,
args: &[Felt],
gas: u64,
builtin_costs: Option<BuiltinCosts>,
mut syscall_handler: impl StarknetSyscallHandler,
) -> Result<ContractExecutionResult> {
let result = sierra_emu::VirtualMachine::run_contract(
Arc::clone(&self.program),
&self.entry_points,
self.sierra_version,
selector,
gas,
args.to_vec(),
builtin_costs.map(convert_builtin_costs),
&mut syscall_handler,
)
.ok_or_else(|| {
Error::UnexpectedValue("sierra-emu VM produced no final state".to_string())
})?;
Ok(ContractExecutionResult {
remaining_gas: result.remaining_gas,
failure_flag: result.failure_flag,
return_values: result.return_values,
error_msg: result.error_msg,
builtin_stats: Default::default(),
})
}
}
fn convert_builtin_costs(builtin_costs: BuiltinCosts) -> sierra_emu::BuiltinCosts {
sierra_emu::BuiltinCosts {
r#const: builtin_costs.r#const,
pedersen: builtin_costs.pedersen,
bitwise: builtin_costs.bitwise,
ecop: builtin_costs.ecop,
poseidon: builtin_costs.poseidon,
add_mod: builtin_costs.add_mod,
mul_mod: builtin_costs.mul_mod,
blake: builtin_costs.blake,
}
}