Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Sandboxed Fallback #1215

Open
wants to merge 15 commits into
base: sandboxed_native
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading