@@ -13,7 +13,7 @@ use cairo_vm::types::builtin_name::BuiltinName;
1313use expect_test:: expect;
1414use rstest:: rstest;
1515use starknet_api:: abi:: abi_utils:: { get_storage_var_address, selector_from_name} ;
16- use starknet_api:: block:: { BlockNumber , BlockTimestamp } ;
16+ use starknet_api:: block:: { BlockInfo , BlockNumber , BlockTimestamp } ;
1717use starknet_api:: contract_class:: compiled_class_hash:: { HashVersion , HashableCompiledClass } ;
1818use starknet_api:: contract_class:: { ClassInfo , ContractClass } ;
1919use starknet_api:: core:: {
@@ -1848,3 +1848,136 @@ async fn test_deploy_syscall() {
18481848 . is_subset( & allowed_changed_addresses)
18491849 ) ;
18501850}
1851+
1852+ #[ rstest]
1853+ #[ tokio:: test]
1854+ async fn test_block_info ( #[ values( true , false ) ] is_cairo0 : bool ) {
1855+ let cairo_version =
1856+ if is_cairo0 { CairoVersion :: Cairo0 } else { CairoVersion :: Cairo1 ( RunnableCairo1 :: Casm ) } ;
1857+ let test_contract = FeatureContract :: BlockInfoTestContract ( cairo_version) ;
1858+ let class_hash = get_class_hash_of_feature_contract ( test_contract) ;
1859+ let is_validate = Felt :: ONE ;
1860+ let ( mut test_manager, _) =
1861+ TestManager :: < DictStateReader > :: new_with_default_initial_state ( [ ] ) . await ;
1862+
1863+ // Prepare block info data.
1864+ let next_block_number = test_manager. initial_state . next_block_number ;
1865+ let rounded_block_number = ( next_block_number. 0 / 100 ) * 100 ;
1866+ let next_block_timestamp = BlockInfo :: create_for_testing ( ) . block_timestamp . 0 ;
1867+ let rounded_next_block_timestamp = ( next_block_timestamp / 3600 ) * 3600 ;
1868+ assert ! (
1869+ rounded_block_number != next_block_number. 0 ,
1870+ "For the test the rounded block number must be different from the next block number; both \
1871+ are {rounded_block_number}."
1872+ ) ;
1873+ assert ! (
1874+ rounded_next_block_timestamp != next_block_timestamp,
1875+ "For the test the rounded block timestamp must be different from the next block \
1876+ timestamp; both are {rounded_next_block_timestamp}."
1877+ ) ;
1878+
1879+ // Declare the block info contract.
1880+ let class_info = get_class_info_of_feature_contract ( test_contract) ;
1881+ if is_cairo0 {
1882+ let declare_args = declare_tx_args ! {
1883+ version: TransactionVersion :: ZERO ,
1884+ max_fee: Fee ( 1_000_000_000_000_000 ) ,
1885+ class_hash,
1886+ sender_address: * FUNDED_ACCOUNT_ADDRESS ,
1887+ nonce: Nonce :: default ( ) ,
1888+ } ;
1889+ let account_declare_tx = declare_tx ( declare_args) ;
1890+ let tx = DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS )
1891+ . unwrap ( ) ;
1892+ test_manager. add_cairo0_declare_tx ( tx, class_hash) ;
1893+ } else {
1894+ let test_contract_sierra = test_contract. get_sierra ( ) ;
1895+ let test_contract_compiled_class_hash =
1896+ test_contract. get_compiled_class_hash ( & HashVersion :: V2 ) ;
1897+ let declare_tx_args = declare_tx_args ! {
1898+ sender_address: * FUNDED_ACCOUNT_ADDRESS ,
1899+ class_hash,
1900+ compiled_class_hash: test_contract_compiled_class_hash,
1901+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1902+ nonce: test_manager. next_nonce( * FUNDED_ACCOUNT_ADDRESS ) ,
1903+ } ;
1904+ let account_declare_tx = declare_tx ( declare_tx_args) ;
1905+ let declare_tx =
1906+ DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS )
1907+ . unwrap ( ) ;
1908+ test_manager. add_cairo1_declare_tx ( declare_tx. clone ( ) , & test_contract_sierra) ;
1909+ }
1910+
1911+ // Prepare to deploy: precompute the address.
1912+ let salt = Felt :: ZERO ;
1913+ let block_info_account_address = calculate_contract_address (
1914+ ContractAddressSalt ( salt) ,
1915+ class_hash,
1916+ & calldata ! [ is_validate] ,
1917+ ContractAddress :: default ( ) ,
1918+ )
1919+ . unwrap ( ) ;
1920+
1921+ // Fund the address.
1922+ test_manager. add_fund_address_tx_with_default_amount ( block_info_account_address) ;
1923+
1924+ // Deploy the contract using a DeployAccount transaction.
1925+ let deploy_account_tx_args = deploy_account_tx_args ! {
1926+ class_hash,
1927+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1928+ contract_address_salt: ContractAddressSalt ( Felt :: ZERO ) ,
1929+ constructor_calldata: calldata![ is_validate] ,
1930+ nonce: Nonce :: default ( ) ,
1931+ } ;
1932+ let deploy_account_tx = DeployAccountTransaction :: create (
1933+ deploy_account_tx (
1934+ deploy_account_tx_args,
1935+ test_manager. next_nonce ( block_info_account_address) ,
1936+ ) ,
1937+ & CHAIN_ID_FOR_TESTS ,
1938+ )
1939+ . unwrap ( ) ;
1940+ test_manager. add_deploy_account_tx ( deploy_account_tx) ;
1941+
1942+ // Test validate_declare.
1943+ let empty_contract = FeatureContract :: Empty ( CairoVersion :: Cairo1 ( RunnableCairo1 :: Casm ) ) ;
1944+ let empty_class_hash = get_class_hash_of_feature_contract ( empty_contract) ;
1945+ let empty_compiled_class_hash = empty_contract. get_compiled_class_hash ( & HashVersion :: V2 ) ;
1946+ let declare_tx_args = declare_tx_args ! {
1947+ sender_address: block_info_account_address,
1948+ class_hash: empty_class_hash,
1949+ compiled_class_hash: empty_compiled_class_hash,
1950+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1951+ nonce: test_manager. next_nonce( block_info_account_address) ,
1952+ } ;
1953+ let account_declare_tx = declare_tx ( declare_tx_args) ;
1954+ let class_info = get_class_info_of_feature_contract ( empty_contract) ;
1955+ let declare_tx =
1956+ DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS ) . unwrap ( ) ;
1957+ test_manager. add_cairo1_declare_tx ( declare_tx. clone ( ) , & empty_contract. get_sierra ( ) ) ;
1958+
1959+ // Test `validate` and `execute`.
1960+ let invoke_args = invoke_tx_args ! {
1961+ sender_address: block_info_account_address,
1962+ nonce: test_manager. next_nonce( block_info_account_address) ,
1963+ // Dummy contract address and selector, calldata length of zero.
1964+ calldata: calldata![ Felt :: ZERO , Felt :: ZERO , Felt :: ZERO ] ,
1965+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1966+ } ;
1967+ test_manager. add_invoke_tx_from_args ( invoke_args, & CHAIN_ID_FOR_TESTS , None ) ;
1968+
1969+ // Test `constructor` in execute mode.
1970+ let ctor_calldata = [ Felt :: ZERO ] ; // Not validate mode (execute mode).
1971+ let salt = Felt :: ZERO ;
1972+ let calldata = create_calldata (
1973+ * FUNDED_ACCOUNT_ADDRESS ,
1974+ "deploy_contract" ,
1975+ & [ class_hash. 0 , salt, ctor_calldata. len ( ) . into ( ) , ctor_calldata[ 0 ] ] ,
1976+ ) ;
1977+ test_manager. add_funded_account_invoke ( invoke_tx_args ! { calldata } ) ;
1978+
1979+ // Run the test.
1980+ let test_output =
1981+ test_manager. execute_test_with_default_block_contexts ( & TestParameters :: default ( ) ) . await ;
1982+ test_output. perform_default_validations ( ) ;
1983+ }
0 commit comments