diff --git a/Cargo.lock b/Cargo.lock index 84248d0fc..bc67a8024 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1320,7 +1320,7 @@ dependencies = [ [[package]] name = "cairo-native" version = "0.1.0" -source = "git+https://github.com/lambdaclass/cairo_native?rev=f668096bd6382066392cd563873dda5e7885a388#f668096bd6382066392cd563873dda5e7885a388" +source = "git+https://github.com/lambdaclass/cairo_native?rev=9b669cf8fefbff5e3dced87b70a5d957bdc3e85c#9b669cf8fefbff5e3dced87b70a5d957bdc3e85c" dependencies = [ "bumpalo", "cairo-felt", @@ -1338,15 +1338,15 @@ dependencies = [ "cairo-native-runtime", "cc", "clap", + "educe", "id-arena", - "itertools 0.11.0", + "itertools 0.12.0", "lazy_static", "libc", "melior", "mlir-sys", "num-bigint", - "serde", - "serde_json", + "num-traits 0.2.17", "thiserror", "tracing", "tracing-subscriber", @@ -1355,7 +1355,7 @@ dependencies = [ [[package]] name = "cairo-native-runtime" version = "0.1.0" -source = "git+https://github.com/lambdaclass/cairo_native?rev=f668096bd6382066392cd563873dda5e7885a388#f668096bd6382066392cd563873dda5e7885a388" +source = "git+https://github.com/lambdaclass/cairo_native?rev=9b669cf8fefbff5e3dced87b70a5d957bdc3e85c#9b669cf8fefbff5e3dced87b70a5d957bdc3e85c" dependencies = [ "cairo-felt", "cairo-lang-runner", @@ -1969,6 +1969,18 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +[[package]] +name = "educe" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "either" version = "1.9.0" @@ -2005,6 +2017,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" +[[package]] +name = "enum-ordinalize" +version = "3.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf1fa3f06bbff1ea5b1a9c7b14aa992a39657db60a2759457328d7e058f49ee" +dependencies = [ + "num-bigint", + "num-traits 0.2.17", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -2682,6 +2707,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" diff --git a/Cargo.toml b/Cargo.toml index e861e837d..502c93eaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ cairo-lang-runner = { workspace = true } cairo-lang-sierra = { workspace = true } cairo-lang-starknet = { workspace = true } cairo-lang-utils = { workspace = true } -cairo-native = { git = "https://github.com/lambdaclass/cairo_native", rev = "f668096bd6382066392cd563873dda5e7885a388", optional = true } +cairo-native = { git = "https://github.com/lambdaclass/cairo_native", rev = "9b669cf8fefbff5e3dced87b70a5d957bdc3e85c", optional = true } cairo-vm = { workspace = true } flate2 = "1.0.25" getset = "0.1.2" diff --git a/bench/internals.rs b/bench/internals.rs index 40bcb8211..c5f500d3e 100644 --- a/bench/internals.rs +++ b/bench/internals.rs @@ -1,6 +1,8 @@ #![deny(warnings)] +#[cfg(feature = "cairo-native")] use cairo_native::cache::ProgramCache; + use cairo_vm::felt; use felt::{felt_str, Felt252}; use lazy_static::lazy_static; @@ -56,14 +58,16 @@ fn scope(f: impl FnOnce() -> T) -> T { // FnOnce calls for each test, that are merged in the flamegraph. fn main() { #[cfg(feature = "cairo-native")] - let program_cache = Rc::new(RefCell::new(ProgramCache::new( - starknet_in_rust::utils::get_native_context(), - ))); + { + let program_cache = Rc::new(RefCell::new(ProgramCache::new( + starknet_in_rust::utils::get_native_context(), + ))); - deploy_account(program_cache.clone()); - declare(program_cache.clone()); - deploy(program_cache.clone()); - invoke(program_cache.clone()); + deploy_account(program_cache.clone()); + declare(program_cache.clone()); + deploy(program_cache.clone()); + invoke(program_cache.clone()); + } // The black_box ensures there's no tail-call optimization. // If not, the flamegraph ends up less nice. @@ -71,7 +75,7 @@ fn main() { } #[inline(never)] -fn deploy_account( +pub fn deploy_account( #[cfg(feature = "cairo-native")] program_cache: Rc>>, ) { const RUNS: usize = 500; @@ -120,7 +124,9 @@ fn deploy_account( } #[inline(never)] -fn declare(#[cfg(feature = "cairo-native")] program_cache: Rc>>) { +pub fn declare( + #[cfg(feature = "cairo-native")] program_cache: Rc>>, +) { const RUNS: usize = 5; let state_reader = Arc::new(InMemoryStateReader::default()); @@ -160,7 +166,9 @@ fn declare(#[cfg(feature = "cairo-native")] program_cache: Rc>>) { +pub fn deploy( + #[cfg(feature = "cairo-native")] program_cache: Rc>>, +) { const RUNS: usize = 8; let state_reader = Arc::new(InMemoryStateReader::default()); @@ -206,7 +214,9 @@ fn deploy(#[cfg(feature = "cairo-native")] program_cache: Rc>>) { +pub fn invoke( + #[cfg(feature = "cairo-native")] program_cache: Rc>>, +) { const RUNS: usize = 100; let state_reader = Arc::new(InMemoryStateReader::default()); diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index c98e2351d..a76840cde 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -51,13 +51,7 @@ use std::sync::Arc; #[cfg(feature = "cairo-native")] use { crate::syscalls::native_syscall_handler::NativeSyscallHandler, - cairo_native::{ - execution_result::NativeExecutionResult, metadata::syscall_handler::SyscallHandlerMeta, - utils::felt252_bigint, - }, - core::cell::RefCell, - serde_json::Value, - std::rc::Rc, + cairo_native::metadata::syscall_handler::SyscallHandlerMeta, core::cell::RefCell, std::rc::Rc, }; #[derive(Debug, Default)] @@ -671,14 +665,11 @@ impl ExecutionEntryPoint { class_hash: &ClassHash, program_cache: Rc>>, ) -> Result { + use cairo_native::values::JITValue; + use crate::{ syscalls::business_logic_syscall_handler::SYSCALL_BASE, utils::NATIVE_CONTEXT, }; - use cairo_lang_sierra::{ - extensions::core::{CoreLibfunc, CoreType, CoreTypeConcrete}, - program_registry::ProgramRegistry, - }; - use serde_json::json; // Ensure we're using the global context, if initialized. if let Some(native_context) = NATIVE_CONTEXT.get() { @@ -706,9 +697,6 @@ impl ExecutionEntryPoint { .unwrap(), }; - let program_registry: ProgramRegistry = - ProgramRegistry::new(sierra_program).unwrap(); - let native_executor = { let mut cache = program_cache.borrow_mut(); if let Some(executor) = cache.get(*class_hash) { @@ -744,85 +732,26 @@ impl ExecutionEntryPoint { .get_module_mut() .insert_metadata(SyscallHandlerMeta::new(&mut syscall_handler)); - let syscall_addr = native_executor - .borrow() - .get_module() - .get_metadata::() - .unwrap() - .as_ptr() - .as_ptr() as *const () as usize; - let entry_point_fn = &sierra_program .funcs .iter() .find(|x| x.id.id == (entry_point.function_idx as u64)) .unwrap(); - let ret_types: Vec<&CoreTypeConcrete> = entry_point_fn - .signature - .ret_types - .iter() - .map(|x| program_registry.get_type(x).unwrap()) - .collect(); - let entry_point_id = &entry_point_fn.id; - let required_init_gas = native_executor - .borrow() - .get_module() - .get_required_init_gas(entry_point_id); + let entry_point_id = &entry_point_fn.id; let calldata: Vec<_> = self .calldata .iter() - .map(|felt| felt252_bigint(felt.to_bigint())) - .collect(); - - /* - Below we construct `params`, the Serde value that MLIR expects. It consists of the following: - - - One `null` value for each builtin that is going to be used. - - The maximum amout of gas allowed by the call. - - `syscall_addr`, the address of the syscall handler. - - `calldata`, an array of Felt arguments to the method being called. - */ - - let wrapped_calldata = vec![calldata]; - let params: Vec = sierra_program.funcs[entry_point_id.id as usize] - .params - .iter() - .map(|param| { - match param.ty.debug_name.as_ref().unwrap().as_str() { - "GasBuiltin" => { - json!(self.initial_gas) - } - "Pedersen" | "SegmentArena" | "RangeCheck" | "Bitwise" | "Poseidon" => { - json!(null) - } - "System" => { - json!(syscall_addr) - } - // calldata - "core::array::Span::" => json!(wrapped_calldata), - x => { - unimplemented!("unhandled param type: {:?}", x); - } - } - }) + .cloned() + .map(JITValue::Felt252) .collect(); - let mut writer: Vec = Vec::new(); - let returns = &mut serde_json::Serializer::new(&mut writer); - - native_executor + let value = native_executor .borrow() - .execute(entry_point_id, json!(params), returns, required_init_gas) + .execute_contract(entry_point_id, &calldata, self.initial_gas) .map_err(|e| TransactionError::CustomError(format!("cairo-native error: {:?}", e)))?; - let value = NativeExecutionResult::deserialize_from_ret_types( - &mut serde_json::Deserializer::from_slice(&writer), - &ret_types, - ) - .expect("failed to serialize starknet execution result"); - Ok(CallInfo { caller_address: self.caller_address.clone(), call_type: Some(self.call_type.clone()), diff --git a/tests/cairo_native.rs b/tests/cairo_native.rs index 504e15cc7..c1a90b514 100644 --- a/tests/cairo_native.rs +++ b/tests/cairo_native.rs @@ -896,7 +896,7 @@ fn replace_class_test() { let casm_replace_selector = &casm_entrypoints.external.get(0).unwrap().selector; // Create state reader with class hash data - let mut contract_class_cache = PermanentContractClassCache::default(); + let contract_class_cache = PermanentContractClassCache::default(); let address = Address(1111.into()); let casm_address = Address(2222.into()); @@ -906,7 +906,7 @@ fn replace_class_test() { let nonce = Felt252::zero(); - insert_sierra_class_into_cache(&mut contract_class_cache, CLASS_HASH_A, contract_class_a); + insert_sierra_class_into_cache(&contract_class_cache, CLASS_HASH_A, contract_class_a); contract_class_cache.set_contract_class( CASM_CLASS_HASH_A, @@ -1066,7 +1066,7 @@ fn replace_class_contract_call() { // Create state reader with class hash data let contract_class_cache = PermanentContractClassCache::default(); - let mut native_contract_class_cache = PermanentContractClassCache::default(); + let native_contract_class_cache = PermanentContractClassCache::default(); let address = Address(Felt252::one()); let class_hash_a: ClassHash = ClassHash([1; 32]); @@ -1076,11 +1076,7 @@ fn replace_class_contract_call() { class_hash_a, CompiledClass::Casm(Arc::new(casm_contract_class_a)), ); - insert_sierra_class_into_cache( - &mut native_contract_class_cache, - class_hash_a, - sierra_class_a, - ); + insert_sierra_class_into_cache(&native_contract_class_cache, class_hash_a, sierra_class_a); let mut state_reader = InMemoryStateReader::default(); state_reader @@ -1114,11 +1110,7 @@ fn replace_class_contract_call() { class_hash_b, CompiledClass::Casm(Arc::new(contract_class_b)), ); - insert_sierra_class_into_cache( - &mut native_contract_class_cache, - class_hash_b, - sierra_class_b, - ); + insert_sierra_class_into_cache(&native_contract_class_cache, class_hash_b, sierra_class_b); // SET GET_NUMBER_WRAPPER @@ -1151,7 +1143,7 @@ fn replace_class_contract_call() { CompiledClass::Casm(Arc::new(wrapper_contract_class)), ); insert_sierra_class_into_cache( - &mut native_contract_class_cache, + &native_contract_class_cache, wrapper_class_hash, wrapper_sierra_class, ); @@ -1776,14 +1768,14 @@ fn get_execution_info_test() { let selector = &entrypoints.external.get(0).unwrap().selector; // Create state reader with class hash data - let mut contract_class_cache = PermanentContractClassCache::default(); + let contract_class_cache = PermanentContractClassCache::default(); // Contract data let address = Address(1111.into()); let class_hash: ClassHash = ClassHash([1; 32]); let nonce = Felt252::zero(); - insert_sierra_class_into_cache(&mut contract_class_cache, class_hash, sierra_contract_class); + insert_sierra_class_into_cache(&contract_class_cache, class_hash, sierra_contract_class); let mut state_reader = InMemoryStateReader::default();