diff --git a/crates/blockifier/src/execution/native/entry_point_execution.rs b/crates/blockifier/src/execution/native/entry_point_execution.rs index 3037f176fd..02f4f45b12 100644 --- a/crates/blockifier/src/execution/native/entry_point_execution.rs +++ b/crates/blockifier/src/execution/native/entry_point_execution.rs @@ -98,11 +98,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 95ae089b40..7d9651ff20 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -76,6 +76,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, @@ -98,6 +101,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, } } @@ -297,10 +302,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 5bab43ebb2..a24ea84cf2 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,10 @@ 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")] +#[cfg_attr( + feature = "cairo_native", + 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)]);