@@ -17,7 +17,7 @@ use starknet_api::abi::abi_utils::{
1717 get_storage_var_address,
1818 selector_from_name,
1919} ;
20- use starknet_api:: block:: { FeeType , GasPrice } ;
20+ use starknet_api:: block:: { BlockHash , BlockNumber , FeeType , GasPrice } ;
2121use starknet_api:: contract_class:: compiled_class_hash:: { HashVersion , HashableCompiledClass } ;
2222use starknet_api:: contract_class:: ContractClass ;
2323use starknet_api:: core:: {
@@ -41,6 +41,7 @@ use starknet_api::test_utils::deploy_account::executable_deploy_account_tx;
4141use starknet_api:: test_utils:: invoke:: { executable_invoke_tx, InvokeTxArgs } ;
4242use starknet_api:: test_utils:: {
4343 NonceManager ,
44+ CURRENT_BLOCK_NUMBER ,
4445 DEFAULT_L1_DATA_GAS_MAX_AMOUNT ,
4546 DEFAULT_L1_GAS_AMOUNT ,
4647 DEFAULT_L2_GAS_MAX_AMOUNT ,
@@ -55,9 +56,12 @@ use starknet_api::transaction::fields::{
5556 ContractAddressSalt ,
5657 Fee ,
5758 GasVectorComputationMode ,
59+ ProofFacts ,
5860 Resource ,
5961 ResourceBounds ,
62+ SnosProofFacts ,
6063 ValidResourceBounds ,
64+ VIRTUAL_SNOS ,
6165} ;
6266use starknet_api:: transaction:: {
6367 DeclareTransaction ,
@@ -79,6 +83,7 @@ use starknet_api::{
7983} ;
8084use starknet_types_core:: felt:: Felt ;
8185
86+ use crate :: abi:: constants:: STORED_BLOCK_HASH_BUFFER ;
8287use crate :: context:: { BlockContext , TransactionContext } ;
8388use crate :: execution:: call_info:: CallInfo ;
8489use crate :: execution:: contract_class:: TrackedResource ;
@@ -2191,3 +2196,111 @@ fn test_missing_validate_entrypoint_rejects(
21912196 if ret == retdata![ Felt :: from_hex( ENTRYPOINT_NOT_FOUND_ERROR ) . unwrap( ) ]
21922197 ) ;
21932198}
2199+
2200+ /// Converts SnosProofFacts to ProofFacts for testing.
2201+ fn snos_to_proof_facts ( snos : SnosProofFacts ) -> ProofFacts {
2202+ vec ! [
2203+ felt!( VIRTUAL_SNOS ) ,
2204+ snos. program_hash,
2205+ felt!( snos. block_number. 0 ) ,
2206+ snos. block_hash. 0 ,
2207+ snos. config_hash,
2208+ ]
2209+ . into ( )
2210+ }
2211+
2212+ /// Returns valid SNOS proof facts.
2213+ /// Block number must be more than STORED_BLOCK_HASH_BUFFER blocks old (difference > buffer).
2214+ fn valid_snos_proof_facts ( ) -> SnosProofFacts {
2215+ SnosProofFacts {
2216+ program_hash : felt ! ( 0x1_u64 ) ,
2217+ block_number : BlockNumber ( CURRENT_BLOCK_NUMBER - STORED_BLOCK_HASH_BUFFER - 1 ) ,
2218+ block_hash : BlockHash ( felt ! ( 0xABCDEF_u64 ) ) ,
2219+ config_hash : felt ! ( 0x2_u64 ) ,
2220+ }
2221+ }
2222+
2223+ /// Returns valid proof facts.
2224+ fn valid_proof_facts ( ) -> ProofFacts {
2225+ snos_to_proof_facts ( valid_snos_proof_facts ( ) )
2226+ }
2227+
2228+ /// Returns invalid proof_facts with a too recent block number.
2229+ fn too_recent_block_proof_facts ( ) -> ProofFacts {
2230+ snos_to_proof_facts ( SnosProofFacts {
2231+ block_number : BlockNumber ( CURRENT_BLOCK_NUMBER - STORED_BLOCK_HASH_BUFFER ) ,
2232+ ..valid_snos_proof_facts ( )
2233+ } )
2234+ }
2235+
2236+ /// Returns invalid proof_facts with a mismatched block hash.
2237+ fn mismatched_hash_proof_facts ( ) -> ProofFacts {
2238+ snos_to_proof_facts ( SnosProofFacts {
2239+ block_hash : BlockHash ( felt ! ( 0xDEADBEEF_u64 ) ) ,
2240+ ..valid_snos_proof_facts ( )
2241+ } )
2242+ }
2243+
2244+ /// Returns invalid proof_facts with a block number greater than the current block number.
2245+ fn future_block_proof_facts ( ) -> ProofFacts {
2246+ snos_to_proof_facts ( SnosProofFacts {
2247+ block_number : BlockNumber ( CURRENT_BLOCK_NUMBER + 100 ) ,
2248+ ..valid_snos_proof_facts ( )
2249+ } )
2250+ }
2251+
2252+ /// Tests the `validate_proof_facts` function for Invoke V3 transactions.
2253+ /// Covers: valid proof facts, too recent block number, mismatched block hash, and future block.
2254+ #[ rstest]
2255+ #[ case:: valid_proof_facts( valid_proof_facts( ) , CURRENT_BLOCK_NUMBER ) ]
2256+ #[ should_panic( expected = "is too recent" ) ]
2257+ #[ case:: too_recent_block( too_recent_block_proof_facts( ) , CURRENT_BLOCK_NUMBER ) ]
2258+ #[ should_panic( expected = "Block hash mismatch" ) ]
2259+ #[ case:: mismatched_block_hash( mismatched_hash_proof_facts( ) , CURRENT_BLOCK_NUMBER ) ]
2260+ #[ should_panic( expected = "is less than proof block number" ) ]
2261+ #[ case:: future_block( future_block_proof_facts( ) , CURRENT_BLOCK_NUMBER ) ]
2262+ fn test_validate_proof_facts (
2263+ default_all_resource_bounds : ValidResourceBounds ,
2264+ #[ case] proof_facts : ProofFacts ,
2265+ #[ case] current_block_number : u64 ,
2266+ ) {
2267+ let mut block_context = BlockContext :: create_for_account_testing ( ) ;
2268+ block_context. block_info . block_number = BlockNumber ( current_block_number) ;
2269+
2270+ let chain_info = & block_context. chain_info ;
2271+ let account = FeatureContract :: AccountWithoutValidations ( CairoVersion :: Cairo0 ) ;
2272+ let mut state = test_state ( chain_info, BALANCE , & [ ( account, 1u16 ) ] ) ;
2273+ let account_address = account. get_instance_address ( 0_u16 ) ;
2274+
2275+ // Get the block hash contract address from versioned constants.
2276+ let block_hash_contract_address = block_context
2277+ . versioned_constants
2278+ . os_constants
2279+ . os_contract_addresses
2280+ . block_hash_contract_address ( ) ;
2281+
2282+ // Store block hashes for test blocks.
2283+ // Valid block number: more than STORED_BLOCK_HASH_BUFFER blocks old.
2284+ let valid_proof_block_number = CURRENT_BLOCK_NUMBER - STORED_BLOCK_HASH_BUFFER - 1 ;
2285+ let stored_block_hash = felt ! ( 0xABCDEF_u64 ) ;
2286+
2287+ // Store the block hash in the block hash contract.
2288+ state
2289+ . set_storage_at (
2290+ block_hash_contract_address,
2291+ StorageKey :: try_from ( felt ! ( valid_proof_block_number) ) . unwrap ( ) ,
2292+ stored_block_hash,
2293+ )
2294+ . unwrap ( ) ;
2295+
2296+ let tx = invoke_tx_with_default_flags ( invoke_tx_args ! {
2297+ sender_address: account_address,
2298+ resource_bounds: default_all_resource_bounds,
2299+ version: TransactionVersion :: THREE ,
2300+ proof_facts: proof_facts,
2301+ } ) ;
2302+
2303+ // Run only pre-validation stage (which includes proof facts validation).
2304+ let tx_context = block_context. to_tx_context ( & tx) ;
2305+ tx. perform_pre_validation_stage ( & mut state, & tx_context) . unwrap ( ) ;
2306+ }
0 commit comments