@@ -2640,3 +2640,74 @@ async fn test_meta_tx() {
26402640 test_output. assert_storage_diff_eq ( meta_tx_contract_address, expected_meta_tx_contract_diffs) ;
26412641 test_output. assert_storage_diff_eq ( tx_info_contract_address, expected_tx_info_writer_diffs) ;
26422642}
2643+
2644+ #[ rstest]
2645+ #[ tokio:: test]
2646+ /// Verifies that a contract can be declared in one block and deployed in a later block:
2647+ /// 1. Class declarations persist across block boundaries.
2648+ /// 2. The deployed contract's storage is properly initialized.
2649+ /// 3. The class hash to compiled class hash mapping appears in the state diff.
2650+ async fn test_declare_and_deploy_in_separate_blocks ( ) {
2651+ let ( mut test_manager, _) =
2652+ TestManager :: < DictStateReader > :: new_with_default_initial_state ( [ ] ) . await ;
2653+
2654+ // Declare a test contract.
2655+ let test_contract = FeatureContract :: TestContract ( CairoVersion :: Cairo1 ( RunnableCairo1 :: Casm ) ) ;
2656+ let test_contract_sierra = test_contract. get_sierra ( ) ;
2657+ let class_hash = test_contract_sierra. calculate_class_hash ( ) ;
2658+ let compiled_class_hash = test_contract. get_compiled_class_hash ( & HashVersion :: V2 ) ;
2659+ let declare_tx_args = declare_tx_args ! {
2660+ sender_address: * FUNDED_ACCOUNT_ADDRESS ,
2661+ class_hash,
2662+ compiled_class_hash,
2663+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
2664+ nonce: test_manager. next_nonce( * FUNDED_ACCOUNT_ADDRESS ) ,
2665+ } ;
2666+ let account_declare_tx = declare_tx ( declare_tx_args) ;
2667+ let class_info = get_class_info_of_feature_contract ( test_contract) ;
2668+ let tx =
2669+ DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS ) . unwrap ( ) ;
2670+ test_manager. add_cairo1_declare_tx ( tx, & test_contract_sierra) ;
2671+
2672+ // Move on to the next block, with an empty block in between.
2673+ test_manager. move_to_next_block ( ) ;
2674+ test_manager. move_to_next_block ( ) ;
2675+
2676+ // Deploy the test contract using the deploy contract syscall.
2677+ let ( constructor_arg1, constructor_arg2) = ( Felt :: from ( 7 ) , Felt :: from ( 90 ) ) ;
2678+ let salt = ContractAddressSalt ( Felt :: ZERO ) ;
2679+ let ( deploy_tx, address) = get_deploy_contract_tx_and_address_with_salt (
2680+ class_hash,
2681+ calldata ! [ constructor_arg1, constructor_arg2] ,
2682+ test_manager. next_nonce ( * FUNDED_ACCOUNT_ADDRESS ) ,
2683+ * NON_TRIVIAL_RESOURCE_BOUNDS ,
2684+ salt,
2685+ ) ;
2686+ test_manager. add_invoke_tx ( deploy_tx, None ) ;
2687+
2688+ // Run the test and verify the storage changes.
2689+ let test_output = test_manager
2690+ . execute_test_with_default_block_contexts ( & TestParameters {
2691+ use_kzg_da : true ,
2692+ ..Default :: default ( )
2693+ } )
2694+ . await ;
2695+ test_output. perform_default_validations ( ) ;
2696+ // The test contract constructor writes the sum of the two input arguments to storage.
2697+ test_output. assert_storage_diff_eq (
2698+ address,
2699+ HashMap :: from ( [ (
2700+ * * get_storage_var_address ( "my_storage_var" , & [ ] ) ,
2701+ constructor_arg1 + constructor_arg2,
2702+ ) ] ) ,
2703+ ) ;
2704+ assert_eq ! (
2705+ test_output
2706+ . decompressed_state_diff
2707+ . class_hash_to_compiled_class_hash
2708+ . get( & class_hash)
2709+ . unwrap( )
2710+ . 0 ,
2711+ compiled_class_hash. 0
2712+ ) ;
2713+ }
0 commit comments