diff --git a/crates/blockifier/src/execution/native/syscall_handler.rs b/crates/blockifier/src/execution/native/syscall_handler.rs index 669be87e29..f51cb29ae6 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -28,7 +28,6 @@ use starknet_api::transaction::fields::{Calldata, ContractAddressSalt}; use starknet_api::transaction::{EventContent, EventData, EventKey, L2ToL1Payload}; use starknet_types_core::felt::Felt; -use crate::abi::constants; use crate::execution::call_info::{ CallInfo, MessageToL1, @@ -50,10 +49,10 @@ use crate::execution::native::utils::{calculate_resource_bounds, default_tx_v2_i use crate::execution::syscalls::exceeds_event_size_limit; use crate::execution::syscalls::hint_processor::{ SyscallExecutionError, - BLOCK_NUMBER_OUT_OF_RANGE_ERROR, INVALID_INPUT_LENGTH_ERROR, OUT_OF_GAS_ERROR, }; +use crate::execution::syscalls::syscall_base::get_block_hash_base; use crate::state::state_api::State; use crate::transaction::objects::TransactionInfo; @@ -280,21 +279,9 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> { let current_block_number = self.context.tx_context.block_context.block_info().block_number.0; - if current_block_number < constants::STORED_BLOCK_HASH_BUFFER - || block_number > current_block_number - constants::STORED_BLOCK_HASH_BUFFER - { - // `panic` is unreachable in this case, also this is covered by tests so we can safely - // unwrap - let out_of_range_felt = Felt::from_hex(BLOCK_NUMBER_OUT_OF_RANGE_ERROR) - .expect("Converting BLOCK_NUMBER_OUT_OF_RANGE_ERROR to Felt should not fail."); - let error = SyscallExecutionError::SyscallError { error_data: vec![out_of_range_felt] }; - return Err(self.handle_error(remaining_gas, error)); - } - let key = StorageKey::try_from(Felt::from(block_number)) - .map_err(|e| self.handle_error(remaining_gas, e.into()))?; - let block_hash_contract_address = - ContractAddress::try_from(Felt::from(constants::BLOCK_HASH_CONTRACT_ADDRESS)) + let (key, block_hash_contract_address) = + get_block_hash_base(current_block_number, block_number) .map_err(|e| self.handle_error(remaining_gas, e.into()))?; match self.state.get_storage_at(block_hash_contract_address, key) { diff --git a/crates/blockifier/src/execution/syscalls/mod.rs b/crates/blockifier/src/execution/syscalls/mod.rs index 1f84bfa4f7..cf552924aa 100644 --- a/crates/blockifier/src/execution/syscalls/mod.rs +++ b/crates/blockifier/src/execution/syscalls/mod.rs @@ -27,9 +27,7 @@ use self::hint_processor::{ EmitEventError, SyscallExecutionError, SyscallHintProcessor, - BLOCK_NUMBER_OUT_OF_RANGE_ERROR, }; -use crate::abi::constants; use crate::execution::call_info::{MessageToL1, OrderedEvent, OrderedL2ToL1Message}; use crate::execution::deprecated_syscalls::DeprecatedSyscallSelector; use crate::execution::entry_point::{CallEntryPoint, CallType, ConstructorContext}; @@ -41,16 +39,17 @@ use crate::execution::execution_utils::{ ReadOnlySegment, }; use crate::execution::syscalls::hint_processor::{INVALID_INPUT_LENGTH_ERROR, OUT_OF_GAS_ERROR}; +use crate::execution::syscalls::syscall_base::{get_block_hash_base, SyscallResult}; use crate::transaction::account_transaction::is_cairo1; use crate::versioned_constants::{EventLimits, VersionedConstants}; pub mod hint_processor; mod secp; +pub mod syscall_base; #[cfg(test)] pub mod syscall_tests; -pub type SyscallResult = Result; pub type WriteResponseResult = SyscallResult<()>; pub type SyscallSelector = DeprecatedSyscallSelector; @@ -403,17 +402,8 @@ pub fn get_block_hash( let current_block_number = syscall_handler.context.tx_context.block_context.block_info.block_number.0; - if current_block_number < constants::STORED_BLOCK_HASH_BUFFER - || requested_block_number > current_block_number - constants::STORED_BLOCK_HASH_BUFFER - { - let out_of_range_error = - Felt::from_hex(BLOCK_NUMBER_OUT_OF_RANGE_ERROR).map_err(SyscallExecutionError::from)?; - return Err(SyscallExecutionError::SyscallError { error_data: vec![out_of_range_error] }); - } - - let key = StorageKey::try_from(Felt::from(requested_block_number))?; - let block_hash_contract_address = - ContractAddress::try_from(Felt::from(constants::BLOCK_HASH_CONTRACT_ADDRESS))?; + let (key, block_hash_contract_address) = + get_block_hash_base(current_block_number, requested_block_number)?; let block_hash = BlockHash(syscall_handler.state.get_storage_at(block_hash_contract_address, key)?); Ok(GetBlockHashResponse { block_hash }) diff --git a/crates/blockifier/src/execution/syscalls/syscall_base.rs b/crates/blockifier/src/execution/syscalls/syscall_base.rs new file mode 100644 index 0000000000..3aebb9b7d2 --- /dev/null +++ b/crates/blockifier/src/execution/syscalls/syscall_base.rs @@ -0,0 +1,29 @@ +use starknet_api::core::ContractAddress; +use starknet_api::state::StorageKey; +use starknet_types_core::felt::Felt; + +use crate::abi::constants; +use crate::execution::syscalls::hint_processor::{ + SyscallExecutionError, + BLOCK_NUMBER_OUT_OF_RANGE_ERROR, +}; + +pub type SyscallResult = Result; + +pub fn get_block_hash_base( + current_block_number: u64, + requested_block_number: u64, +) -> SyscallResult<(StorageKey, ContractAddress)> { + if current_block_number < constants::STORED_BLOCK_HASH_BUFFER + || requested_block_number > current_block_number - constants::STORED_BLOCK_HASH_BUFFER + { + let out_of_range_error = + Felt::from_hex(BLOCK_NUMBER_OUT_OF_RANGE_ERROR).map_err(SyscallExecutionError::from)?; + return Err(SyscallExecutionError::SyscallError { error_data: vec![out_of_range_error] }); + } + + let key = StorageKey::try_from(Felt::from(requested_block_number))?; + let block_hash_contract_address = + ContractAddress::try_from(Felt::from(constants::BLOCK_HASH_CONTRACT_ADDRESS))?; + Ok((key, block_hash_contract_address)) +} diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/get_block_hash.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/get_block_hash.rs index cf07ca445b..413647c2dd 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/get_block_hash.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/get_block_hash.rs @@ -117,11 +117,10 @@ fn negative_flow_block_number_out_of_range(test_contract: FeatureContract) { ..trivial_external_entry_point_new(test_contract) }; - let call_result = entry_point_call.execute_directly(&mut state); - let (actual_error_msg, expected_error_msg) = ( - format_panic_data(&call_result.unwrap().execution.retdata.0), - "0x426c6f636b206e756d626572206f7574206f662072616e6765 ('Block number out of range')", + let call_info = entry_point_call.execute_directly(&mut state).unwrap(); + assert!(call_info.execution.failed); + assert_eq!( + format_panic_data(&call_info.execution.retdata.0), + "0x426c6f636b206e756d626572206f7574206f662072616e6765 ('Block number out of range')" ); - - assert_eq!(actual_error_msg, expected_error_msg); }