@@ -99,6 +99,9 @@ use starknet_api::transaction::fields::{
9999 ResourceBounds ,
100100 Tip ,
101101 TransactionSignature ,
102+ PROOF_VERSION ,
103+ VIRTUAL_OS_OUTPUT_VERSION ,
104+ VIRTUAL_SNOS ,
102105} ;
103106use starknet_api:: transaction:: {
104107 CalculateContractAddress ,
@@ -110,7 +113,7 @@ use starknet_api::transaction::{
110113 TransactionOffsetInBlock ,
111114 TransactionVersion ,
112115} ;
113- use starknet_api:: { calldata, contract_address} ;
116+ use starknet_api:: { calldata, contract_address, proof_facts } ;
114117use starknet_committer:: block_committer:: input:: StateDiff ;
115118use starknet_committer:: db:: facts_db:: FactsDb ;
116119use starknet_committer:: db:: forest_trait:: StorageInitializer ;
@@ -594,6 +597,46 @@ impl BlobFactory {
594597 calldata : & [ Felt ] ,
595598 with_fee_charge : bool ,
596599 should_revert : bool ,
600+ ) {
601+ self . make_operator_invoke_tx_with_proof (
602+ address,
603+ function_name,
604+ calldata,
605+ with_fee_charge,
606+ should_revert,
607+ ProofFacts :: default ( ) ,
608+ )
609+ }
610+
611+ /// Same as [Self::make_operator_invoke_tx], but with virtual SNOS proof facts.
612+ fn make_operator_proof_tx (
613+ & mut self ,
614+ address : ContractAddress ,
615+ function_name : & str ,
616+ calldata : & [ Felt ] ,
617+ with_fee_charge : bool ,
618+ should_revert : bool ,
619+ ) {
620+ self . make_operator_invoke_tx_with_proof (
621+ address,
622+ function_name,
623+ calldata,
624+ with_fee_charge,
625+ should_revert,
626+ self . make_snos_proof_facts ( ) ,
627+ ) ;
628+ }
629+
630+ /// Utility method to share code between invokes with and without proofs. Should not be called
631+ /// directly, use [Self::make_operator_invoke_tx] or [Self::make_operator_proof_tx] instead.
632+ fn make_operator_invoke_tx_with_proof (
633+ & mut self ,
634+ address : ContractAddress ,
635+ function_name : & str ,
636+ calldata : & [ Felt ] ,
637+ with_fee_charge : bool ,
638+ should_revert : bool ,
639+ proof_facts : ProofFacts ,
597640 ) {
598641 let nonce = self . nonce_manager . next ( * OPERATOR_ADDRESS ) ;
599642 let resource_bounds = if with_fee_charge {
@@ -613,7 +656,7 @@ impl BlobFactory {
613656 fee_data_availability_mode : DataAvailabilityMode :: L1 ,
614657 account_deployment_data : AccountDeploymentData :: default ( ) ,
615658 paymaster_data : PaymasterData :: default ( ) ,
616- proof_facts : ProofFacts :: default ( ) ,
659+ proof_facts,
617660 } ;
618661 let tx_hash = rpc_tx_unsigned
619662 . calculate_transaction_hash ( & CHAIN_ID , & TransactionVersion :: THREE )
@@ -632,6 +675,43 @@ impl BlobFactory {
632675 self . next_txs . push ( TxData { executable : executable. into ( ) , internal, should_revert } ) ;
633676 }
634677
678+ /// Constructs valid SNOS proof facts referencing the hash of the retrospective block.
679+ fn make_snos_proof_facts ( & self ) -> ProofFacts {
680+ let block_context = self . next_block_context ( ) ;
681+ let retrospective_block_number = block_context
682+ . block_info ( )
683+ . block_number
684+ . 0
685+ . checked_sub ( STORED_BLOCK_HASH_BUFFER )
686+ . unwrap_or_else ( || {
687+ panic ! (
688+ "The current block number must be at least {STORED_BLOCK_HASH_BUFFER} blocks \
689+ ahead of the first block."
690+ )
691+ } ) ;
692+ let retrospective_block_hash =
693+ self . blocks [ usize:: try_from ( retrospective_block_number) . unwrap ( ) ] . block_hash ;
694+ let program_hash = * block_context
695+ . versioned_constants ( )
696+ . os_constants
697+ . allowed_virtual_os_program_hashes
698+ . first ( )
699+ . expect ( "No allowed virtual OS program hashes in versioned constants" ) ;
700+ let config_hash = OsChainInfo :: from ( & self . chain_info )
701+ . compute_virtual_os_config_hash ( )
702+ . expect ( "Failed to compute virtual OS config hash" ) ;
703+ proof_facts ! [
704+ PROOF_VERSION ,
705+ VIRTUAL_SNOS ,
706+ program_hash,
707+ VIRTUAL_OS_OUTPUT_VERSION ,
708+ Felt :: from( retrospective_block_number) ,
709+ retrospective_block_hash. 0 ,
710+ config_hash,
711+ Felt :: ZERO , // l2_to_l1_messages_segment_size
712+ ]
713+ }
714+
635715 fn make_operator_deploy_tx (
636716 & mut self ,
637717 contract_to_deploy : FeatureContract ,
@@ -957,6 +1037,14 @@ async fn test_make_data() {
9571037 false , // should not revert
9581038 ) ;
9591039 blob_factory. close_block ( ) . await ;
1040+ blob_factory. make_operator_proof_tx (
1041+ test_contract_address_0,
1042+ "test_storage_read_write" ,
1043+ & [ Felt :: from ( 0x4000u32 ) , Felt :: from ( 0x4000u32 ) ] ,
1044+ true , // charge fee
1045+ false , // should not revert
1046+ ) ;
1047+ blob_factory. close_block ( ) . await ;
9601048 blob_factory. make_operator_invoke_tx (
9611049 test_contract_address_0,
9621050 "catch_write_revert_panic" ,
0 commit comments