From 5b55102867d9888e67c535acd5149e8d7a47b520 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Thu, 14 Nov 2024 22:53:16 +0000 Subject: [PATCH] feat(blockifier): implement get_clash_at syscall for native --- .../execution/native/entry_point_execution.rs | 7 ++---- .../src/execution/native/syscall_handler.rs | 25 ++++++++++++++++--- .../syscall_tests/get_class_hash_at.rs | 1 + 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/blockifier/src/execution/native/entry_point_execution.rs b/crates/blockifier/src/execution/native/entry_point_execution.rs index 7e8746caad..2ed18928db 100644 --- a/crates/blockifier/src/execution/native/entry_point_execution.rs +++ b/crates/blockifier/src/execution/native/entry_point_execution.rs @@ -85,11 +85,8 @@ fn create_callinfo( inner_calls: syscall_handler.inner_calls, storage_read_values: syscall_handler.read_values, accessed_storage_keys: syscall_handler.accessed_keys, - // TODO(Aviv): The syscall is not supported here yet. - // Currently, `accessed_contract_addresses` and `read_class_hash_values` are initialized - // as empty. Support for handling accessed storage keys via syscalls should be implemented. - accessed_contract_addresses: Default::default(), - read_class_hash_values: Default::default(), + accessed_contract_addresses: syscall_handler.accessed_contract_addresses, + read_class_hash_values: syscall_handler.read_class_hash_values, tracked_resource: TrackedResource::SierraGas, }) } diff --git a/crates/blockifier/src/execution/native/syscall_handler.rs b/crates/blockifier/src/execution/native/syscall_handler.rs index e9c0b6d463..67b310b76b 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -69,6 +69,9 @@ pub struct NativeSyscallHandler<'state> { // Additional information gathered during execution. pub read_values: Vec, pub accessed_keys: HashSet, + pub read_class_hash_values: Vec, + // Accessed addresses by the `get_class_hash_at` syscall. + pub accessed_contract_addresses: HashSet, // It is set if an unrecoverable error happens during syscall execution pub unrecoverable_error: Option, @@ -91,6 +94,8 @@ impl<'state> NativeSyscallHandler<'state> { inner_calls: Vec::new(), read_values: Vec::new(), accessed_keys: HashSet::new(), + read_class_hash_values: Vec::new(), + accessed_contract_addresses: HashSet::new(), unrecoverable_error: None, } } @@ -285,10 +290,24 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> { fn get_class_hash_at( &mut self, - _contract_address: Felt, - _remaining_gas: &mut u128, + contract_address: Felt, + remaining_gas: &mut u128, ) -> SyscallResult { - todo!() + self.pre_execute_syscall( + remaining_gas, + self.context.gas_costs().get_class_hash_at_gas_cost, + )?; + let request = ContractAddress::try_from(contract_address) + .map_err(|err| self.handle_error(remaining_gas, err.into()))?; + self.accessed_contract_addresses.insert(request); + + let class_hash = self + .state + .get_class_hash_at(request) + .map_err(|err| self.handle_error(remaining_gas, err.into()))?; + self.read_class_hash_values.push(class_hash); + + Ok(class_hash.0) } fn get_execution_info_v2( diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/get_class_hash_at.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/get_class_hash_at.rs index 108af5e5d3..07bb65f96c 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/get_class_hash_at.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/get_class_hash_at.rs @@ -18,6 +18,7 @@ use crate::test_utils::{trivial_external_entry_point_new, CairoVersion, BALANCE} /// 4. Execution fails if `address` has a different `class_hash`. /// 5. Execution succeeds and returns `class_hash` = 0 if `address` is absent. #[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), REQUIRED_GAS_GET_CLASS_HASH_AT_TEST; "VM")] +#[test_case(FeatureContract::TestContract(CairoVersion::Native), 17830; "Native")] fn test_get_class_hash_at(test_contract: FeatureContract, expected_gas: u64) { let chain_info = &ChainInfo::create_for_testing(); let mut state = test_state(chain_info, BALANCE, &[(test_contract, 1)]);