diff --git a/crates/blockifier/src/execution/errors.rs b/crates/blockifier/src/execution/errors.rs index 208daefccc..664633a3ee 100644 --- a/crates/blockifier/src/execution/errors.rs +++ b/crates/blockifier/src/execution/errors.rs @@ -16,6 +16,8 @@ use thiserror::Error; use crate::execution::entry_point::ConstructorContext; use crate::execution::stack_trace::Cairo1RevertStack; +#[cfg(feature = "cairo_native")] +use crate::execution::syscalls::hint_processor::SyscallExecutionError; use crate::state::errors::StateError; // TODO(AlonH, 21/12/2022): Implement Display for all types that appear in errors. @@ -91,6 +93,9 @@ pub enum EntryPointExecutionError { #[cfg(feature = "cairo_native")] #[error(transparent)] NativeUnexpectedError(#[from] NativeError), + #[cfg(feature = "cairo_native")] + #[error(transparent)] + NativeExecutionError(#[from] Box), #[error(transparent)] PostExecutionError(#[from] PostExecutionError), #[error(transparent)] diff --git a/crates/blockifier/src/execution/native/entry_point_execution.rs b/crates/blockifier/src/execution/native/entry_point_execution.rs index 2b1d22b19d..7b23d278ea 100644 --- a/crates/blockifier/src/execution/native/entry_point_execution.rs +++ b/crates/blockifier/src/execution/native/entry_point_execution.rs @@ -35,6 +35,11 @@ pub fn execute_entry_point_call( ); let call_result = execution_result.map_err(EntryPointExecutionError::NativeUnexpectedError)?; + + if let Some(error) = syscall_handler.unrecoverable_error { + return Err(EntryPointExecutionError::NativeExecutionError(Box::new(error))); + } + create_callinfo(call_result, syscall_handler) } diff --git a/crates/blockifier/src/execution/native/syscall_handler.rs b/crates/blockifier/src/execution/native/syscall_handler.rs index 3581496239..1525ac8e51 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -10,7 +10,6 @@ use cairo_native::starknet::{ SyscallResult, U256, }; -use cairo_native::starknet_stub::encode_str_as_felts; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; @@ -42,6 +41,9 @@ pub struct NativeSyscallHandler<'state> { // Additional information gathered during execution. pub read_values: Vec, pub accessed_keys: HashSet, + + // It is set if an unrecoverable error happens during syscall execution + pub unrecoverable_error: Option, } impl<'state> NativeSyscallHandler<'state> { @@ -62,6 +64,7 @@ impl<'state> NativeSyscallHandler<'state> { syscall_counter: SyscallCounter::new(), read_values: Vec::new(), accessed_keys: HashSet::new(), + unrecoverable_error: None, } } @@ -98,18 +101,6 @@ impl<'state> NativeSyscallHandler<'state> { Ok(retdata) } - fn handle_error( - &mut self, - _remaining_gas: &mut u128, - error: SyscallExecutionError, - ) -> Vec { - match error { - SyscallExecutionError::SyscallError { error_data } => error_data, - // unrecoverable errors are yet to be implemented - _ => encode_str_as_felts(&error.to_string()), - } - } - /// Handles all gas-related logics and additional metadata such as `SyscallCounter`. In native, /// we need to explicitly call this method at the beginning of each syscall. fn pre_execute_syscall( @@ -139,6 +130,21 @@ impl<'state> NativeSyscallHandler<'state> { Ok(()) } + + fn handle_error( + &mut self, + remaining_gas: &mut u128, + error: SyscallExecutionError, + ) -> Vec { + match error { + SyscallExecutionError::SyscallError { error_data } => error_data, + _ => { + self.unrecoverable_error = Some(error); + *remaining_gas = 0; + vec![] + } + } + } } impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {