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

feat(execution): calculate the syscall resources for every entry point #1437

Merged
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 @@ -241,7 +241,12 @@ pub fn finalize_execution(
.get_execution_resources(&vm)
.map_err(VirtualMachineError::RunnerError)?
.filter_unused_builtins();
// TODO(Ori, 14/2/2024): Rename `vm_resources`.
syscall_handler.resources.vm_resources += &vm_resources_without_inner_calls;
let versioned_constants = syscall_handler.context.versioned_constants();
// Take into account the syscall resources of the current call.
syscall_handler.resources.vm_resources += &versioned_constants
.get_additional_os_syscall_resources(&syscall_handler.syscall_counter)?;

let full_call_vm_resources = &syscall_handler.resources.vm_resources - &previous_vm_resources;
Ok(CallInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,11 @@ fn test_nested_library_call() {
calldata: calldata![stark_felt!(key), stark_felt!(value)],
..nested_storage_entry_point
};
let storage_entry_point_vm_resources =
VmExecutionResources { n_steps: 42, ..Default::default() };
let storage_entry_point_vm_resources = VmExecutionResources {
n_steps: 218,
n_memory_holes: 0,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 2)]),
};
let nested_storage_call_info = CallInfo {
call: nested_storage_entry_point,
execution: CallExecution::from_retdata(retdata![stark_felt!(value + 1)]),
Expand All @@ -145,9 +148,9 @@ fn test_nested_library_call() {
..Default::default()
};
let mut library_call_vm_resources = VmExecutionResources {
n_steps: 39,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 1)]),
..Default::default()
n_steps: 790,
n_memory_holes: 4,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 21)]),
};
library_call_vm_resources += &storage_entry_point_vm_resources;
let library_call_info = CallInfo {
Expand All @@ -167,7 +170,11 @@ fn test_nested_library_call() {
};

// Nested library call cost: library_call(inner) + library_call(library_call(inner)).
let mut main_call_vm_resources = VmExecutionResources { n_steps: 45, ..Default::default() };
let mut main_call_vm_resources = VmExecutionResources {
n_steps: 796,
n_memory_holes: 4,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 20)]),
};
main_call_vm_resources += &(&library_call_vm_resources * 2);
let expected_call_info = CallInfo {
call: main_entry_point.clone(),
Expand Down Expand Up @@ -218,7 +225,11 @@ fn test_call_contract() {
..trivial_external_entry_point
},
execution: expected_execution.clone(),
vm_resources: VmExecutionResources { n_steps: 42, ..Default::default() },
vm_resources: VmExecutionResources {
n_steps: 218,
n_memory_holes: 0,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 2)]),
},
storage_read_values: vec![StarkFelt::ZERO, stark_felt!(value)],
accessed_storage_keys: HashSet::from([StorageKey(patricia_key!(key))]),
..Default::default()
Expand All @@ -235,9 +246,9 @@ fn test_call_contract() {
},
execution: expected_execution,
vm_resources: VmExecutionResources {
n_steps: 81,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 1)]),
..Default::default()
n_steps: 1017,
n_memory_holes: 4,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 23)]),
},
..Default::default()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub struct DeprecatedSyscallHintProcessor<'a> {
pub inner_calls: Vec<CallInfo>,
pub events: Vec<OrderedEvent>,
pub l2_to_l1_messages: Vec<OrderedL2ToL1Message>,
pub syscall_counter: SyscallCounter,

// Fields needed for execution and validation.
pub read_only_segments: ReadOnlySegments,
Expand Down Expand Up @@ -134,6 +135,7 @@ impl<'a> DeprecatedSyscallHintProcessor<'a> {
inner_calls: vec![],
events: vec![],
l2_to_l1_messages: vec![],
syscall_counter: SyscallCounter::default(),
read_only_segments: ReadOnlySegments::default(),
syscall_ptr: initial_syscall_ptr,
read_values: vec![],
Expand Down Expand Up @@ -290,6 +292,8 @@ impl<'a> DeprecatedSyscallHintProcessor<'a> {
fn increment_syscall_count(&mut self, selector: &DeprecatedSyscallSelector) {
let syscall_count = self.resources.syscall_counter.entry(*selector).or_default();
*syscall_count += 1;
let entry_point_syscall_count = self.syscall_counter.entry(*selector).or_default();
*entry_point_syscall_count += 1;
}

fn allocate_tx_signature_segment(
Expand Down
5 changes: 5 additions & 0 deletions crates/blockifier/src/execution/entry_point_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,12 @@ pub fn finalize_execution(
.get_execution_resources(&vm)
.map_err(VirtualMachineError::RunnerError)?
.filter_unused_builtins();
// TODO(Ori, 14/2/2024): Rename `vm_resources`.
syscall_handler.resources.vm_resources += &vm_resources_without_inner_calls;
let versioned_constants = syscall_handler.context.versioned_constants();
// Take into account the syscall resources of the current call.
syscall_handler.resources.vm_resources += &versioned_constants
.get_additional_os_syscall_resources(&syscall_handler.syscall_counter)?;

let full_call_vm_resources = &syscall_handler.resources.vm_resources - &previous_vm_resources;
Ok(CallInfo {
Expand Down
4 changes: 4 additions & 0 deletions crates/blockifier/src/execution/syscalls/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ pub struct SyscallHintProcessor<'a> {
pub inner_calls: Vec<CallInfo>,
pub events: Vec<OrderedEvent>,
pub l2_to_l1_messages: Vec<OrderedL2ToL1Message>,
pub syscall_counter: SyscallCounter,

// Fields needed for execution and validation.
pub read_only_segments: ReadOnlySegments,
Expand Down Expand Up @@ -163,6 +164,7 @@ impl<'a> SyscallHintProcessor<'a> {
inner_calls: vec![],
events: vec![],
l2_to_l1_messages: vec![],
syscall_counter: SyscallCounter::default(),
read_only_segments,
syscall_ptr: initial_syscall_ptr,
read_values: vec![],
Expand Down Expand Up @@ -418,6 +420,8 @@ impl<'a> SyscallHintProcessor<'a> {
pub fn increment_syscall_count_by(&mut self, selector: &SyscallSelector, n: usize) {
let syscall_count = self.resources.syscall_counter.entry(*selector).or_default();
*syscall_count += n;
let entry_point_syscall_count = self.syscall_counter.entry(*selector).or_default();
*entry_point_syscall_count += n;
}

fn increment_syscall_count(&mut self, selector: &SyscallSelector) {
Expand Down
16 changes: 8 additions & 8 deletions crates/blockifier/src/execution/syscalls/syscalls_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,9 @@ fn test_nested_library_call() {
..nested_storage_entry_point
};
let storage_entry_point_vm_resources = VmExecutionResources {
n_steps: 143,
n_steps: 319,
n_memory_holes: 1,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 5)]),
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 7)]),
};
let nested_storage_call_info = CallInfo {
call: nested_storage_entry_point,
Expand All @@ -559,9 +559,9 @@ fn test_nested_library_call() {
..Default::default()
};
let library_call_vm_resources = VmExecutionResources {
n_steps: 411,
n_memory_holes: 2,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 13)]),
n_steps: 1338,
n_memory_holes: 6,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 35)]),
};
let library_call_info = CallInfo {
call: library_entry_point,
Expand All @@ -588,9 +588,9 @@ fn test_nested_library_call() {
};

let main_call_vm_resources = VmExecutionResources {
n_steps: 765,
n_memory_holes: 4,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 23)]),
n_steps: 3370,
n_memory_holes: 16,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 87)]),
};
let expected_call_info = CallInfo {
call: main_entry_point.clone(),
Expand Down
6 changes: 1 addition & 5 deletions crates/blockifier/src/transaction/transaction_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@ pub fn calculate_tx_resources(
.expect("This conversion should not fail as the value is a converted usize.");
// Add additional Cairo resources needed for the OS to run the transaction.
let total_vm_usage = &execution_resources.vm_resources
+ &versioned_constants.get_additional_os_resources(
&execution_resources.syscall_counter,
tx_type,
calldata_length,
)?;
+ &versioned_constants.get_additional_os_tx_resources(tx_type, calldata_length)?;
let mut total_vm_usage = total_vm_usage.filter_unused_builtins();
// The segment arena" builtin is not part of SHARP (not in any proof layout).
// Each instance requires approximately 10 steps in the OS.
Expand Down
16 changes: 8 additions & 8 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,9 @@ fn default_invoke_tx_args(
range_check: 102,
n_steps: 4496,
vm_resources: VmExecutionResources {
n_steps: 62,
n_memory_holes: 0,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 1)]),
n_steps: 822,
n_memory_holes: 4,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 21)]),
},
validate_gas_consumed: 0,
execute_gas_consumed: 0,
Expand All @@ -323,9 +323,9 @@ fn default_invoke_tx_args(
range_check: 115,
n_steps: 4949,
vm_resources: VmExecutionResources {
n_steps: 284,
n_memory_holes: 1,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 7)]),
n_steps: 1106,
n_memory_holes: 5,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 28)]),
},
validate_gas_consumed: 14360, // The gas consumption results from parsing the input
// arguments.
Expand Down Expand Up @@ -1701,9 +1701,9 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) {
..Default::default()
},
vm_resources: VmExecutionResources {
n_steps: 143,
n_steps: 232,
n_memory_holes: 1,
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 5)]),
builtin_instance_counter: HashMap::from([(RANGE_CHECK_BUILTIN_NAME.to_string(), 6)]),
},
accessed_storage_keys: HashSet::from_iter(vec![accessed_storage_key]),
..Default::default()
Expand Down
40 changes: 25 additions & 15 deletions crates/blockifier/src/versioned_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use thiserror::Error;

