From 19b7323c6437cfdc56dbbbdd11c77a64990d26f3 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Mon, 29 Jan 2024 18:32:58 -0300 Subject: [PATCH 01/13] match test --- src/execution/execution_entry_point.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index 50e501f00..2c8fd741c 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -189,6 +189,9 @@ impl ExecutionEntryPoint { n_reverted_steps: 0, }) }, + Err(TransactionError::SandboxError(e)) => { + match e + } Err(e) => { if !support_reverted { state.apply_state_update(&StateDiff::from_cached_state( @@ -741,15 +744,14 @@ impl ExecutionEntryPoint { }; let value = if let Some(sandbox) = sandbox { - sandbox - .run_program( - *class_hash, - sierra_program.clone(), - self.calldata.clone(), - Some(self.initial_gas), - entry_point.function_idx, - &mut syscall_handler, - )? + sandbox.run_program( + *class_hash, + sierra_program.clone(), + self.calldata.clone(), + Some(self.initial_gas), + entry_point.function_idx, + &mut syscall_handler, + )? } else { let native_executor: NativeExecutor = { let mut cache = program_cache.borrow_mut(); From b62af5d6c30fac3b433e9d8569c531e8d311ee4d Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Mon, 29 Jan 2024 19:13:54 -0300 Subject: [PATCH 02/13] Changes Related to the Casm Enum --- src/execution/execution_entry_point.rs | 34 +++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index 2c8fd741c..afee6ab9a 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -157,7 +157,7 @@ impl ExecutionEntryPoint { }) } #[cfg(feature = "cairo-native")] - CompiledClass::Casm { + casm@CompiledClass::Casm { sierra: Some(sierra_program_and_entrypoints), .. } => { @@ -190,8 +190,36 @@ impl ExecutionEntryPoint { }) }, Err(TransactionError::SandboxError(e)) => { - match e - } + // See contract class + match self._execute( + state, + resources_manager, + block_context, + tx_execution_context, + contract_class, + class_hash, + support_reverted, + ) { + Ok(call_info) => Ok(ExecutionResult { + call_info: Some(call_info), + revert_error: None, + n_reverted_steps: 0, + }), + Err(e) => { + if !support_reverted { + return Err(e); + } + + let n_reverted_steps = + (max_steps as usize) - resources_manager.cairo_usage.n_steps; + Ok(ExecutionResult { + call_info: None, + revert_error: Some(e.to_string()), + n_reverted_steps, + }) + } + } + }, Err(e) => { if !support_reverted { state.apply_state_update(&StateDiff::from_cached_state( From ad260af1c6bb083966bef84bd7ffe4e67dfe4dc2 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Tue, 30 Jan 2024 10:29:54 -0300 Subject: [PATCH 03/13] Implement fallback --- src/execution/execution_entry_point.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index afee6ab9a..06a71b0cf 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -157,9 +157,9 @@ impl ExecutionEntryPoint { }) } #[cfg(feature = "cairo-native")] - casm@CompiledClass::Casm { + CompiledClass::Casm { sierra: Some(sierra_program_and_entrypoints), - .. + casm } => { let mut transactional_state = state.create_transactional()?; @@ -189,14 +189,13 @@ impl ExecutionEntryPoint { n_reverted_steps: 0, }) }, - Err(TransactionError::SandboxError(e)) => { - // See contract class + Err(TransactionError::SandboxError(_)) => { match self._execute( state, resources_manager, block_context, tx_execution_context, - contract_class, + casm, class_hash, support_reverted, ) { From 76a0a08ee881bc16836df450172047e1fde8a330 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Tue, 30 Jan 2024 11:30:25 -0300 Subject: [PATCH 04/13] Run cargo clippy and fmt --- src/execution/execution_entry_point.rs | 8 ++++---- src/transaction/error.rs | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index 06a71b0cf..738429b70 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -159,7 +159,7 @@ impl ExecutionEntryPoint { #[cfg(feature = "cairo-native")] CompiledClass::Casm { sierra: Some(sierra_program_and_entrypoints), - casm + casm, } => { let mut transactional_state = state.create_transactional()?; @@ -188,7 +188,7 @@ impl ExecutionEntryPoint { revert_error: None, n_reverted_steps: 0, }) - }, + } Err(TransactionError::SandboxError(_)) => { match self._execute( state, @@ -208,7 +208,7 @@ impl ExecutionEntryPoint { if !support_reverted { return Err(e); } - + let n_reverted_steps = (max_steps as usize) - resources_manager.cairo_usage.n_steps; Ok(ExecutionResult { @@ -218,7 +218,7 @@ impl ExecutionEntryPoint { }) } } - }, + } Err(e) => { if !support_reverted { state.apply_state_update(&StateDiff::from_cached_state( diff --git a/src/transaction/error.rs b/src/transaction/error.rs index 8b3e9569c..ad9139474 100644 --- a/src/transaction/error.rs +++ b/src/transaction/error.rs @@ -2,10 +2,13 @@ use crate::{ core::errors::{ contract_address_errors::ContractAddressError, hash_errors::HashError, state_errors::StateError, - }, definitions::transaction_type::TransactionType, execution::os_usage::OsResources, syscalls::syscall_handler_errors::SyscallHandlerError, utils::ClassHash + }, + definitions::transaction_type::TransactionType, + execution::os_usage::OsResources, + syscalls::syscall_handler_errors::SyscallHandlerError, + utils::ClassHash, }; - use cairo_vm::{ types::{ errors::{math_errors::MathError, program_errors::ProgramError}, @@ -164,5 +167,5 @@ pub enum TransactionError { CurrentAccountTxFieldsInNonV3TX, #[cfg(feature = "cairo-native")] #[error("sandbox error {0}")] - SandboxError(#[from] crate::sandboxing::SandboxError) + SandboxError(#[from] crate::sandboxing::SandboxError), } From 0fa98eb982807d432983c9801bbecf1ef8169442 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Wed, 31 Jan 2024 15:07:22 -0300 Subject: [PATCH 05/13] Add simple Test for Sandbox mode --- src/transaction/invoke_function.rs | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/transaction/invoke_function.rs b/src/transaction/invoke_function.rs index c38768de4..5f3621428 100644 --- a/src/transaction/invoke_function.rs +++ b/src/transaction/invoke_function.rs @@ -1683,4 +1683,96 @@ mod tests { Err(TransactionError::UnsupportedTxVersion(tx, ver, supp)) if tx == "Invoke" && ver == 2.into() && supp == vec![0, 1]); } + + #[test] + fn test_sandbox() { + use crate::sandboxing::IsolatedExecutor; + let internal_invoke_function = InvokeFunction { + contract_address: Address(0.into()), + entry_point_selector: Felt252::from_hex( + "0x112e35f48499939272000bd72eb840e502ca4c3aefa8800992e8defb746e0c9", + ) + .unwrap(), + entry_point_type: EntryPointType::External, + calldata: vec![1.into(), 1.into(), 10.into()], + tx_type: TransactionType::InvokeFunction, + version: 0.into(), + validate_entry_point_selector: 0.into(), + hash_value: 0.into(), + signature: Vec::new(), + account_tx_fields: Default::default(), + nonce: Some(0.into()), + skip_validation: false, + skip_execute: false, + skip_fee_transfer: false, + skip_nonce_check: false, + }; + + // Instantiate CachedState + let mut state_reader = InMemoryStateReader::default(); + // Set contract_class + let class_hash: ClassHash = ClassHash([1; 32]); + + let path = std::env::current_dir() + .unwrap() + .join("starknet_programs/fibonacci.json"); + dbg!("After, dir:{:?}", &path); + let contract_class = ContractClass::from_path(path).unwrap(); + // Set contract_state + let contract_address = Address(0.into()); + let nonce = Felt252::ZERO; + + state_reader + .address_to_class_hash_mut() + .insert(contract_address.clone(), class_hash); + state_reader + .address_to_nonce + .insert(contract_address, nonce); + + let mut state = CachedState::new( + Arc::new(state_reader), + Arc::new(PermanentContractClassCache::default()), + ); + + state + .set_contract_class( + &class_hash, + &CompiledClass::Deprecated(Arc::new(contract_class)), + ) + .unwrap(); + let path = std::env::current_dir() + .unwrap() + .join("target/debug/cairo-executor"); + + let isolated_executor = IsolatedExecutor::new(&path).unwrap(); + let sandbox = Some(&isolated_executor); + println!("After"); + + let result = internal_invoke_function + .execute( + &mut state, + &BlockContext::default(), + 0, + #[cfg(feature = "cairo-native")] + None, + #[cfg(feature = "cairo-native")] + sandbox, + ) + .unwrap(); + + assert_eq!(result.tx_type, Some(TransactionType::InvokeFunction)); + assert_eq!( + result.call_info.as_ref().unwrap().class_hash, + Some(class_hash) + ); + assert_eq!( + result.call_info.as_ref().unwrap().entry_point_selector, + Some(internal_invoke_function.entry_point_selector) + ); + assert_eq!( + result.call_info.as_ref().unwrap().calldata, + internal_invoke_function.calldata + ); + assert_eq!(result.call_info.unwrap().retdata, vec![Felt252::from(144)]); + } } From bb2bb2859140e64137bf71c8ea2561003f00be7d Mon Sep 17 00:00:00 2001 From: Gaston Date: Wed, 31 Jan 2024 15:30:45 -0300 Subject: [PATCH 06/13] Fix sandbox test --- src/transaction/invoke_function.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/transaction/invoke_function.rs b/src/transaction/invoke_function.rs index 5f3621428..13666725c 100644 --- a/src/transaction/invoke_function.rs +++ b/src/transaction/invoke_function.rs @@ -1685,8 +1685,7 @@ mod tests { } #[test] - fn test_sandbox() { - use crate::sandboxing::IsolatedExecutor; +fn test_sandbox() { let internal_invoke_function = InvokeFunction { contract_address: Address(0.into()), entry_point_selector: Felt252::from_hex( @@ -1712,12 +1711,7 @@ mod tests { let mut state_reader = InMemoryStateReader::default(); // Set contract_class let class_hash: ClassHash = ClassHash([1; 32]); - - let path = std::env::current_dir() - .unwrap() - .join("starknet_programs/fibonacci.json"); - dbg!("After, dir:{:?}", &path); - let contract_class = ContractClass::from_path(path).unwrap(); + let contract_class = ContractClass::from_path("starknet_programs/fibonacci.json").unwrap(); // Set contract_state let contract_address = Address(0.into()); let nonce = Felt252::ZERO; @@ -1740,13 +1734,6 @@ mod tests { &CompiledClass::Deprecated(Arc::new(contract_class)), ) .unwrap(); - let path = std::env::current_dir() - .unwrap() - .join("target/debug/cairo-executor"); - - let isolated_executor = IsolatedExecutor::new(&path).unwrap(); - let sandbox = Some(&isolated_executor); - println!("After"); let result = internal_invoke_function .execute( @@ -1756,7 +1743,7 @@ mod tests { #[cfg(feature = "cairo-native")] None, #[cfg(feature = "cairo-native")] - sandbox, + None, ) .unwrap(); From 45045b5c92e5aa847ec9bc9955e7ca0ba1d2cede Mon Sep 17 00:00:00 2001 From: Gaston Date: Wed, 31 Jan 2024 16:08:51 -0300 Subject: [PATCH 07/13] Add sandbox to sandbox test --- src/transaction/invoke_function.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/transaction/invoke_function.rs b/src/transaction/invoke_function.rs index 13666725c..c38a84684 100644 --- a/src/transaction/invoke_function.rs +++ b/src/transaction/invoke_function.rs @@ -1735,6 +1735,10 @@ fn test_sandbox() { ) .unwrap(); + let path = std::env::current_dir() + .unwrap() + .join("target/debug/cairo_native_executor"); + let sandbox = crate::sandboxing::IsolatedExecutor::new(&path).unwrap(); let result = internal_invoke_function .execute( &mut state, @@ -1743,7 +1747,7 @@ fn test_sandbox() { #[cfg(feature = "cairo-native")] None, #[cfg(feature = "cairo-native")] - None, + Some(&sandbox), ) .unwrap(); From 120ea44907f805e9fd57f4a8d205bbef0e415c42 Mon Sep 17 00:00:00 2001 From: Gaston Date: Thu, 1 Feb 2024 13:04:46 -0300 Subject: [PATCH 08/13] Change test from invoke_function to execution_entry_point --- src/execution/execution_entry_point.rs | 129 +++++++++++++++++++++++++ src/transaction/invoke_function.rs | 83 +--------------- 2 files changed, 130 insertions(+), 82 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index 738429b70..ca28d09ed 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -852,3 +852,132 @@ impl ExecutionEntryPoint { }) } } + + +#[cfg(test)] +mod tests { + use super::*; + #[test] +fn test_sandbox() { + // let internal_invoke_function = InvokeFunction { + // contract_address: Address(0.into()), + // entry_point_selector: Felt252::from_hex( + // "0x112e35f48499939272000bd72eb840e502ca4c3aefa8800992e8defb746e0c9", + // ) + // .unwrap(), + // entry_point_type: EntryPointType::External, + // calldata: vec![1.into(), 1.into(), 10.into()], + // tx_type: TransactionType::InvokeFunction, + // version: 0.into(), + // validate_entry_point_selector: 0.into(), + // hash_value: 0.into(), + // signature: Vec::new(), + // account_tx_fields: Default::default(), + // nonce: Some(0.into()), + // skip_validation: false, + // skip_execute: false, + // skip_fee_transfer: false, + // skip_nonce_check: false, + // }; + + let path = std::path::Path::new("starknet_programs/cairo2/fibonacci.cairo"); + + let casm_contract_class_data = std::fs::read_to_string(path.with_extension("casm")).unwrap(); + let sierra_contract_class_data = std::fs::read_to_string(path.with_extension("sierra")).unwrap(); + + let casm_contract_class: CasmContractClass = serde_json::from_str(&casm_contract_class_data).unwrap(); + let sierra_contract_class: cairo_lang_starknet::contract_class::ContractClass = + serde_json::from_str(&sierra_contract_class_data).unwrap(); + + let casm_contract_class = Arc::new(casm_contract_class); + let sierra_contract_class = Arc::new(( + sierra_contract_class.extract_sierra_program().unwrap(), + sierra_contract_class.entry_points_by_type, + )); + + + let mut state_reader = crate::state::in_memory_state_reader::InMemoryStateReader::default(); + let cache = crate::state::contract_class_cache::PermanentContractClassCache::default(); + + let class_hash = ClassHash([1; 32]); + let caller_address = Address(1.into()); + let callee_address = Address(1.into()); + + cache.set_contract_class( + class_hash, + CompiledClass::Casm { + casm: casm_contract_class, + sierra: Some(sierra_contract_class), + }, + ); + + state_reader + .address_to_class_hash_mut() + .insert(caller_address.clone(), class_hash); + state_reader + .address_to_nonce_mut() + .insert(callee_address.clone(), Felt252::default()); + + let mut state = CachedState::new(Arc::new(state_reader), Arc::new(cache)); + + state.cache_mut().storage_initial_values_mut().insert( + (Address(Felt252::ONE), crate::utils::felt_to_hash(&10.into()).0), + Felt252::from_bytes_be(&[5; 32]), + ); + + let class_hash = *state + .state_reader + .address_to_class_hash + .get(&caller_address) + .unwrap(); + + let mut block_context = BlockContext::default(); + block_context.block_info_mut().block_number = 30; + + let executor_path = std::env::var("CAIRO_NATIVE_EXECUTOR_PATH") + .map(std::path::PathBuf::from) + .unwrap_or_else(|_| { + std::env::current_dir() + .unwrap() + .join("target/debug/cairo_native_executor") + }); + let sandbox = IsolatedExecutor::new(executor_path.as_path()).unwrap(); + + let execution_result_native = ExecutionEntryPoint::new( + callee_address.clone(), + vec![1.into(), 1.into(), 10.into()], + Felt252::from_hex("0x112e35f48499939272000bd72eb840e502ca4c3aefa8800992e8defb746e0c9") + .unwrap(), + caller_address.clone(), + crate::EntryPointType::External, + Some(CallType::Delegate), + Some(class_hash), + u128::MAX, + ) + .execute( + &mut state, + &block_context, + &mut ExecutionResourcesManager::default(), + &mut TransactionExecutionContext::new( + Address(Felt252::default()), + Felt252::default(), + Vec::default(), + Default::default(), + 10.into(), + block_context.invoke_tx_max_n_steps(), + *crate::definitions::constants::TRANSACTION_VERSION, + ), + false, + block_context.invoke_tx_max_n_steps(), + None, + Some(&sandbox), + ).unwrap(); + + + // assert_eq!( + // execution_result_native.call_info.as_ref().unwrap().class_hash, + // Some(class_hash) + // ); + assert_eq!(execution_result_native.call_info.unwrap().retdata, vec![Felt252::from(144)]); + } +} \ No newline at end of file diff --git a/src/transaction/invoke_function.rs b/src/transaction/invoke_function.rs index c38a84684..8dfa7f461 100644 --- a/src/transaction/invoke_function.rs +++ b/src/transaction/invoke_function.rs @@ -1684,86 +1684,5 @@ mod tests { if tx == "Invoke" && ver == 2.into() && supp == vec![0, 1]); } - #[test] -fn test_sandbox() { - let internal_invoke_function = InvokeFunction { - contract_address: Address(0.into()), - entry_point_selector: Felt252::from_hex( - "0x112e35f48499939272000bd72eb840e502ca4c3aefa8800992e8defb746e0c9", - ) - .unwrap(), - entry_point_type: EntryPointType::External, - calldata: vec![1.into(), 1.into(), 10.into()], - tx_type: TransactionType::InvokeFunction, - version: 0.into(), - validate_entry_point_selector: 0.into(), - hash_value: 0.into(), - signature: Vec::new(), - account_tx_fields: Default::default(), - nonce: Some(0.into()), - skip_validation: false, - skip_execute: false, - skip_fee_transfer: false, - skip_nonce_check: false, - }; - - // Instantiate CachedState - let mut state_reader = InMemoryStateReader::default(); - // Set contract_class - let class_hash: ClassHash = ClassHash([1; 32]); - let contract_class = ContractClass::from_path("starknet_programs/fibonacci.json").unwrap(); - // Set contract_state - let contract_address = Address(0.into()); - let nonce = Felt252::ZERO; - - state_reader - .address_to_class_hash_mut() - .insert(contract_address.clone(), class_hash); - state_reader - .address_to_nonce - .insert(contract_address, nonce); - - let mut state = CachedState::new( - Arc::new(state_reader), - Arc::new(PermanentContractClassCache::default()), - ); - - state - .set_contract_class( - &class_hash, - &CompiledClass::Deprecated(Arc::new(contract_class)), - ) - .unwrap(); - - let path = std::env::current_dir() - .unwrap() - .join("target/debug/cairo_native_executor"); - let sandbox = crate::sandboxing::IsolatedExecutor::new(&path).unwrap(); - let result = internal_invoke_function - .execute( - &mut state, - &BlockContext::default(), - 0, - #[cfg(feature = "cairo-native")] - None, - #[cfg(feature = "cairo-native")] - Some(&sandbox), - ) - .unwrap(); - - assert_eq!(result.tx_type, Some(TransactionType::InvokeFunction)); - assert_eq!( - result.call_info.as_ref().unwrap().class_hash, - Some(class_hash) - ); - assert_eq!( - result.call_info.as_ref().unwrap().entry_point_selector, - Some(internal_invoke_function.entry_point_selector) - ); - assert_eq!( - result.call_info.as_ref().unwrap().calldata, - internal_invoke_function.calldata - ); - assert_eq!(result.call_info.unwrap().retdata, vec![Felt252::from(144)]); - } + } From be7da9fcfc9fa0ee0d86e1ca12c76137fb91f99b Mon Sep 17 00:00:00 2001 From: Gaston Date: Thu, 1 Feb 2024 13:57:46 -0300 Subject: [PATCH 09/13] Test fallback procedure killing sandbox --- src/execution/execution_entry_point.rs | 29 ++++++-------------------- src/sandboxing/mod.rs | 4 ++++ 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index ca28d09ed..d0fe3fc47 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -858,27 +858,7 @@ impl ExecutionEntryPoint { mod tests { use super::*; #[test] -fn test_sandbox() { - // let internal_invoke_function = InvokeFunction { - // contract_address: Address(0.into()), - // entry_point_selector: Felt252::from_hex( - // "0x112e35f48499939272000bd72eb840e502ca4c3aefa8800992e8defb746e0c9", - // ) - // .unwrap(), - // entry_point_type: EntryPointType::External, - // calldata: vec![1.into(), 1.into(), 10.into()], - // tx_type: TransactionType::InvokeFunction, - // version: 0.into(), - // validate_entry_point_selector: 0.into(), - // hash_value: 0.into(), - // signature: Vec::new(), - // account_tx_fields: Default::default(), - // nonce: Some(0.into()), - // skip_validation: false, - // skip_execute: false, - // skip_fee_transfer: false, - // skip_nonce_check: false, - // }; +fn fallback_procedure_sandbox_kill_test() { let path = std::path::Path::new("starknet_programs/cairo2/fibonacci.cairo"); @@ -941,11 +921,12 @@ fn test_sandbox() { .unwrap() .join("target/debug/cairo_native_executor") }); - let sandbox = IsolatedExecutor::new(executor_path.as_path()).unwrap(); + let mut sandbox = IsolatedExecutor::new(executor_path.as_path()).unwrap(); + sandbox.kill(); let execution_result_native = ExecutionEntryPoint::new( callee_address.clone(), - vec![1.into(), 1.into(), 10.into()], + vec![1.into(), 1.into(), 11.into()], Felt252::from_hex("0x112e35f48499939272000bd72eb840e502ca4c3aefa8800992e8defb746e0c9") .unwrap(), caller_address.clone(), @@ -978,6 +959,8 @@ fn test_sandbox() { // execution_result_native.call_info.as_ref().unwrap().class_hash, // Some(class_hash) // ); + println!("{}", execution_result_native.call_info.clone().unwrap().retdata.first().unwrap().to_bigint()); + println!("{}",Felt252::from(144).to_bigint()); assert_eq!(execution_result_native.call_info.unwrap().retdata, vec![Felt252::from(144)]); } } \ No newline at end of file diff --git a/src/sandboxing/mod.rs b/src/sandboxing/mod.rs index 408b4a17d..9f029f211 100644 --- a/src/sandboxing/mod.rs +++ b/src/sandboxing/mod.rs @@ -435,6 +435,10 @@ impl IsolatedExecutor { } } } + pub fn kill(&mut self) { + let _ = self.sender.send(Message::Kill.wrap().unwrap()); + let _ = self.proc.kill(); + } } impl Drop for IsolatedExecutor { From 0a48f3018cc51c6ffd8c99e91b19a63346d77c67 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Fri, 2 Feb 2024 12:41:43 -0300 Subject: [PATCH 10/13] Add test for Fallback Mechanism The test proposed kills `sandbox.proc` == `std::process:Child`. This kill makes the `sandbox` instance unusable. The current testbench checks with `lsof` command, using the `sandbox.proc`'s pid, comparing the outputs, before `sandbox.kill()` and after. A better way to test may be adding an extra field to the `ExecutionResult` struct: ```rust pub struct ExecutionResult { pub call_info: Option, pub revert_error: Option, pub native_or_casm: Option, // <- For example pub n_reverted_steps: usize, } ``` in order to return some info related to the environment used to run the contract whenever `execution_entry_point.rs::execute()` is used. --- src/execution/execution_entry_point.rs | 82 ++++++++++++++++---------- src/transaction/invoke_function.rs | 2 - 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index d0fe3fc47..896add6b1 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -189,7 +189,7 @@ impl ExecutionEntryPoint { n_reverted_steps: 0, }) } - Err(TransactionError::SandboxError(_)) => { + Err(TransactionError::SandboxError(_e)) => { match self._execute( state, resources_manager, @@ -853,19 +853,22 @@ impl ExecutionEntryPoint { } } - #[cfg(test)] mod tests { + use std::process::Command; + use super::*; #[test] -fn fallback_procedure_sandbox_kill_test() { - + fn fallback_procedure_sandbox_kill_test() { let path = std::path::Path::new("starknet_programs/cairo2/fibonacci.cairo"); - let casm_contract_class_data = std::fs::read_to_string(path.with_extension("casm")).unwrap(); - let sierra_contract_class_data = std::fs::read_to_string(path.with_extension("sierra")).unwrap(); + let casm_contract_class_data = + std::fs::read_to_string(path.with_extension("casm")).unwrap(); + let sierra_contract_class_data = + std::fs::read_to_string(path.with_extension("sierra")).unwrap(); - let casm_contract_class: CasmContractClass = serde_json::from_str(&casm_contract_class_data).unwrap(); + let casm_contract_class: CasmContractClass = + serde_json::from_str(&casm_contract_class_data).unwrap(); let sierra_contract_class: cairo_lang_starknet::contract_class::ContractClass = serde_json::from_str(&sierra_contract_class_data).unwrap(); @@ -875,7 +878,6 @@ fn fallback_procedure_sandbox_kill_test() { sierra_contract_class.entry_points_by_type, )); - let mut state_reader = crate::state::in_memory_state_reader::InMemoryStateReader::default(); let cache = crate::state::contract_class_cache::PermanentContractClassCache::default(); @@ -890,38 +892,50 @@ fn fallback_procedure_sandbox_kill_test() { sierra: Some(sierra_contract_class), }, ); - + state_reader .address_to_class_hash_mut() .insert(caller_address.clone(), class_hash); state_reader .address_to_nonce_mut() .insert(callee_address.clone(), Felt252::default()); - + let mut state = CachedState::new(Arc::new(state_reader), Arc::new(cache)); - + state.cache_mut().storage_initial_values_mut().insert( - (Address(Felt252::ONE), crate::utils::felt_to_hash(&10.into()).0), + ( + Address(Felt252::ONE), + crate::utils::felt_to_hash(&10.into()).0, + ), Felt252::from_bytes_be(&[5; 32]), ); - + let class_hash = *state .state_reader .address_to_class_hash .get(&caller_address) .unwrap(); - + let mut block_context = BlockContext::default(); block_context.block_info_mut().block_number = 30; let executor_path = std::env::var("CAIRO_NATIVE_EXECUTOR_PATH") - .map(std::path::PathBuf::from) - .unwrap_or_else(|_| { - std::env::current_dir() - .unwrap() - .join("target/debug/cairo_native_executor") - }); + .map(std::path::PathBuf::from) + .unwrap_or_else(|_| { + std::env::current_dir() + .unwrap() + .join("target/debug/cairo_native_executor") + }); let mut sandbox = IsolatedExecutor::new(executor_path.as_path()).unwrap(); + + let check_sandbox_pid_before = Command::new("lsof") + .arg("-p") + .arg(sandbox.proc.id().to_string()) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .output() + .unwrap(); + sandbox.kill(); let execution_result_native = ExecutionEntryPoint::new( @@ -952,15 +966,23 @@ fn fallback_procedure_sandbox_kill_test() { block_context.invoke_tx_max_n_steps(), None, Some(&sandbox), - ).unwrap(); - + ) + .unwrap(); - // assert_eq!( - // execution_result_native.call_info.as_ref().unwrap().class_hash, - // Some(class_hash) - // ); - println!("{}", execution_result_native.call_info.clone().unwrap().retdata.first().unwrap().to_bigint()); - println!("{}",Felt252::from(144).to_bigint()); - assert_eq!(execution_result_native.call_info.unwrap().retdata, vec![Felt252::from(144)]); + let check_sandbox_pid_after: std::process::Output = Command::new("lsof") + .arg("-p") + .arg(sandbox.proc.id().to_string()) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .output() + .unwrap(); + assert_ne!( + String::from_utf8_lossy(&check_sandbox_pid_after.stderr), + String::from_utf8_lossy(&check_sandbox_pid_before.stdout) + ); + assert_eq!( + execution_result_native.call_info.unwrap().retdata, + vec![Felt252::from(144)] + ); } -} \ No newline at end of file +} diff --git a/src/transaction/invoke_function.rs b/src/transaction/invoke_function.rs index 8dfa7f461..c38768de4 100644 --- a/src/transaction/invoke_function.rs +++ b/src/transaction/invoke_function.rs @@ -1683,6 +1683,4 @@ mod tests { Err(TransactionError::UnsupportedTxVersion(tx, ver, supp)) if tx == "Invoke" && ver == 2.into() && supp == vec![0, 1]); } - - } From 07dd6cc57a0d9211b0a2779c4e89f095dc89ebc2 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Mon, 5 Feb 2024 10:17:42 -0300 Subject: [PATCH 11/13] Add cairo-native feature to test --- src/execution/execution_entry_point.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/execution/execution_entry_point.rs b/src/execution/execution_entry_point.rs index 896add6b1..7b7e993a7 100644 --- a/src/execution/execution_entry_point.rs +++ b/src/execution/execution_entry_point.rs @@ -854,6 +854,7 @@ impl ExecutionEntryPoint { } #[cfg(test)] +#[cfg(feature = "cairo-native")] mod tests { use std::process::Command; From 4c300e3e88607e87b5c1bf22ee4739e1e71b25c9 Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Tue, 6 Feb 2024 10:17:43 -0300 Subject: [PATCH 12/13] Change the function IsolatedExecutor::kill() from [pub] to [pub(crate)] --- src/sandboxing/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sandboxing/mod.rs b/src/sandboxing/mod.rs index 08336a861..0c506d48a 100644 --- a/src/sandboxing/mod.rs +++ b/src/sandboxing/mod.rs @@ -433,7 +433,7 @@ impl IsolatedExecutor { } } } - pub fn kill(&mut self) { + pub(crate) fn kill(&mut self) { let _ = self.sender.send(Message::Kill.wrap().unwrap()); let _ = self.proc.kill(); } From 416f8b6379ffbdc1e56635223f3d7332facccecd Mon Sep 17 00:00:00 2001 From: fborello-lambda Date: Tue, 6 Feb 2024 11:46:11 -0300 Subject: [PATCH 13/13] Add #[cfg(test)] to pub(crate) fn kill() --- src/sandboxing/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sandboxing/mod.rs b/src/sandboxing/mod.rs index 0c506d48a..b52f42e06 100644 --- a/src/sandboxing/mod.rs +++ b/src/sandboxing/mod.rs @@ -433,6 +433,8 @@ impl IsolatedExecutor { } } } + + #[cfg(test)] pub(crate) fn kill(&mut self) { let _ = self.sender.send(Message::Kill.wrap().unwrap()); let _ = self.proc.kill();