Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): add ExecutableCallEntryPoint #3657

Merged
merged 1 commit into from
Jan 28, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use crate::execution::call_info::{CallExecution, CallInfo};
use crate::execution::contract_class::{CompiledClassV0, TrackedResource};
use crate::execution::deprecated_syscalls::hint_processor::DeprecatedSyscallHintProcessor;
use crate::execution::entry_point::{
CallEntryPoint,
EntryPointExecutionContext,
EntryPointExecutionResult,
ExecutableCallEntryPoint,
};
use crate::execution::errors::{PostExecutionError, PreExecutionError};
use crate::execution::execution_utils::{read_execution_retdata, Args, ReadOnlySegments};
Expand All @@ -42,7 +42,7 @@ pub const CAIRO0_BUILTINS_NAMES: [BuiltinName; 6] = [

/// Executes a specific call to a contract entry point and returns its output.
pub fn execute_entry_point_call(
call: CallEntryPoint,
call: ExecutableCallEntryPoint,
compiled_class: CompiledClassV0,
state: &mut dyn State,
context: &mut EntryPointExecutionContext,
Expand All @@ -65,7 +65,7 @@ pub fn execute_entry_point_call(
}

pub fn initialize_execution_context<'a>(
call: &CallEntryPoint,
call: &ExecutableCallEntryPoint,
compiled_class: CompiledClassV0,
state: &'a mut dyn State,
context: &'a mut EntryPointExecutionContext,
Expand Down Expand Up @@ -102,14 +102,14 @@ pub fn initialize_execution_context<'a>(
initial_syscall_ptr,
call.storage_address,
call.caller_address,
call.class_hash.expect("Class hash must be resolved prior to call execution."),
call.class_hash,
);

Ok(VmExecutionContext { runner, syscall_handler, initial_syscall_ptr, entry_point_pc })
}

pub fn resolve_entry_point_pc(
call: &CallEntryPoint,
call: &ExecutableCallEntryPoint,
compiled_class: &CompiledClassV0,
) -> Result<usize, PreExecutionError> {
if call.entry_point_type == EntryPointType::Constructor
Expand Down Expand Up @@ -157,7 +157,7 @@ pub fn resolve_entry_point_pc(
}

pub fn prepare_call_arguments(
call: &CallEntryPoint,
call: &ExecutableCallEntryPoint,
runner: &mut CairoRunner,
initial_syscall_ptr: Relocatable,
read_only_segments: &mut ReadOnlySegments,
Expand Down Expand Up @@ -218,7 +218,7 @@ pub fn run_entry_point(
pub fn finalize_execution(
mut runner: CairoRunner,
syscall_handler: DeprecatedSyscallHintProcessor<'_>,
call: CallEntryPoint,
call: ExecutableCallEntryPoint,
implicit_args: Vec<MaybeRelocatable>,
n_total_args: usize,
) -> Result<CallInfo, PostExecutionError> {
Expand Down Expand Up @@ -258,7 +258,7 @@ pub fn finalize_execution(
+ &CallInfo::summarize_vm_resources(syscall_handler.inner_calls.iter());

Ok(CallInfo {
call,
call: call.into(),
execution: CallExecution {
retdata: read_execution_retdata(&runner, retdata_size, &retdata_ptr)?,
events: syscall_handler.events,
Expand Down
53 changes: 48 additions & 5 deletions crates/blockifier/src/execution/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,14 @@ pub enum CallType {
/// Represents a call to an entry point of a Starknet contract.
#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))]
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
pub struct CallEntryPoint {
// The class hash is not given if it can be deduced from the storage address.
// It is resolved prior to entry point's execution.
pub class_hash: Option<ClassHash>,
pub struct CallEntryPointVariant<TClassHash> {
/// The class hash of the entry point.
/// The type is `ClassHash` in the case of [ExecutableCallEntryPoint] and `Option<ClassHash>`
/// in the case of [CallEntryPoint].
///
/// The class hash is not given if it can be deduced from the storage address.
/// It is resolved prior to entry point's execution.
pub class_hash: TClassHash,
// Optional, since there is no address to the code implementation in a library call.
// and for outermost calls (triggered by the transaction itself).
// TODO(AlonH): BACKWARD-COMPATIBILITY.
Expand All @@ -114,6 +118,25 @@ pub struct CallEntryPoint {
pub initial_gas: u64,
}

pub type CallEntryPoint = CallEntryPointVariant<Option<ClassHash>>;
pub type ExecutableCallEntryPoint = CallEntryPointVariant<ClassHash>;

impl From<ExecutableCallEntryPoint> for CallEntryPoint {
fn from(call: ExecutableCallEntryPoint) -> Self {
Self {
class_hash: Some(call.class_hash),
code_address: call.code_address,
entry_point_type: call.entry_point_type,
entry_point_selector: call.entry_point_selector,
calldata: call.calldata,
storage_address: call.storage_address,
caller_address: call.caller_address,
call_type: call.call_type,
initial_gas: call.initial_gas,
}
}
}

impl CallEntryPoint {
pub fn execute(
mut self,
Expand Down Expand Up @@ -159,7 +182,13 @@ impl CallEntryPoint {
));

// This is the last operation of this function.
execute_entry_point_call_wrapper(self, compiled_class, state, context, remaining_gas)
execute_entry_point_call_wrapper(
self.into_executable(class_hash),
compiled_class,
state,
context,
remaining_gas,
)
}

/// Similar to `execute`, but returns an error if the outer call is reverted.
Expand Down Expand Up @@ -200,6 +229,20 @@ impl CallEntryPoint {
Ok(())
}
}

fn into_executable(self, class_hash: ClassHash) -> ExecutableCallEntryPoint {
ExecutableCallEntryPoint {
class_hash,
code_address: self.code_address,
entry_point_type: self.entry_point_type,
entry_point_selector: self.entry_point_selector,
calldata: self.calldata,
storage_address: self.storage_address,
caller_address: self.caller_address,
call_type: self.call_type,
initial_gas: self.initial_gas,
}
}
}

pub struct ConstructorContext {
Expand Down
19 changes: 12 additions & 7 deletions crates/blockifier/src/execution/execution_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ use crate::execution::call_info::{CallExecution, CallInfo, Retdata};
use crate::execution::contract_class::{RunnableCompiledClass, TrackedResource};
use crate::execution::entry_point::{
execute_constructor_entry_point,
CallEntryPoint,
ConstructorContext,
ConstructorEntryPointExecutionResult,
EntryPointExecutionContext,
EntryPointExecutionResult,
ExecutableCallEntryPoint,
};
use crate::execution::errors::{
ConstructorEntryPointExecutionError,
Expand All @@ -51,7 +51,7 @@ pub const SEGMENT_ARENA_BUILTIN_SIZE: usize = 3;

/// A wrapper for execute_entry_point_call that performs pre and post-processing.
pub fn execute_entry_point_call_wrapper(
mut call: CallEntryPoint,
mut call: ExecutableCallEntryPoint,
compiled_class: RunnableCompiledClass,
state: &mut dyn State,
context: &mut EntryPointExecutionContext,
Expand Down Expand Up @@ -93,7 +93,7 @@ pub fn execute_entry_point_call_wrapper(
_ => return Err(err.into()),
};
Ok(CallInfo {
call: orig_call,
call: orig_call.into(),
execution: CallExecution {
retdata: Retdata(vec![Felt::from_hex(error_code).unwrap()]),
failed: true,
Expand All @@ -110,7 +110,7 @@ pub fn execute_entry_point_call_wrapper(

/// Executes a specific call to a contract entry point and returns its output.
pub fn execute_entry_point_call(
call: CallEntryPoint,
call: ExecutableCallEntryPoint,
compiled_class: RunnableCompiledClass,
state: &mut dyn State,
context: &mut EntryPointExecutionContext,
Expand All @@ -125,22 +125,27 @@ pub fn execute_entry_point_call(
)
}
RunnableCompiledClass::V1(compiled_class) => {
entry_point_execution::execute_entry_point_call(call, compiled_class, state, context)
entry_point_execution::execute_entry_point_call(
call.into(),
compiled_class,
state,
context,
)
}
#[cfg(feature = "cairo_native")]
RunnableCompiledClass::V1Native(compiled_class) => {
if context.tracked_resource_stack.last() == Some(&TrackedResource::CairoSteps) {
// We cannot run native with cairo steps as the tracked resources (it's a vm
// resouorce).
entry_point_execution::execute_entry_point_call(
call,
call.into(),
compiled_class.casm(),
state,
context,
)
} else {
native_entry_point_execution::execute_entry_point_call(
call,
call.into(),
compiled_class,
state,
context,
Expand Down
Empty file modified scripts/rust_fmt.sh
100644 → 100755
Empty file.
Loading