Skip to content

Commit f427327

Browse files
blockifier: verify that the proof facts block number matches the block hash
1 parent 75105c7 commit f427327

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

crates/blockifier/src/transaction/account_transaction.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use starknet_api::core::{ClassHash, 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;
11+
use starknet_api::state::StorageKey;
1112
use starknet_api::transaction::fields::Resource::{L1DataGas, L1Gas, L2Gas};
1213
use starknet_api::transaction::fields::{
1314
AccountDeploymentData,
@@ -24,6 +25,7 @@ use starknet_api::transaction::{constants, TransactionHash, TransactionVersion};
2425
use starknet_types_core::felt::Felt;
2526

2627
use super::errors::ResourceBoundsError;
28+
use crate::abi::constants::STORED_BLOCK_HASH_BUFFER;
2729
use crate::context::{BlockContext, GasCounter, TransactionContext};
2830
use crate::execution::call_info::CallInfo;
2931
use crate::execution::common_hints::ExecutionMode;
@@ -246,15 +248,49 @@ impl AccountTransaction {
246248
}
247249
}
248250

249-
fn validate_proof_facts(&self) -> TransactionPreValidationResult<()> {
251+
fn validate_proof_facts(
252+
&self,
253+
tx_context: &TransactionContext,
254+
state: &mut dyn State,
255+
) -> TransactionPreValidationResult<()> {
250256
if let Transaction::Invoke(tx) = &self.tx {
251257
if tx.tx.version() == TransactionVersion::THREE {
252258
let proof_facts_variant = ProofFactsVariant::try_from(&tx.tx.proof_facts())
253259
.map_err(|e| TransactionPreValidationError::InvalidProofFacts(e.to_string()))?;
254260
match proof_facts_variant {
255261
ProofFactsVariant::Empty => {}
256-
ProofFactsVariant::Snos(_snos_proof_facts) => {
257-
// TODO(Meshi/ AvivG): add proof facts validations.
262+
ProofFactsVariant::Snos(snos_proof_facts) => {
263+
// TODO(Meshi/AvivG): Add more proof facts validations.
264+
let proof_block_number = snos_proof_facts.block_number;
265+
let proof_block_hash = snos_proof_facts.block_hash.0;
266+
267+
// Validate block number is not too recent.
268+
let current_block_number = tx_context.block_context.block_info.block_number;
269+
if current_block_number.0 - proof_block_number.0 < STORED_BLOCK_HASH_BUFFER
270+
{
271+
return Err(TransactionPreValidationError::InvalidProofFacts(format!(
272+
"Proof block number is too recent. Proof block number: \
273+
{proof_block_number}, current block number: \
274+
{current_block_number}."
275+
)));
276+
}
277+
278+
// Validate that the proof block hash matches the stored hash.
279+
let os_addresses = &tx_context
280+
.block_context
281+
.versioned_constants
282+
.os_constants
283+
.os_contract_addresses;
284+
let stored_block_hash = state.get_storage_at(
285+
os_addresses.block_hash_contract_address(),
286+
StorageKey::from(proof_block_number.0),
287+
)?;
288+
if stored_block_hash != proof_block_hash {
289+
return Err(TransactionPreValidationError::InvalidProofFacts(format!(
290+
"Block hash mismatch for block {proof_block_number}. Proof block \
291+
hash: {proof_block_hash}, stored block hash: {stored_block_hash}."
292+
)));
293+
}
258294
}
259295
}
260296
}
@@ -278,7 +314,7 @@ impl AccountTransaction {
278314
verify_can_pay_committed_bounds(state, tx_context).map_err(Box::new)?;
279315
}
280316

281-
self.validate_proof_facts()?;
317+
self.validate_proof_facts(tx_context, state)?;
282318

283319
Ok(())
284320
}

0 commit comments

Comments
 (0)