Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.
Open
167 changes: 166 additions & 1 deletion src/execution/execution_entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl ExecutionEntryPoint {
#[cfg(feature = "cairo-native")]
CompiledClass::Casm {
sierra: Some(sierra_program_and_entrypoints),
..
casm,
} => {
let mut transactional_state = state.create_transactional()?;

Expand Down Expand Up @@ -189,6 +189,36 @@ impl ExecutionEntryPoint {
n_reverted_steps: 0,
})
}
Err(TransactionError::SandboxError(_e)) => {
match self._execute(
state,
resources_manager,
block_context,
tx_execution_context,
casm,
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(
Expand Down Expand Up @@ -822,3 +852,138 @@ impl ExecutionEntryPoint {
})
}
}

#[cfg(test)]
#[cfg(feature = "cairo-native")]
mod tests {
use std::process::Command;

use super::*;
#[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: 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 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(
callee_address.clone(),
vec![1.into(), 1.into(), 11.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();

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)]
);
}
}
6 changes: 6 additions & 0 deletions src/sandboxing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,12 @@ impl IsolatedExecutor {
}
}
}

#[cfg(test)]
pub(crate) fn kill(&mut self) {
let _ = self.sender.send(Message::Kill.wrap().unwrap());
let _ = self.proc.kill();
}
}

impl Drop for IsolatedExecutor {
Expand Down