@@ -3,6 +3,7 @@ use std::sync::{Arc, LazyLock};
33
44use blockifier:: abi:: constants:: STORED_BLOCK_HASH_BUFFER ;
55use blockifier:: blockifier_versioned_constants:: VersionedConstants ;
6+ use blockifier:: test_utils:: contracts:: FeatureContractTrait ;
67use blockifier:: test_utils:: dict_state_reader:: DictStateReader ;
78use blockifier:: test_utils:: ALIAS_CONTRACT_ADDRESS ;
89use blockifier:: transaction:: test_utils:: ExpectedExecutionInfo ;
@@ -15,7 +16,7 @@ use rstest::rstest;
1516use starknet_api:: abi:: abi_utils:: { get_storage_var_address, selector_from_name} ;
1617use starknet_api:: block:: { BlockInfo , BlockNumber , BlockTimestamp , GasPrice } ;
1718use starknet_api:: contract_class:: compiled_class_hash:: { HashVersion , HashableCompiledClass } ;
18- use starknet_api:: contract_class:: { ClassInfo , ContractClass } ;
19+ use starknet_api:: contract_class:: { ClassInfo , ContractClass , SierraVersion } ;
1920use starknet_api:: core:: {
2021 calculate_contract_address,
2122 ClassHash ,
@@ -2221,3 +2222,106 @@ async fn test_reverted_call() {
22212222 {expected_changed_addresses:#?}"
22222223 ) ;
22232224}
2225+
2226+ /// Tests that the OS correctly handles calls between Cairo 1.0 contracts that count resources by
2227+ /// cairo steps and sierra gas.
2228+ #[ rstest]
2229+ #[ tokio:: test]
2230+ async fn test_resources_type ( ) {
2231+ let test_contract = FeatureContract :: TestContract ( CairoVersion :: Cairo1 ( RunnableCairo1 :: Casm ) ) ;
2232+ let ( mut test_manager, [ sierra_gas_contract_address] ) =
2233+ TestManager :: < DictStateReader > :: new_with_default_initial_state ( [ (
2234+ test_contract,
2235+ calldata ! [ Felt :: ZERO , Felt :: ZERO ] ,
2236+ ) ] )
2237+ . await ;
2238+
2239+ // Define an updated Cairo 1.0 contract by overriding the encoded sierra version.
2240+ let mut cairo_steps_contract_sierra = test_contract. get_sierra ( ) ;
2241+ let min_sierra_version =
2242+ VersionedConstants :: latest_constants ( ) . min_sierra_version_for_sierra_gas . clone ( ) ;
2243+ let ( old_major, old_minor, old_patch) = ( 1 , 5 , 0 ) ;
2244+ let old_sierra_version = SierraVersion :: new ( old_major, old_minor, old_patch) ;
2245+ assert ! ( old_sierra_version < min_sierra_version) ;
2246+
2247+ // Override version.
2248+ assert ! ( cairo_steps_contract_sierra. get_sierra_version( ) . unwrap( ) >= min_sierra_version) ;
2249+ cairo_steps_contract_sierra. sierra_program [ 0 ] = Felt :: from ( old_major) ;
2250+ cairo_steps_contract_sierra. sierra_program [ 1 ] = Felt :: from ( old_minor) ;
2251+ cairo_steps_contract_sierra. sierra_program [ 2 ] = Felt :: from ( old_patch) ;
2252+ assert_eq ! ( cairo_steps_contract_sierra. get_sierra_version( ) . unwrap( ) , old_sierra_version) ;
2253+
2254+ // Declare it.
2255+ let cairo_steps_class_hash = cairo_steps_contract_sierra. calculate_class_hash ( ) ;
2256+ let compiled_class_hash = test_contract. get_compiled_class_hash ( & HashVersion :: V2 ) ;
2257+ let declare_tx_args = declare_tx_args ! {
2258+ sender_address: * FUNDED_ACCOUNT_ADDRESS ,
2259+ class_hash: cairo_steps_class_hash,
2260+ compiled_class_hash,
2261+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
2262+ nonce: test_manager. next_nonce( * FUNDED_ACCOUNT_ADDRESS ) ,
2263+ } ;
2264+ let account_declare_tx = declare_tx ( declare_tx_args) ;
2265+ let class_info = match test_contract. get_class ( ) {
2266+ ContractClass :: V0 ( _) => panic ! ( "Expected Cairo 1.0 contract" ) ,
2267+ ContractClass :: V1 ( ( contract_class, _sierra_version) ) => ClassInfo {
2268+ contract_class : ContractClass :: V1 ( ( contract_class, old_sierra_version. clone ( ) ) ) ,
2269+ sierra_program_length : cairo_steps_contract_sierra. sierra_program . len ( ) ,
2270+ abi_length : cairo_steps_contract_sierra. abi . len ( ) ,
2271+ sierra_version : old_sierra_version,
2272+ } ,
2273+ } ;
2274+ let tx =
2275+ DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS ) . unwrap ( ) ;
2276+ test_manager. add_cairo1_declare_tx ( tx, & cairo_steps_contract_sierra) ;
2277+
2278+ // Deploy it.
2279+ let ( deploy_tx, cairo_steps_contract_address) = get_deploy_contract_tx_and_address_with_salt (
2280+ cairo_steps_class_hash,
2281+ calldata ! [ Felt :: ZERO , Felt :: ZERO ] ,
2282+ test_manager. next_nonce ( * FUNDED_ACCOUNT_ADDRESS ) ,
2283+ * NON_TRIVIAL_RESOURCE_BOUNDS ,
2284+ ContractAddressSalt ( Felt :: ZERO ) ,
2285+ ) ;
2286+ test_manager. add_invoke_tx ( deploy_tx, None ) ;
2287+
2288+ // Test recursive calling.
2289+ let ( key, value) = ( Felt :: from ( 123 ) , Felt :: from ( 45 ) ) ;
2290+ let calldata_0 = vec ! [
2291+ * * cairo_steps_contract_address,
2292+ selector_from_name( "test_call_contract" ) . 0 ,
2293+ Felt :: from( 5 ) , // Outer calldata length.
2294+ * * sierra_gas_contract_address,
2295+ selector_from_name( "test_storage_write" ) . 0 ,
2296+ Felt :: TWO , // Inner calldata length.
2297+ key,
2298+ value,
2299+ ] ;
2300+ let calldata_1 = vec ! [
2301+ * * sierra_gas_contract_address,
2302+ selector_from_name( "test_storage_write" ) . 0 ,
2303+ Felt :: TWO ,
2304+ key + Felt :: ONE ,
2305+ value + Felt :: ONE ,
2306+ ] ;
2307+ let calldata = create_calldata (
2308+ sierra_gas_contract_address,
2309+ "test_call_two_contracts" ,
2310+ & [ calldata_0, calldata_1] . concat ( ) ,
2311+ ) ;
2312+ test_manager. add_funded_account_invoke ( invoke_tx_args ! { calldata } ) ;
2313+
2314+ // Run test and check storage updates.
2315+ let test_output = test_manager
2316+ . execute_test_with_default_block_contexts ( & TestParameters {
2317+ use_kzg_da : true ,
2318+ ..Default :: default ( )
2319+ } )
2320+ . await ;
2321+
2322+ let expected_storage_updates =
2323+ HashMap :: from ( [ ( key, value) , ( key + Felt :: ONE , value + Felt :: ONE ) ] ) ;
2324+ test_output. perform_default_validations ( ) ;
2325+ test_output. assert_storage_diff_eq ( cairo_steps_contract_address, HashMap :: default ( ) ) ;
2326+ test_output. assert_storage_diff_eq ( sierra_gas_contract_address, expected_storage_updates) ;
2327+ }
0 commit comments