use crate::execution::deprecated_syscalls::hint_processor::SyscallCounter;
use crate::execution::deprecated_syscalls::DeprecatedSyscallSelector;
use crate::execution::errors::PostExecutionError;
use crate::transaction::errors::TransactionExecutionError;
use crate::transaction::transaction_types::TransactionType;

Expand Down Expand Up @@ -97,15 +98,19 @@ impl VersionedConstants {
self.os_resources.resources_for_tx_type(tx_type, calldata_length)
}

/// Calculates the additional resources needed for the OS to run the given syscalls;
/// i.e., the resources of the Starknet OS function `execute_syscalls`.
pub fn get_additional_os_resources(
pub fn get_additional_os_tx_resources(
&self,
syscall_counter: &SyscallCounter,
tx_type: TransactionType,
calldata_length: usize,
) -> Result<VmExecutionResources, TransactionExecutionError> {
self.os_resources.get_additional_os_resources(syscall_counter, tx_type, calldata_length)
self.os_resources.get_additional_os_tx_resources(tx_type, calldata_length)
}

pub fn get_additional_os_syscall_resources(
&self,
syscall_counter: &SyscallCounter,
) -> Result<VmExecutionResources, PostExecutionError> {
self.os_resources.get_additional_os_syscall_resources(syscall_counter)
}

#[cfg(any(feature = "testing", test))]
Expand Down Expand Up @@ -151,14 +156,24 @@ pub struct OsResources {
}

impl OsResources {
/// Calculates the additional resources needed for the OS to run the given syscalls;
/// i.e., the resources of the Starknet OS function `execute_syscalls`.
fn get_additional_os_resources(
/// Calculates the additional resources needed for the OS to run the given transaction;
/// i.e., the resources of the Starknet OS function `execute_transactions_inner`.
/// Also adds the resources needed for the fee transfer execution, performed in the end·
/// of every transaction.
fn get_additional_os_tx_resources(
&self,
syscall_counter: &SyscallCounter,
tx_type: TransactionType,
calldata_length: usize,
) -> Result<VmExecutionResources, TransactionExecutionError> {
Ok(self.resources_for_tx_type(&tx_type, calldata_length))
}

/// Calculates the additional resources needed for the OS to run the given syscalls;
/// i.e., the resources of the Starknet OS function `execute_syscalls`.
fn get_additional_os_syscall_resources(
&self,
syscall_counter: &SyscallCounter,
) -> Result<VmExecutionResources, PostExecutionError> {
let mut os_additional_vm_resources = VmExecutionResources::default();
for (syscall_selector, count) in syscall_counter {
let syscall_resources =
Expand All @@ -168,12 +183,7 @@ impl OsResources {
os_additional_vm_resources += &(syscall_resources * *count);
}

// Calculates the additional resources needed for the OS to run the given transaction;
// i.e., the resources of the Starknet OS function `execute_transactions_inner`.
// Also adds the resources needed for the fee transfer execution, performed in the end·
// of every transaction.
let os_resources = self.resources_for_tx_type(&tx_type, calldata_length);
Ok(&os_additional_vm_resources + &os_resources)
Ok(os_additional_vm_resources)
}

fn resources_params_for_tx_type(&self, tx_type: &TransactionType) -> &ResourcesParams {
Expand Down
Loading