1- use std:: collections:: HashMap ;
1+ use std:: collections:: { HashMap , HashSet } ;
22use std:: sync:: { Arc , LazyLock } ;
33
44use blockifier:: abi:: constants:: STORED_BLOCK_HASH_BUFFER ;
55use blockifier:: blockifier_versioned_constants:: VersionedConstants ;
66use blockifier:: test_utils:: dict_state_reader:: DictStateReader ;
7+ use blockifier:: test_utils:: ALIAS_CONTRACT_ADDRESS ;
78use blockifier:: transaction:: test_utils:: ExpectedExecutionInfo ;
89use blockifier_test_utils:: cairo_versions:: { CairoVersion , RunnableCairo1 } ;
910use blockifier_test_utils:: calldata:: create_calldata;
@@ -78,6 +79,7 @@ use starknet_committer::patricia_merkle_tree::types::CompiledClassHash;
7879use starknet_core:: crypto:: ecdsa_sign;
7980use starknet_crypto:: { get_public_key, Signature } ;
8081use starknet_os:: hints:: hint_implementation:: deprecated_compiled_class:: class_hash:: compute_deprecated_class_hash;
82+ use starknet_os:: hints:: vars:: Const ;
8183use starknet_os:: io:: os_output:: MessageToL2 ;
8284use starknet_types_core:: felt:: Felt ;
8385use starknet_types_core:: hash:: { Pedersen , StarkHash } ;
@@ -91,7 +93,12 @@ use crate::special_contracts::{
9193 V1_BOUND_CAIRO1_CONTRACT_CASM ,
9294 V1_BOUND_CAIRO1_CONTRACT_SIERRA ,
9395} ;
94- use crate :: test_manager:: { TestManager , TestParameters , FUNDED_ACCOUNT_ADDRESS } ;
96+ use crate :: test_manager:: {
97+ TestManager ,
98+ TestParameters ,
99+ FUNDED_ACCOUNT_ADDRESS ,
100+ STRK_FEE_TOKEN_ADDRESS ,
101+ } ;
95102use crate :: utils:: {
96103 divide_vec_into_n_parts,
97104 get_class_hash_of_feature_contract,
@@ -1766,3 +1773,78 @@ async fn test_deprecated_tx_info() {
17661773 test_output. assert_account_balance_change ( tx_info_account_address) ;
17671774 test_output. assert_account_balance_change ( contract_address ! ( TEST_SEQUENCER_ADDRESS ) ) ;
17681775}
1776+
1777+ #[ rstest]
1778+ #[ tokio:: test]
1779+ async fn test_deploy_syscall ( ) {
1780+ let test_contract = FeatureContract :: TestContract ( CairoVersion :: Cairo0 ) ;
1781+ let empty_contract = FeatureContract :: Empty ( CairoVersion :: Cairo0 ) ;
1782+ let class_hash = get_class_hash_of_feature_contract ( test_contract) ;
1783+ let empty_class_hash = get_class_hash_of_feature_contract ( empty_contract) ;
1784+ // Initialize the test manager with the test contract and empty contract already declared.
1785+ // We can ignore the addresses of the deployed instances.
1786+ let ( mut test_manager, _) = TestManager :: < DictStateReader > :: new_with_default_initial_state ( [
1787+ ( test_contract, calldata ! [ Felt :: ZERO , Felt :: ZERO ] ) ,
1788+ ( empty_contract, calldata ! [ ] ) ,
1789+ ] )
1790+ . await ;
1791+
1792+ let ctor_calldata = vec ! [ Felt :: from( 1979 ) , Felt :: from( 1989 ) ] ;
1793+ let salt = ContractAddressSalt ( Felt :: from ( 12 ) ) ;
1794+
1795+ // Call deploy_contract(...).
1796+ let ( deploy_tx, deployed_test_address) = get_deploy_contract_tx_and_address_with_salt (
1797+ class_hash,
1798+ Calldata ( Arc :: new ( ctor_calldata. clone ( ) ) ) ,
1799+ test_manager. next_nonce ( * FUNDED_ACCOUNT_ADDRESS ) ,
1800+ * NON_TRIVIAL_RESOURCE_BOUNDS ,
1801+ salt,
1802+ ) ;
1803+ test_manager. add_invoke_tx ( deploy_tx, None ) ;
1804+ let expected_storage_updates = HashMap :: from ( [ (
1805+ deployed_test_address,
1806+ HashMap :: from ( [ (
1807+ StarknetStorageKey ( ctor_calldata[ 0 ] . try_into ( ) . unwrap ( ) ) ,
1808+ StarknetStorageValue ( ctor_calldata[ 1 ] ) ,
1809+ ) ] ) ,
1810+ ) ] ) ;
1811+
1812+ // Deploy a contract with no constructor using deploy syscall.
1813+ let calldata = create_calldata (
1814+ * FUNDED_ACCOUNT_ADDRESS ,
1815+ "deploy_contract" ,
1816+ & [ empty_class_hash. 0 , salt. 0 , Felt :: ZERO ] ,
1817+ ) ;
1818+ test_manager. add_funded_account_invoke ( invoke_tx_args ! { calldata } ) ;
1819+
1820+ // Run the test and verify storage changes.
1821+ let test_output =
1822+ test_manager. execute_test_with_default_block_contexts ( & TestParameters :: default ( ) ) . await ;
1823+ let perform_global_validations = true ;
1824+ test_output. perform_validations (
1825+ perform_global_validations,
1826+ Some ( & StateDiff { storage_updates : expected_storage_updates, ..Default :: default ( ) } ) ,
1827+ ) ;
1828+
1829+ // Make sure only the newly deployed contract and the fee contract have changed storage.
1830+ let block_hash_contract_address = ContractAddress (
1831+ Const :: BlockHashContractAddress . fetch_from_os_program ( ) . unwrap ( ) . try_into ( ) . unwrap ( ) ,
1832+ ) ;
1833+ let allowed_changed_addresses = HashSet :: from ( [
1834+ & deployed_test_address,
1835+ & * STRK_FEE_TOKEN_ADDRESS ,
1836+ & * ALIAS_CONTRACT_ADDRESS ,
1837+ & block_hash_contract_address,
1838+ ] ) ;
1839+ assert ! (
1840+ HashSet :: from_iter(
1841+ test_output
1842+ . decompressed_state_diff
1843+ . storage_updates
1844+ . into_keys( )
1845+ . collect:: <Vec <_>>( )
1846+ . iter( )
1847+ )
1848+ . is_subset( & allowed_changed_addresses)
1849+ ) ;
1850+ }
0 commit comments