@@ -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:: {
@@ -1788,3 +1788,136 @@ async fn test_deploy_syscall() {
17881788 . is_subset( & allowed_changed_addresses)
17891789 ) ;
17901790}
1791+
1792+ #[ rstest]
1793+ #[ tokio:: test]
1794+ async fn test_block_info ( #[ values( true , false ) ] is_cairo0 : bool ) {
1795+ let cairo_version =
1796+ if is_cairo0 { CairoVersion :: Cairo0 } else { CairoVersion :: Cairo1 ( RunnableCairo1 :: Casm ) } ;
1797+ let test_contract = FeatureContract :: BlockInfoTestContract ( cairo_version) ;
1798+ let class_hash = get_class_hash_of_feature_contract ( test_contract) ;
1799+ let is_validate = Felt :: ONE ;
1800+ let ( mut test_manager, _) =
1801+ TestManager :: < DictStateReader > :: new_with_default_initial_state ( [ ] ) . await ;
1802+
1803+ // Prepare block info data.
1804+ let next_block_number = test_manager. initial_state . next_block_number ;
1805+ let rounded_block_number = ( next_block_number. 0 / 100 ) * 100 ;
1806+ let next_block_timestamp = BlockInfo :: create_for_testing ( ) . block_timestamp . 0 ;
1807+ let rounded_next_block_timestamp = ( next_block_timestamp / 3600 ) * 3600 ;
1808+ assert ! (
1809+ rounded_block_number != next_block_number. 0 ,
1810+ "For the test the rounded block number must be different from the next block number; both \
1811+ are {rounded_block_number}."
1812+ ) ;
1813+ assert ! (
1814+ rounded_next_block_timestamp != next_block_timestamp,
1815+ "For the test the rounded block timestamp must be different from the next block \
1816+ timestamp; both are {rounded_next_block_timestamp}."
1817+ ) ;
1818+
1819+ // Declare the block info contract.
1820+ let class_info = get_class_info_of_feature_contract ( test_contract) ;
1821+ if is_cairo0 {
1822+ let declare_args = declare_tx_args ! {
1823+ version: TransactionVersion :: ZERO ,
1824+ max_fee: Fee ( 1_000_000_000_000_000 ) ,
1825+ class_hash,
1826+ sender_address: * FUNDED_ACCOUNT_ADDRESS ,
1827+ nonce: Nonce :: default ( ) ,
1828+ } ;
1829+ let account_declare_tx = declare_tx ( declare_args) ;
1830+ let tx = DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS )
1831+ . unwrap ( ) ;
1832+ test_manager. add_cairo0_declare_tx ( tx, class_hash) ;
1833+ } else {
1834+ let test_contract_sierra = test_contract. get_sierra ( ) ;
1835+ let test_contract_compiled_class_hash =
1836+ test_contract. get_compiled_class_hash ( & HashVersion :: V2 ) ;
1837+ let declare_tx_args = declare_tx_args ! {
1838+ sender_address: * FUNDED_ACCOUNT_ADDRESS ,
1839+ class_hash,
1840+ compiled_class_hash: test_contract_compiled_class_hash,
1841+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1842+ nonce: test_manager. next_nonce( * FUNDED_ACCOUNT_ADDRESS ) ,
1843+ } ;
1844+ let account_declare_tx = declare_tx ( declare_tx_args) ;
1845+ let declare_tx =
1846+ DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS )
1847+ . unwrap ( ) ;
1848+ test_manager. add_cairo1_declare_tx ( declare_tx. clone ( ) , & test_contract_sierra) ;
1849+ }
1850+
1851+ // Prepare to deploy: precompute the address.
1852+ let salt = Felt :: ZERO ;
1853+ let block_info_account_address = calculate_contract_address (
1854+ ContractAddressSalt ( salt) ,
1855+ class_hash,
1856+ & calldata ! [ is_validate] ,
1857+ ContractAddress :: default ( ) ,
1858+ )
1859+ . unwrap ( ) ;
1860+
1861+ // Fund the address.
1862+ test_manager. add_fund_address_tx_with_default_amount ( block_info_account_address) ;
1863+
1864+ // Deploy the contract using a DeployAccount transaction.
1865+ let deploy_account_tx_args = deploy_account_tx_args ! {
1866+ class_hash,
1867+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1868+ contract_address_salt: ContractAddressSalt ( Felt :: ZERO ) ,
1869+ constructor_calldata: calldata![ is_validate] ,
1870+ nonce: Nonce :: default ( ) ,
1871+ } ;
1872+ let deploy_account_tx = DeployAccountTransaction :: create (
1873+ deploy_account_tx (
1874+ deploy_account_tx_args,
1875+ test_manager. next_nonce ( block_info_account_address) ,
1876+ ) ,
1877+ & CHAIN_ID_FOR_TESTS ,
1878+ )
1879+ . unwrap ( ) ;
1880+ test_manager. add_deploy_account_tx ( deploy_account_tx) ;
1881+
1882+ // Test validate_declare.
1883+ let empty_contract = FeatureContract :: Empty ( CairoVersion :: Cairo1 ( RunnableCairo1 :: Casm ) ) ;
1884+ let empty_class_hash = get_class_hash_of_feature_contract ( empty_contract) ;
1885+ let empty_compiled_class_hash = empty_contract. get_compiled_class_hash ( & HashVersion :: V2 ) ;
1886+ let declare_tx_args = declare_tx_args ! {
1887+ sender_address: block_info_account_address,
1888+ class_hash: empty_class_hash,
1889+ compiled_class_hash: empty_compiled_class_hash,
1890+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1891+ nonce: test_manager. next_nonce( block_info_account_address) ,
1892+ } ;
1893+ let account_declare_tx = declare_tx ( declare_tx_args) ;
1894+ let class_info = get_class_info_of_feature_contract ( empty_contract) ;
1895+ let declare_tx =
1896+ DeclareTransaction :: create ( account_declare_tx, class_info, & CHAIN_ID_FOR_TESTS ) . unwrap ( ) ;
1897+ test_manager. add_cairo1_declare_tx ( declare_tx. clone ( ) , & empty_contract. get_sierra ( ) ) ;
1898+
1899+ // Test `validate` and `execute`.
1900+ let invoke_args = invoke_tx_args ! {
1901+ sender_address: block_info_account_address,
1902+ nonce: test_manager. next_nonce( block_info_account_address) ,
1903+ // Dummy contract address and selector, calldata length of zero.
1904+ calldata: calldata![ Felt :: ZERO , Felt :: ZERO , Felt :: ZERO ] ,
1905+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
1906+ } ;
1907+ test_manager. add_invoke_tx_from_args ( invoke_args, & CHAIN_ID_FOR_TESTS , None ) ;
1908+
1909+ // Test `constructor` in execute mode.
1910+ let ctor_calldata = [ Felt :: ZERO ] ; // Not validate mode (execute mode).
1911+ let salt = Felt :: ZERO ;
1912+ let calldata = create_calldata (
1913+ * FUNDED_ACCOUNT_ADDRESS ,
1914+ "deploy_contract" ,
1915+ & [ class_hash. 0 , salt, ctor_calldata. len ( ) . into ( ) , ctor_calldata[ 0 ] ] ,
1916+ ) ;
1917+ test_manager. add_funded_account_invoke ( invoke_tx_args ! { calldata } ) ;
1918+
1919+ // Run the test.
1920+ let test_output =
1921+ test_manager. execute_test_with_default_block_contexts ( & TestParameters :: default ( ) ) . await ;
1922+ test_output. perform_default_validations ( ) ;
1923+ }
0 commit comments