Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): add OS constants to VC #2281

Merged
merged 1 commit into from
Dec 2, 2024
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
6 changes: 5 additions & 1 deletion crates/blockifier/resources/versioned_constants_0_13_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
},
Expand Down
6 changes: 5 additions & 1 deletion crates/blockifier/resources/versioned_constants_0_13_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
},
Expand Down
6 changes: 5 additions & 1 deletion crates/blockifier/resources/versioned_constants_0_13_2.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion crates/blockifier/resources/versioned_constants_0_13_3.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion crates/blockifier/resources/versioned_constants_0_13_4.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 0 additions & 7 deletions crates/blockifier/src/abi/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ContractAddress> = ...
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;
6 changes: 3 additions & 3 deletions crates/blockifier/src/blockifier/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down Expand Up @@ -78,12 +77,13 @@ pub fn pre_process_block(
state: &mut dyn State,
old_block_number_and_hash: Option<BlockHashAndNumber>,
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 {
Expand Down
10 changes: 6 additions & 4 deletions crates/blockifier/src/blockifier/block_test.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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);
Expand All @@ -23,22 +24,23 @@ 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);

// 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 > {}.",
Expand Down
1 change: 1 addition & 0 deletions crates/blockifier/src/blockifier/transaction_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ impl<S: StateReader> TransactionExecutor<S> {
&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))
}
Expand Down
10 changes: 8 additions & 2 deletions crates/blockifier/src/execution/syscalls/syscall_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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<DictStateReader>, Felt, Felt) {
Expand All @@ -33,8 +33,10 @@ fn initialize_state(test_contract: FeatureContract) -> (CachedState<DictStateRea
let block_number = felt!(upper_bound_block_number);
let block_hash = felt!(66_u64);
let key = StorageKey::try_from(block_number).unwrap();
let block_hash_contract_address =
ContractAddress::try_from(Felt::from(constants::BLOCK_HASH_CONTRACT_ADDRESS)).unwrap();
let block_hash_contract_address = VersionedConstants::create_for_testing()
.os_constants
.os_contract_addresses
.block_hash_contract_address();
state.set_storage_at(block_hash_contract_address, key, block_hash).unwrap();

(state, block_number, block_hash)
Expand Down
36 changes: 33 additions & 3 deletions crates/blockifier/src/versioned_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use serde::de::Error as DeserializationError;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::{Map, Number, Value};
use starknet_api::block::{GasPrice, StarknetVersion};
use starknet_api::core::ContractAddress;
use starknet_api::execution_resources::{GasAmount, GasVector};
use starknet_api::transaction::fields::GasVectorComputationMode;
use strum::IntoEnumIterator;
Expand Down Expand Up @@ -691,15 +692,15 @@ impl GasCosts {
pub struct OsConstants {
pub gas_costs: GasCosts,
pub validate_rounding_consts: ValidateRoundingConsts,
pub os_contract_addresses: OsContractAddresses,
}

impl OsConstants {
// List of additinal os constants, beside the gas cost and validate rounding constants, that are
// not used by the blockifier but included for transparency. These constanst will be ignored
// during the creation of the struct containing the gas costs.

const ADDITIONAL_FIELDS: [&'static str; 29] = [
"block_hash_contract_address",
const ADDITIONAL_FIELDS: [&'static str; 28] = [
"constructor_entry_point_selector",
"default_entry_point_selector",
"entry_point_type_constructor",
Expand Down Expand Up @@ -747,10 +748,38 @@ impl TryFrom<OsConstantsRawJson> for OsConstants {
fn try_from(raw_json_data: OsConstantsRawJson) -> Result<Self, Self::Error> {
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.
Expand All @@ -760,6 +789,7 @@ struct OsConstantsRawJson {
raw_json_file_as_dict: IndexMap<String, Value>,
#[serde(default)]
validate_rounding_consts: ValidateRoundingConsts,
os_contract_addresses: OsContractAddresses,
}

impl OsConstantsRawJson {
Expand Down
4 changes: 4 additions & 0 deletions crates/blockifier/src/versioned_constants_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ fn check_constants_serde_error(json_data: &str, expected_error_message: &str) {
let mut json_data_raw: IndexMap<String, Value> = 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();

Expand Down
7 changes: 6 additions & 1 deletion crates/papyrus_execution/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Loading