From 111c6fd7ea6895f6322c15865a6f7fafaf29781e Mon Sep 17 00:00:00 2001 From: nimrod-starkware <143319383+nimrod-starkware@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:10:41 +0200 Subject: [PATCH] feat(blockifier): add OS constants (#2281) --- .../resources/versioned_constants_0_13_0.json | 6 +++- .../resources/versioned_constants_0_13_1.json | 6 +++- .../versioned_constants_0_13_1_1.json | 6 +++- .../resources/versioned_constants_0_13_2.json | 6 +++- .../versioned_constants_0_13_2_1.json | 6 +++- .../resources/versioned_constants_0_13_3.json | 6 +++- .../resources/versioned_constants_0_13_4.json | 6 +++- crates/blockifier/src/abi/constants.rs | 7 ---- crates/blockifier/src/blockifier/block.rs | 6 ++-- .../blockifier/src/blockifier/block_test.rs | 10 +++--- .../src/blockifier/transaction_executor.rs | 1 + .../src/execution/syscalls/syscall_base.rs | 10 ++++-- .../syscalls/syscall_tests/get_block_hash.rs | 8 +++-- crates/blockifier/src/versioned_constants.rs | 36 +++++++++++++++++-- .../src/versioned_constants_test.rs | 4 +++ crates/papyrus_execution/src/lib.rs | 7 +++- 16 files changed, 101 insertions(+), 30 deletions(-) diff --git a/crates/blockifier/resources/versioned_constants_0_13_0.json b/crates/blockifier/resources/versioned_constants_0_13_0.json index 6f52d6cb43..36c41326c8 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_0.json +++ b/crates/blockifier/resources/versioned_constants_0_13_0.json @@ -69,7 +69,6 @@ "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "default_entry_point_selector": 0, - "block_hash_contract_address": 1, "stored_block_hash_buffer": 10, "step_gas_cost": 100, "range_check_gas_cost": 70, @@ -80,6 +79,11 @@ "add_mod_gas_cost": 0, "mul_mod_gas_cost": 0, "memory_hole_gas_cost": 10, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "default_initial_gas_cost": { "step_gas_cost": 100000000 }, diff --git a/crates/blockifier/resources/versioned_constants_0_13_1.json b/crates/blockifier/resources/versioned_constants_0_13_1.json index 1be6a8686f..cfea76e432 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_1.json +++ b/crates/blockifier/resources/versioned_constants_0_13_1.json @@ -69,7 +69,6 @@ "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "default_entry_point_selector": 0, - "block_hash_contract_address": 1, "stored_block_hash_buffer": 10, "step_gas_cost": 100, "range_check_gas_cost": 70, @@ -79,6 +78,11 @@ "poseidon_gas_cost": 0, "add_mod_gas_cost": 0, "mul_mod_gas_cost": 0, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "memory_hole_gas_cost": 10, "default_initial_gas_cost": { "step_gas_cost": 100000000 diff --git a/crates/blockifier/resources/versioned_constants_0_13_1_1.json b/crates/blockifier/resources/versioned_constants_0_13_1_1.json index 782d3ca130..8849299c49 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_1_1.json +++ b/crates/blockifier/resources/versioned_constants_0_13_1_1.json @@ -69,7 +69,6 @@ "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "default_entry_point_selector": 0, - "block_hash_contract_address": 1, "stored_block_hash_buffer": 10, "step_gas_cost": 100, "range_check_gas_cost": 70, @@ -80,6 +79,11 @@ "add_mod_gas_cost": 0, "mul_mod_gas_cost": 0, "memory_hole_gas_cost": 10, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "default_initial_gas_cost": { "step_gas_cost": 100000000 }, diff --git a/crates/blockifier/resources/versioned_constants_0_13_2.json b/crates/blockifier/resources/versioned_constants_0_13_2.json index 86ab5aeb02..da5869a94c 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_2.json +++ b/crates/blockifier/resources/versioned_constants_0_13_2.json @@ -56,7 +56,6 @@ "max_recursion_depth": 50, "segment_arena_cells": false, "os_constants": { - "block_hash_contract_address": 1, "call_contract_gas_cost": { "entry_point_gas_cost": 1, "step_gas_cost": 10, @@ -125,6 +124,11 @@ }, "memory_hole_gas_cost": 10, "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "range_check_gas_cost": 70, "pedersen_gas_cost": 0, "bitwise_builtin_gas_cost": 594, diff --git a/crates/blockifier/resources/versioned_constants_0_13_2_1.json b/crates/blockifier/resources/versioned_constants_0_13_2_1.json index 0b740a1205..357d42ff12 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_2_1.json +++ b/crates/blockifier/resources/versioned_constants_0_13_2_1.json @@ -56,7 +56,6 @@ "enable_reverts": false, "segment_arena_cells": false, "os_constants": { - "block_hash_contract_address": 1, "call_contract_gas_cost": { "entry_point_gas_cost": 1, "step_gas_cost": 10, @@ -125,6 +124,11 @@ }, "memory_hole_gas_cost": 10, "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "range_check_gas_cost": 70, "pedersen_gas_cost": 0, "bitwise_builtin_gas_cost": 594, diff --git a/crates/blockifier/resources/versioned_constants_0_13_3.json b/crates/blockifier/resources/versioned_constants_0_13_3.json index 0b740a1205..357d42ff12 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_3.json +++ b/crates/blockifier/resources/versioned_constants_0_13_3.json @@ -56,7 +56,6 @@ "enable_reverts": false, "segment_arena_cells": false, "os_constants": { - "block_hash_contract_address": 1, "call_contract_gas_cost": { "entry_point_gas_cost": 1, "step_gas_cost": 10, @@ -125,6 +124,11 @@ }, "memory_hole_gas_cost": 10, "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "range_check_gas_cost": 70, "pedersen_gas_cost": 0, "bitwise_builtin_gas_cost": 594, diff --git a/crates/blockifier/resources/versioned_constants_0_13_4.json b/crates/blockifier/resources/versioned_constants_0_13_4.json index 3c1703482b..c04fd8a728 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_4.json +++ b/crates/blockifier/resources/versioned_constants_0_13_4.json @@ -56,7 +56,6 @@ "max_recursion_depth": 50, "segment_arena_cells": false, "os_constants": { - "block_hash_contract_address": 1, "call_contract_gas_cost": { "entry_point_gas_cost": 1, "step_gas_cost": 860, @@ -126,6 +125,11 @@ }, "memory_hole_gas_cost": 10, "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "range_check_gas_cost": 70, "pedersen_gas_cost": 4050, "bitwise_builtin_gas_cost": 583, diff --git a/crates/blockifier/src/abi/constants.rs b/crates/blockifier/src/abi/constants.rs index ecdab0e133..45031271db 100644 --- a/crates/blockifier/src/abi/constants.rs +++ b/crates/blockifier/src/abi/constants.rs @@ -39,12 +39,5 @@ pub const N_MEMORY_HOLES: &str = "n_memory_holes"; pub const CAIRO0_ENTRY_POINT_STRUCT_SIZE: usize = 2; pub const N_STEPS_PER_PEDERSEN: usize = 8; -// OS reserved contract addresses. - -// This contract stores the block number -> block hash mapping. -// TODO(Arni, 14/6/2023): Replace BLOCK_HASH_CONSTANT_ADDRESS with a lazy calculation. -// pub static BLOCK_HASH_CONTRACT_ADDRESS: Lazy = ... -pub const BLOCK_HASH_CONTRACT_ADDRESS: u64 = 1; - // The block number -> block hash mapping is written for the current block number minus this number. pub const STORED_BLOCK_HASH_BUFFER: u64 = 10; diff --git a/crates/blockifier/src/blockifier/block.rs b/crates/blockifier/src/blockifier/block.rs index 5383d645f5..2fb14b404b 100644 --- a/crates/blockifier/src/blockifier/block.rs +++ b/crates/blockifier/src/blockifier/block.rs @@ -7,13 +7,12 @@ use starknet_api::block::{ GasPrices, NonzeroGasPrice, }; -use starknet_api::core::ContractAddress; use starknet_api::state::StorageKey; use crate::abi::constants; use crate::state::errors::StateError; use crate::state::state_api::{State, StateResult}; -use crate::versioned_constants::VersionedConstants; +use crate::versioned_constants::{OsConstants, VersionedConstants}; #[cfg(test)] #[path = "block_test.rs"] @@ -78,12 +77,13 @@ pub fn pre_process_block( state: &mut dyn State, old_block_number_and_hash: Option, next_block_number: BlockNumber, + os_constants: &OsConstants, ) -> StateResult<()> { let should_block_hash_be_provided = next_block_number >= BlockNumber(constants::STORED_BLOCK_HASH_BUFFER); if let Some(BlockHashAndNumber { number, hash }) = old_block_number_and_hash { let block_hash_contract_address = - ContractAddress::from(constants::BLOCK_HASH_CONTRACT_ADDRESS); + os_constants.os_contract_addresses.block_hash_contract_address(); let block_number_as_storage_key = StorageKey::from(number.0); state.set_storage_at(block_hash_contract_address, block_number_as_storage_key, hash.0)?; } else if should_block_hash_be_provided { diff --git a/crates/blockifier/src/blockifier/block_test.rs b/crates/blockifier/src/blockifier/block_test.rs index 39dd8e5336..1822dc9349 100644 --- a/crates/blockifier/src/blockifier/block_test.rs +++ b/crates/blockifier/src/blockifier/block_test.rs @@ -1,5 +1,4 @@ use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockNumber}; -use starknet_api::core::ContractAddress; use starknet_api::felt; use starknet_api::state::StorageKey; @@ -10,11 +9,13 @@ use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{CairoVersion, BALANCE}; +use crate::versioned_constants::VersionedConstants; #[test] fn test_pre_process_block() { let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1); let mut state = test_state(&ChainInfo::create_for_testing(), BALANCE, &[(test_contract, 1)]); + let os_constants = VersionedConstants::create_for_testing().os_constants; // Test the positive flow of pre_process_block inside the allowed block number interval let block_number = BlockNumber(constants::STORED_BLOCK_HASH_BUFFER); @@ -23,11 +24,12 @@ fn test_pre_process_block() { &mut state, Some(BlockHashAndNumber { hash: BlockHash(block_hash), number: block_number }), block_number, + &os_constants, ) .unwrap(); let written_hash = state.get_storage_at( - ContractAddress::from(constants::BLOCK_HASH_CONTRACT_ADDRESS), + os_constants.os_contract_addresses.block_hash_contract_address(), StorageKey::from(block_number.0), ); assert_eq!(written_hash.unwrap(), block_hash); @@ -35,10 +37,10 @@ fn test_pre_process_block() { // Test that block pre-process with block hash None is successful only within the allowed // block number interval. let block_number = BlockNumber(constants::STORED_BLOCK_HASH_BUFFER - 1); - assert!(pre_process_block(&mut state, None, block_number).is_ok()); + assert!(pre_process_block(&mut state, None, block_number, &os_constants).is_ok()); let block_number = BlockNumber(constants::STORED_BLOCK_HASH_BUFFER); - let error = pre_process_block(&mut state, None, block_number); + let error = pre_process_block(&mut state, None, block_number, &os_constants); assert_eq!( format!( "A block hash must be provided for block number > {}.", diff --git a/crates/blockifier/src/blockifier/transaction_executor.rs b/crates/blockifier/src/blockifier/transaction_executor.rs index 01be23df90..4ad8bfb285 100644 --- a/crates/blockifier/src/blockifier/transaction_executor.rs +++ b/crates/blockifier/src/blockifier/transaction_executor.rs @@ -68,6 +68,7 @@ impl TransactionExecutor { &mut block_state, old_block_number_and_hash, block_context.block_info().block_number, + &block_context.versioned_constants.os_constants, )?; Ok(Self::new(block_state, block_context, config)) } diff --git a/crates/blockifier/src/execution/syscalls/syscall_base.rs b/crates/blockifier/src/execution/syscalls/syscall_base.rs index bfb9da2ad1..f664d2ab47 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_base.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_base.rs @@ -105,8 +105,14 @@ impl<'state> SyscallHandlerBase<'state> { } 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 block_hash_contract_address = self + .context + .tx_context + .block_context + .versioned_constants + .os_constants + .os_contract_addresses + .block_hash_contract_address(); Ok(self.state.get_storage_at(block_hash_contract_address, key)?) } 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 83c7af1a63..37ef06006f 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 @@ -1,6 +1,5 @@ use pretty_assertions::assert_eq; use starknet_api::abi::abi_utils::selector_from_name; -use starknet_api::core::ContractAddress; use starknet_api::execution_utils::format_panic_data; use starknet_api::state::StorageKey; use starknet_api::{calldata, felt}; @@ -22,6 +21,7 @@ use crate::test_utils::{ BALANCE, CURRENT_BLOCK_NUMBER, }; +use crate::versioned_constants::VersionedConstants; use crate::{check_entry_point_execution_error_for_custom_hint, retdata}; fn initialize_state(test_contract: FeatureContract) -> (CachedState, Felt, Felt) { @@ -33,8 +33,10 @@ fn initialize_state(test_contract: FeatureContract) -> (CachedState for OsConstants { fn try_from(raw_json_data: OsConstantsRawJson) -> Result { let gas_costs = GasCosts::try_from(&raw_json_data)?; let validate_rounding_consts = raw_json_data.validate_rounding_consts; - let os_constants = OsConstants { gas_costs, validate_rounding_consts }; + let os_contract_addresses = raw_json_data.os_contract_addresses; + let os_constants = + OsConstants { gas_costs, validate_rounding_consts, os_contract_addresses }; Ok(os_constants) } } +#[derive(Clone, Copy, Debug, Deserialize, Serialize)] +pub struct OsContractAddresses { + block_hash_contract_address: u8, + alias_contract_address: u8, + reserved_contract_address: u8, +} + +impl OsContractAddresses { + pub fn block_hash_contract_address(&self) -> ContractAddress { + ContractAddress::from(self.block_hash_contract_address) + } + + pub fn alias_contract_address(&self) -> ContractAddress { + ContractAddress::from(self.alias_contract_address) + } + + pub fn reserved_contract_address(&self) -> ContractAddress { + ContractAddress::from(self.reserved_contract_address) + } +} + +impl Default for OsContractAddresses { + fn default() -> Self { + VersionedConstants::latest_constants().os_constants.os_contract_addresses + } +} // Intermediate representation of the JSON file in order to make the deserialization easier, using a // regular try_from. @@ -760,6 +789,7 @@ struct OsConstantsRawJson { raw_json_file_as_dict: IndexMap, #[serde(default)] validate_rounding_consts: ValidateRoundingConsts, + os_contract_addresses: OsContractAddresses, } impl OsConstantsRawJson { diff --git a/crates/blockifier/src/versioned_constants_test.rs b/crates/blockifier/src/versioned_constants_test.rs index 4f281f71af..320f38aa90 100644 --- a/crates/blockifier/src/versioned_constants_test.rs +++ b/crates/blockifier/src/versioned_constants_test.rs @@ -78,6 +78,10 @@ fn check_constants_serde_error(json_data: &str, expected_error_message: &str) { let mut json_data_raw: IndexMap = serde_json::from_str(json_data).unwrap(); json_data_raw.insert("validate_block_number_rounding".to_string(), 0.into()); json_data_raw.insert("validate_timestamp_rounding".to_string(), 0.into()); + json_data_raw.insert( + "os_contract_addresses".to_string(), + serde_json::to_value(OsContractAddresses::default()).unwrap(), + ); let json_data = &serde_json::to_string(&json_data_raw).unwrap(); diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index 77e5348e4a..369222aec5 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -405,7 +405,12 @@ fn create_block_context( ); let next_block_number = block_context.block_info().block_number; - pre_process_block(cached_state, ten_blocks_ago, next_block_number)?; + pre_process_block( + cached_state, + ten_blocks_ago, + next_block_number, + &versioned_constants.os_constants, + )?; Ok(block_context) }