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