Skip to content

Commit

Permalink
feat(blockifier): add unrecoverable error handling for native
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-pino committed Nov 11, 2024
1 parent 8313167 commit db04179
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 13 deletions.
5 changes: 5 additions & 0 deletions crates/blockifier/src/execution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<SyscallExecutionError>),
#[error(transparent)]
PostExecutionError(#[from] PostExecutionError),
#[error(transparent)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
32 changes: 19 additions & 13 deletions crates/blockifier/src/execution/native/syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -42,6 +41,9 @@ pub struct NativeSyscallHandler<'state> {
// Additional information gathered during execution.
pub read_values: Vec<Felt>,
pub accessed_keys: HashSet<StorageKey, RandomState>,

// It is set if an unrecoverable error happens during syscall execution
pub unrecoverable_error: Option<SyscallExecutionError>,
}

impl<'state> NativeSyscallHandler<'state> {
Expand All @@ -62,6 +64,7 @@ impl<'state> NativeSyscallHandler<'state> {
syscall_counter: SyscallCounter::new(),
read_values: Vec::new(),
accessed_keys: HashSet::new(),
unrecoverable_error: None,
}
}

Expand Down Expand Up @@ -98,18 +101,6 @@ impl<'state> NativeSyscallHandler<'state> {
Ok(retdata)
}

fn handle_error(
&mut self,
_remaining_gas: &mut u128,
error: SyscallExecutionError,
) -> Vec<Felt> {
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(
Expand Down Expand Up @@ -139,6 +130,21 @@ impl<'state> NativeSyscallHandler<'state> {

Ok(())
}

fn handle_error(
&mut self,
remaining_gas: &mut u128,
error: SyscallExecutionError,
) -> Vec<Felt> {
match error {
SyscallExecutionError::SyscallError { error_data } => error_data,
_ => {
self.unrecoverable_error = Some(error);
*remaining_gas = 0;
vec![]
}
}
}
}

impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {
Expand Down

0 comments on commit db04179

Please sign in to comment.