Skip to content

Commit f230436

Browse files
starknet_api: cache virtual_os_config_hash in OsConfigHash (#13310)
1 parent 6dc9e93 commit f230436

6 files changed

Lines changed: 56 additions & 41 deletions

File tree

crates/blockifier/src/context.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::collections::BTreeMap;
2-
use std::sync::Arc;
2+
use std::sync::{Arc, OnceLock};
33

44
use apollo_config::dumping::{prepend_sub_config_name, ser_param, SerializeConfig};
55
use apollo_config::{ParamPath, ParamPrivacyInput, SerializedParam};
@@ -14,6 +14,7 @@ use starknet_api::transaction::fields::{
1414
Tip,
1515
ValidResourceBounds,
1616
};
17+
use starknet_types_core::felt::Felt;
1718

1819
use crate::blockifier_versioned_constants::VersionedConstants;
1920
use crate::bouncer::BouncerConfig;
@@ -121,6 +122,9 @@ pub struct BlockContext {
121122
pub(crate) chain_info: ChainInfo,
122123
pub(crate) versioned_constants: VersionedConstants,
123124
pub bouncer_config: BouncerConfig,
125+
/// Cached on first access; derived from `chain_info`. Fixed for the lifetime of a block
126+
/// context.
127+
virtual_os_config_hash: OnceLock<Felt>,
124128
}
125129

126130
impl BlockContext {
@@ -130,7 +134,13 @@ impl BlockContext {
130134
versioned_constants: VersionedConstants,
131135
bouncer_config: BouncerConfig,
132136
) -> Self {
133-
BlockContext { block_info, chain_info, versioned_constants, bouncer_config }
137+
BlockContext {
138+
block_info,
139+
chain_info,
140+
versioned_constants,
141+
bouncer_config,
142+
virtual_os_config_hash: OnceLock::new(),
143+
}
134144
}
135145

136146
pub fn block_info(&self) -> &BlockInfo {
@@ -145,6 +155,15 @@ impl BlockContext {
145155
&self.versioned_constants
146156
}
147157

158+
/// Returns the virtual OS config hash, computing and caching it on first access.
159+
pub(crate) fn virtual_os_config_hash(&self) -> Felt {
160+
*self.virtual_os_config_hash.get_or_init(|| {
161+
OsChainInfo::from(&self.chain_info)
162+
.compute_virtual_os_config_hash()
163+
.expect("Failed to compute OS config hash")
164+
})
165+
}
166+
148167
pub fn to_tx_context(
149168
&self,
150169
tx_info_creator: &impl TransactionInfoCreator,
@@ -179,6 +198,12 @@ impl BlockContext {
179198
}
180199
}
181200

201+
/// Returns a new context with the given chain info, resetting the cached config hash.
202+
#[cfg(any(test, feature = "testing"))]
203+
pub fn with_chain_info(self, chain_info: ChainInfo) -> Self {
204+
Self::new(self.block_info, chain_info, self.versioned_constants, self.bouncer_config)
205+
}
206+
182207
/// Test util to allow overriding block gas limits.
183208
#[cfg(any(test, feature = "testing"))]
184209
pub fn set_sierra_gas_limits(

crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,7 @@ fn test_send_message_to_l1_invalid_address(#[values(true, false)] is_l3: bool) {
727727
..trivial_external_entry_point_new(test_contract)
728728
};
729729

730-
let block_context =
731-
BlockContext { chain_info: chain_info.clone(), ..BlockContext::create_for_testing() };
730+
let block_context = BlockContext::create_for_testing().with_chain_info(chain_info.clone());
732731
let result = entry_point_call.execute_directly_given_block_context(&mut state, block_context);
733732

734733
if is_l3 {

crates/blockifier/src/execution/syscalls/syscall_tests/send_message_to_l1.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ fn test_send_message_to_l1_invalid_address(
114114
calldata,
115115
..trivial_external_entry_point_new(test_contract)
116116
};
117-
let block_context =
118-
BlockContext { chain_info: chain_info.clone(), ..BlockContext::create_for_testing() };
117+
let block_context = BlockContext::create_for_testing().with_chain_info(chain_info.clone());
119118
let result = entry_point_call.execute_directly_given_block_context(&mut state, block_context);
120119

121120
if is_l3 {

crates/blockifier/src/test_utils/struct_impls.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -193,41 +193,39 @@ impl ChainInfo {
193193

194194
impl BlockContext {
195195
pub fn create_for_testing() -> Self {
196-
Self {
197-
block_info: BlockInfo::create_for_testing(),
198-
chain_info: ChainInfo::create_for_testing(),
199-
versioned_constants: VersionedConstants::create_for_testing(),
200-
bouncer_config: BouncerConfig::max(),
201-
}
196+
Self::new(
197+
BlockInfo::create_for_testing(),
198+
ChainInfo::create_for_testing(),
199+
VersionedConstants::create_for_testing(),
200+
BouncerConfig::max(),
201+
)
202202
}
203203

204204
pub fn create_for_account_testing() -> Self {
205-
Self {
206-
block_info: BlockInfo::create_for_testing(),
207-
chain_info: ChainInfo::create_for_testing(),
208-
versioned_constants: VersionedConstants::create_for_account_testing(),
209-
bouncer_config: BouncerConfig::max(),
210-
}
205+
Self::new(
206+
BlockInfo::create_for_testing(),
207+
ChainInfo::create_for_testing(),
208+
VersionedConstants::create_for_account_testing(),
209+
BouncerConfig::max(),
210+
)
211211
}
212212

213213
pub fn create_for_bouncer_testing(max_n_events_in_block: usize) -> Self {
214-
Self {
215-
bouncer_config: BouncerConfig {
216-
block_max_capacity: BouncerWeights {
217-
n_events: max_n_events_in_block,
218-
..BouncerWeights::max()
219-
},
220-
..BouncerConfig::max()
214+
let mut context = Self::create_for_account_testing();
215+
context.bouncer_config = BouncerConfig {
216+
block_max_capacity: BouncerWeights {
217+
n_events: max_n_events_in_block,
218+
..BouncerWeights::max()
221219
},
222-
..Self::create_for_account_testing()
223-
}
220+
..BouncerConfig::max()
221+
};
222+
context
224223
}
225224

226225
pub fn create_for_account_testing_with_kzg(use_kzg_da: bool) -> Self {
227-
Self {
228-
block_info: BlockInfo::create_for_testing_with_kzg(use_kzg_da),
229-
..Self::create_for_account_testing()
230-
}
226+
let mut context = Self::create_for_account_testing();
227+
context.block_info = BlockInfo::create_for_testing_with_kzg(use_kzg_da);
228+
context
231229
}
232230

233231
/// Returns a BlockContext for the given block index based on the base context.

crates/blockifier/src/test_utils/transfers_generator.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,8 @@ pub enum ExecutorWrapper {
100100
impl TransfersGenerator {
101101
pub fn new(config: TransfersGeneratorConfig) -> Self {
102102
let account_contract = FeatureContract::AccountWithoutValidations(config.cairo_version);
103-
let block_context = BlockContext {
104-
block_info: BlockInfo::create_for_testing_with_kzg(true),
105-
..BlockContext::create_for_account_testing()
106-
};
103+
let mut block_context = BlockContext::create_for_account_testing();
104+
block_context.block_info = BlockInfo::create_for_testing_with_kzg(true);
107105
let resource_bounds = ValidResourceBounds::all_bounds_from_vectors(
108106
&GasVector {
109107
l1_gas: 0_u32.into(),

crates/blockifier/src/transaction/account_transaction.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use starknet_api::abi::abi_utils::selector_from_name;
44
use starknet_api::block::{BlockNumber, GasPriceVector};
55
use starknet_api::calldata;
66
use starknet_api::contract_class::EntryPointType;
7-
use starknet_api::core::{ContractAddress, EntryPointSelector, Nonce, OsChainInfo};
7+
use starknet_api::core::{ContractAddress, EntryPointSelector, Nonce};
88
use starknet_api::data_availability::DataAvailabilityMode;
99
use starknet_api::executable_transaction::{AccountTransaction as Transaction, TransactionType};
1010
use starknet_api::execution_resources::GasAmount;
@@ -330,11 +330,7 @@ impl AccountTransaction {
330330
Self::validate_proof_block_hash(proof_block_hash, proof_block_number, os_constants, state)?;
331331

332332
// Validate the config hash.
333-
let chain_info = &block_context.chain_info;
334-
// TODO(Meshi): Cache this computation as part of the chain context.
335-
let virtual_os_config_hash = OsChainInfo::from(chain_info)
336-
.compute_virtual_os_config_hash()
337-
.expect("Failed to compute OS config hash");
333+
let virtual_os_config_hash = block_context.virtual_os_config_hash();
338334
let proof_config_hash = snos_proof_facts.config_hash;
339335
if virtual_os_config_hash != proof_config_hash {
340336
return Err(TransactionPreValidationError::InvalidProofFacts(format!(

0 commit comments

Comments
 (0)