diff --git a/.github/workflows/prove_blocks.yml b/.github/workflows/prove_blocks.yml index 1a9deeb1f..9d48dc4bd 100644 --- a/.github/workflows/prove_blocks.yml +++ b/.github/workflows/prove_blocks.yml @@ -47,4 +47,10 @@ jobs: bash scripts/setup-tests.sh - name: Prove Blocks - run: bash scripts/prove-blocks.sh -p ${{ secrets.PATHFINDER_RPC_URL }} -b 76793,76766,76775 + run: | + # These blocks verify the following issues: + # * 76793: the first block that we managed to prove, only has a few invoke txs + # * 76766 / 76775: additional basic blocks + # * 86507 / 124533: a failing assert that happened because we used the wrong VersionedConstants + # * 87019: diff assert values in contract subcall + bash scripts/prove-blocks.sh -p ${{ secrets.PATHFINDER_RPC_URL }} -b 76793,76766,76775,86507,87019,124533 diff --git a/Cargo.toml b/Cargo.toml index 514abce50..6ba31f41d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,13 +24,13 @@ assert_matches = "1.5.0" base64 = "0.21.3" bitvec = { version = "1.0.1", features = ["serde"] } # Point to the latest commit of branch msl/snos-0.6.0-rc.2 -blockifier = { git = "https://github.com/Moonsong-Labs/blockifier", rev = "983e3b1cdb6621c5e6fa600f47cd69bf9e287621", features = ["testing"] } -cairo-lang-starknet = { version = "2.6.3" } -cairo-lang-starknet-classes = { version = "2.6.3" } -cairo-lang-utils = { version = "2.6.3" } -cairo-lang-casm = { version = "2.6.3" } +blockifier = { git = "https://github.com/Moonsong-Labs/sequencer", rev = "01b97d9354faefa5f0cd520b5efbe73178213f7e", features = ["testing"] } +cairo-lang-starknet = { version = "=2.7.1" } +cairo-lang-starknet-classes = { version = "=2.7.1" } +cairo-lang-utils = { version = "=2.7.1" } +cairo-lang-casm = { version = "=2.7.1" } cairo-type-derive = { version = "0.1.0", path = "crates/cairo-type-derive" } -cairo-vm = { version = "=1.0.0-rc5", features = ["extensive_hints", "cairo-1-hints"] } +cairo-vm = { version = "=1.0.1", features = ["extensive_hints", "cairo-1-hints"] } clap = { version = "4.5.4", features = ["derive"] } env_logger = "0.11.3" flate2 = "1.0.32" @@ -58,7 +58,7 @@ serde_json = { version = "1.0.105", features = ["arbitrary_precision"] } serde_with = "3.3.0" serde_yaml = "0.9.25" starknet = "0.11.0" -starknet_api = { version = "=0.10", features = ["testing"] } +starknet_api = { git = "https://github.com/Moonsong-Labs/sequencer", rev = "01b97d9354faefa5f0cd520b5efbe73178213f7e", features = ["testing"] } starknet-core = "0.11.1" starknet-crypto = "0.6.2" starknet-os = { path = "crates/starknet-os" } diff --git a/crates/bin/prove_block/src/main.rs b/crates/bin/prove_block/src/main.rs index 276413c98..032ac4ea9 100644 --- a/crates/bin/prove_block/src/main.rs +++ b/crates/bin/prove_block/src/main.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, HashSet}; use std::error::Error; -use blockifier::state::cached_state::{CachedState, GlobalContractCache}; +use blockifier::state::cached_state::CachedState; use cairo_vm::types::layout_name::LayoutName; use cairo_vm::vm::errors::cairo_run_errors::CairoRunError::VmException; use cairo_vm::Felt252; @@ -24,13 +24,13 @@ use starknet_os::starknet::business_logic::fact_state::contract_state_objects::C use starknet_os::starknet::starknet_storage::CommitmentInfo; use starknet_os::starkware_utils::commitment_tree::base_types::Height; use starknet_os::starkware_utils::commitment_tree::patricia_tree::patricia_tree::PatriciaTree; -use starknet_os::utils::felt_api2vm; use starknet_os::{config, run_os}; +use starknet_os_types::chain_id::chain_id_from_felt; use starknet_os_types::sierra_contract_class::GenericSierraContractClass; use starknet_types_core::felt::Felt; use crate::reexecute::format_commitment_facts; -use crate::rpc_utils::PathfinderClassProof; +use crate::rpc_utils::{get_starknet_version, PathfinderClassProof}; use crate::state_utils::get_processed_state_update; use crate::types::starknet_rs_tx_to_internal_tx; @@ -113,7 +113,7 @@ async fn main() -> Result<(), Box> { reqwest::ClientBuilder::new().build().unwrap_or_else(|e| panic!("Could not build reqwest client: {e}")); // Step 1: build the block context - let chain_id = provider.chain_id().await?.to_string(); + let chain_id = chain_id_from_felt(provider.chain_id().await?); log::debug!("provider's chain_id: {}", chain_id); let block_with_txs = match provider.get_block_with_txs(block_id).await? { MaybePendingBlockWithTxs::Block(block_with_txs) => block_with_txs, @@ -122,6 +122,9 @@ async fn main() -> Result<(), Box> { } }; + let starknet_version = get_starknet_version(&block_with_txs); + log::debug!("Starknet version: {:?}", starknet_version); + // We only need to get the older block number and hash. No need to fetch all the txs let older_block = match provider .get_block_with_tx_hashes(BlockId::Number(block_number - STORED_BLOCK_HASH_BUFFER)) @@ -134,7 +137,7 @@ async fn main() -> Result<(), Box> { } }; - let block_context = build_block_context(chain_id.clone(), &block_with_txs); + let block_context = build_block_context(chain_id.clone(), &block_with_txs, starknet_version); let old_block_number = Felt252::from(older_block.block_number); let old_block_hash = older_block.block_hash; @@ -155,7 +158,7 @@ async fn main() -> Result<(), Box> { )); let blockifier_state_reader = AsyncRpcStateReader::new(provider_for_blockifier, BlockId::Number(block_number - 1)); - let mut blockifier_state = CachedState::new(blockifier_state_reader, GlobalContractCache::new(1024)); + let mut blockifier_state = CachedState::new(blockifier_state_reader); let tx_execution_infos = reexecute_transactions_with_blockifier( &mut blockifier_state, &block_context, @@ -189,9 +192,7 @@ async fn main() -> Result<(), Box> { let general_config = StarknetGeneralConfig { starknet_os_config: StarknetOsConfig { - // TODO: the string given by provider is in decimal, the OS expects hex - // chain_id: starknet_api::core::ChainId(chain_id.clone()), - chain_id: starknet_api::core::ChainId("SN_SEPOLIA".to_string()), + chain_id, fee_token_address: block_context.chain_info().fee_token_addresses.strk_fee_token_address, deprecated_fee_token_address: block_context.chain_info().fee_token_addresses.eth_fee_token_address, }, @@ -290,7 +291,7 @@ async fn main() -> Result<(), Box> { .visited_pcs .iter() .map(|(class_hash, visited_pcs)| { - (felt_api2vm(class_hash.0), visited_pcs.iter().copied().map(Felt252::from).collect::>()) + (class_hash.0, visited_pcs.iter().copied().map(Felt252::from).collect::>()) }) .collect(); diff --git a/crates/bin/prove_block/src/rpc_utils.rs b/crates/bin/prove_block/src/rpc_utils.rs index 7f45c3eb4..bfcb934e7 100644 --- a/crates/bin/prove_block/src/rpc_utils.rs +++ b/crates/bin/prove_block/src/rpc_utils.rs @@ -5,16 +5,15 @@ use cairo_vm::Felt252; use serde::de::DeserializeOwned; use serde::Deserialize; use serde_json::json; +use starknet::core::types::BlockWithTxs; use starknet_api::core::{ContractAddress, PatriciaKey}; -use starknet_api::hash::StarkHash; -use starknet_api::{contract_address, patricia_key}; +use starknet_api::{contract_address, felt, patricia_key}; use starknet_os::crypto::pedersen::PedersenHash; use starknet_os::crypto::poseidon::PoseidonHash; use starknet_os::starkware_utils::commitment_tree::base_types::{Length, NodePath}; use starknet_os::starkware_utils::commitment_tree::patricia_tree::nodes::{BinaryNodeFact, EdgeNodeFact}; use starknet_os::storage::dict_storage::DictStorage; use starknet_os::storage::storage::{Fact, HashFunctionType}; -use starknet_os::utils::{felt_api2vm, felt_vm2api}; use starknet_types_core::felt::Felt; use crate::utils::get_all_accessed_keys; @@ -137,7 +136,7 @@ pub(crate) async fn get_storage_proofs( ) -> Result, reqwest::Error> { let accessed_keys_by_address = { let mut keys = get_all_accessed_keys(tx_execution_infos); - keys.entry(contract_address!("0x1")).or_default().insert(felt_vm2api(old_block_number).try_into().unwrap()); + keys.entry(contract_address!("0x1")).or_default().insert(old_block_number.try_into().unwrap()); keys }; @@ -149,9 +148,9 @@ pub(crate) async fn get_storage_proofs( } for (contract_address, storage_keys) in accessed_keys_by_address { - let contract_address_felt = felt_api2vm(*contract_address.key()); + let contract_address_felt = *contract_address.key(); - let keys: Vec<_> = storage_keys.iter().map(|storage_key| felt_api2vm(*storage_key.key())).collect(); + let keys: Vec<_> = storage_keys.iter().map(|storage_key| *storage_key.key()).collect(); let storage_proof = if keys.is_empty() { pathfinder_get_proof(client, rpc_provider, block_number, contract_address_felt, &[]).await? @@ -299,3 +298,16 @@ pub(crate) fn verify_proof(key: Felt, commitment: Felt, pro Ok(()) } + +pub(crate) fn get_starknet_version(block_with_txs: &BlockWithTxs) -> blockifier::versioned_constants::StarknetVersion { + let starknet_version_str = &block_with_txs.starknet_version; + match starknet_version_str.as_ref() { + "0.13.0" => blockifier::versioned_constants::StarknetVersion::V0_13_0, + "0.13.1" => blockifier::versioned_constants::StarknetVersion::V0_13_1, + "0.13.1.1" => blockifier::versioned_constants::StarknetVersion::V0_13_1_1, + "0.13.2" => blockifier::versioned_constants::StarknetVersion::Latest, + other => { + unimplemented!("Unsupported Starknet version: {}", other) + } + } +} diff --git a/crates/bin/prove_block/src/types.rs b/crates/bin/prove_block/src/types.rs index 3a4ebae14..57734d988 100644 --- a/crates/bin/prove_block/src/types.rs +++ b/crates/bin/prove_block/src/types.rs @@ -7,17 +7,11 @@ use starknet::core::types::{ Transaction, }; use starknet_os::io::InternalTransaction; -use starknet_types_core::felt::Felt; // entry point for "__execute__" const EXECUTE_ENTRY_POINT_FELT: Felt252 = Felt252::from_hex_unchecked("0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad"); -fn felt_to_vm(felt: Felt) -> Felt252 { - // Turns out that the types are the same between starknet-core and cairo-vm - felt -} - fn da_to_felt(data_availability_mode: DataAvailabilityMode) -> Felt252 { match data_availability_mode { DataAvailabilityMode::L1 => Felt252::ZERO, @@ -26,34 +20,28 @@ fn da_to_felt(data_availability_mode: DataAvailabilityMode) -> Felt252 { } fn invoke_tx_v0_to_internal_tx(tx: InvokeTransactionV0) -> InternalTransaction { - let signature: Vec<_> = tx.signature.into_iter().map(felt_to_vm).collect(); - let calldata: Vec<_> = tx.calldata.into_iter().map(felt_to_vm).collect(); - InternalTransaction { - hash_value: felt_to_vm(tx.transaction_hash), - max_fee: Some(felt_to_vm(tx.max_fee)), - signature: Some(signature), - contract_address: Some(felt_to_vm(tx.contract_address)), - entry_point_selector: Some(felt_to_vm(tx.entry_point_selector)), - calldata: Some(calldata), + hash_value: tx.transaction_hash, + max_fee: Some(tx.max_fee), + signature: Some(tx.signature), + contract_address: Some(tx.contract_address), + entry_point_selector: Some(tx.entry_point_selector), + calldata: Some(tx.calldata), version: Some(Felt252::ZERO), ..Default::default() } } fn invoke_tx_v1_to_internal_tx(tx: InvokeTransactionV1) -> InternalTransaction { - let signature: Vec<_> = tx.signature.into_iter().map(felt_to_vm).collect(); - let calldata: Vec<_> = tx.calldata.into_iter().map(felt_to_vm).collect(); - InternalTransaction { - hash_value: felt_to_vm(tx.transaction_hash), + hash_value: tx.transaction_hash, version: Some(Felt252::ONE), contract_address: Some(tx.sender_address), nonce: Some(tx.nonce), sender_address: Some(tx.sender_address), entry_point_selector: Some(EXECUTE_ENTRY_POINT_FELT), entry_point_type: Some("EXTERNAL".to_string()), - signature: Some(signature), - calldata: Some(calldata), + signature: Some(tx.signature), + calldata: Some(tx.calldata), r#type: "INVOKE_FUNCTION".to_string(), max_fee: Some(tx.max_fee), ..Default::default() @@ -61,27 +49,22 @@ fn invoke_tx_v1_to_internal_tx(tx: InvokeTransactionV1) -> InternalTransaction { } fn invoke_tx_v3_to_internal_tx(tx: InvokeTransactionV3) -> InternalTransaction { - let signature: Vec<_> = tx.signature.into_iter().map(felt_to_vm).collect(); - let calldata: Vec<_> = tx.calldata.into_iter().map(felt_to_vm).collect(); - let paymaster_data: Vec<_> = tx.paymaster_data.into_iter().map(felt_to_vm).collect(); - let account_deployment_data: Vec<_> = tx.account_deployment_data.into_iter().map(felt_to_vm).collect(); - InternalTransaction { - hash_value: felt_to_vm(tx.transaction_hash), - sender_address: Some(felt_to_vm(tx.sender_address)), - signature: Some(signature), - nonce: Some(felt_to_vm(tx.nonce)), + hash_value: tx.transaction_hash, + sender_address: Some(tx.sender_address), + signature: Some(tx.signature), + nonce: Some(tx.nonce), resource_bounds: Some(resource_bounds_core_to_api(&tx.resource_bounds)), tip: Some(Felt252::from(tx.tip)), - paymaster_data: Some(paymaster_data), - account_deployment_data: Some(account_deployment_data), + paymaster_data: Some(tx.paymaster_data), + account_deployment_data: Some(tx.account_deployment_data), nonce_data_availability_mode: Some(da_to_felt(tx.nonce_data_availability_mode)), fee_data_availability_mode: Some(da_to_felt(tx.fee_data_availability_mode)), version: Some(Felt252::TWO), contract_address: Some(tx.sender_address), entry_point_selector: Some(EXECUTE_ENTRY_POINT_FELT), entry_point_type: Some("EXTERNAL".to_string()), - calldata: Some(calldata), + calldata: Some(tx.calldata), ..Default::default() } } @@ -223,6 +206,7 @@ pub(crate) fn starknet_rs_tx_to_internal_tx(tx: Transaction) -> InternalTransact #[cfg(test)] mod tests { use starknet::core::types::{ResourceBounds, ResourceBoundsMapping}; + use starknet_types_core::felt::Felt; use super::*; diff --git a/crates/bin/prove_block/src/utils.rs b/crates/bin/prove_block/src/utils.rs index f776ca6ee..f2053721e 100644 --- a/crates/bin/prove_block/src/utils.rs +++ b/crates/bin/prove_block/src/utils.rs @@ -6,7 +6,6 @@ use cairo_vm::Felt252; use starknet::core::types::{ExecuteInvocation, FunctionInvocation, TransactionTrace, TransactionTraceWithHash}; use starknet_api::core::ContractAddress; use starknet_api::state::StorageKey; -use starknet_os::utils::felt_api2vm; /// Receives the transaction traces of a given block /// And extract the contracts addresses that where subcalled @@ -96,8 +95,7 @@ fn get_accessed_storage_keys(call_info: &CallInfo) -> HashMap = - call_info.accessed_storage_keys.iter().map(|x| felt_api2vm(*x.key()).to_hex_string()).collect(); + let storage_keys: Vec<_> = call_info.accessed_storage_keys.iter().map(|x| x.key().to_hex_string()).collect(); log::debug!("{}: {:?}", contract_address.to_string(), storage_keys); for inner_call in &call_info.inner_calls { diff --git a/crates/rpc-replay/src/block_context.rs b/crates/rpc-replay/src/block_context.rs index 96fb5671c..4c528f968 100644 --- a/crates/rpc-replay/src/block_context.rs +++ b/crates/rpc-replay/src/block_context.rs @@ -1,15 +1,19 @@ -use blockifier::block::{BlockInfo, GasPrices}; +use blockifier::blockifier::block::{BlockInfo, GasPrices}; +use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; use blockifier::versioned_constants::VersionedConstants; use starknet::core::types::BlockWithTxs; use starknet_api::block::{BlockNumber, BlockTimestamp}; -use starknet_api::core::{ContractAddress, PatriciaKey}; -use starknet_api::hash::StarkHash; -use starknet_api::{contract_address, patricia_key}; +use starknet_api::core::{ChainId, ContractAddress, PatriciaKey}; +use starknet_api::{contract_address, felt, patricia_key}; use crate::utils::felt_to_u128; -pub fn build_block_context(chain_id: String, block: &BlockWithTxs) -> BlockContext { +pub fn build_block_context( + chain_id: ChainId, + block: &BlockWithTxs, + starknet_version: blockifier::versioned_constants::StarknetVersion, +) -> BlockContext { let sequencer_address_hex = block.sequencer_address.to_hex_string(); let sequencer_address = contract_address!(sequencer_address_hex.as_str()); @@ -27,7 +31,7 @@ pub fn build_block_context(chain_id: String, block: &BlockWithTxs) -> BlockConte }; let chain_info = ChainInfo { - chain_id: starknet_api::core::ChainId(chain_id), + chain_id, // cf. https://docs.starknet.io/tools/important-addresses/ fee_token_addresses: FeeTokenAddresses { strk_fee_token_address: contract_address!( @@ -39,7 +43,8 @@ pub fn build_block_context(chain_id: String, block: &BlockWithTxs) -> BlockConte }, }; - let versioned_constants = VersionedConstants::latest_constants(); + let versioned_constants = VersionedConstants::get(starknet_version); + let bouncer_config = BouncerConfig::max(); - BlockContext::new_unchecked(&block_info, &chain_info, versioned_constants) + BlockContext::new(block_info, chain_info, versioned_constants.clone(), bouncer_config) } diff --git a/crates/rpc-replay/src/rpc_state_reader.rs b/crates/rpc-replay/src/rpc_state_reader.rs index a9b18030e..1c49783b4 100644 --- a/crates/rpc-replay/src/rpc_state_reader.rs +++ b/crates/rpc-replay/src/rpc_state_reader.rs @@ -1,17 +1,16 @@ use blockifier::execution::contract_class::ContractClass; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader, StateResult}; -use starknet::core::types::BlockId; +use starknet::core::types::{BlockId, Felt}; use starknet::providers::jsonrpc::JsonRpcTransport; use starknet::providers::{JsonRpcClient, Provider, ProviderError}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; -use starknet_api::hash::StarkFelt; use starknet_api::state::StorageKey; use starknet_os_types::deprecated_compiled_class::GenericDeprecatedCompiledClass; use starknet_os_types::hash::GenericClassHash; use starknet_os_types::sierra_contract_class::GenericSierraContractClass; -use crate::utils::{execute_coroutine, felt_api2vm, felt_vm2api}; +use crate::utils::execute_coroutine; pub struct AsyncRpcStateReader where @@ -42,46 +41,39 @@ impl AsyncRpcStateReader where T: JsonRpcTransport + Sync + Send + 'static, { - pub async fn get_storage_at_async( - &self, - contract_address: ContractAddress, - key: StorageKey, - ) -> StateResult { + pub async fn get_storage_at_async(&self, contract_address: ContractAddress, key: StorageKey) -> StateResult { let storage_value = self .provider - .get_storage_at(felt_api2vm(*contract_address.key()), felt_api2vm(*key.0.key()), self.block_id) + .get_storage_at(*contract_address.key(), *key.0.key(), self.block_id) .await .map_err(provider_error_to_state_error)?; - Ok(felt_vm2api(storage_value)) + Ok(storage_value) } pub async fn get_nonce_at_async(&self, contract_address: ContractAddress) -> StateResult { let nonce = self .provider - .get_nonce(self.block_id, felt_api2vm(*contract_address.key())) + .get_nonce(self.block_id, *contract_address.key()) .await .map_err(provider_error_to_state_error)?; - Ok(Nonce(felt_vm2api(nonce))) + Ok(Nonce(nonce)) } pub async fn get_class_hash_at_async(&self, contract_address: ContractAddress) -> StateResult { let nonce = self .provider - .get_class_hash_at(self.block_id, felt_api2vm(*contract_address.key())) + .get_class_hash_at(self.block_id, *contract_address.key()) .await .map_err(provider_error_to_state_error)?; - Ok(ClassHash(felt_vm2api(nonce))) + Ok(ClassHash(nonce)) } pub async fn get_compiled_contract_class_async(&self, class_hash: ClassHash) -> StateResult { - let contract_class = self - .provider - .get_class(self.block_id, felt_api2vm(class_hash.0)) - .await - .map_err(provider_error_to_state_error)?; + let contract_class = + self.provider.get_class(self.block_id, class_hash.0).await.map_err(provider_error_to_state_error)?; let contract_class: ContractClass = match contract_class { starknet::core::types::ContractClass::Sierra(sierra_class) => { @@ -99,11 +91,8 @@ where } pub async fn get_compiled_class_hash_async(&self, class_hash: ClassHash) -> StateResult { - let contract_class = self - .provider - .get_class(self.block_id, felt_api2vm(class_hash.0)) - .await - .map_err(provider_error_to_state_error)?; + let contract_class = + self.provider.get_class(self.block_id, class_hash.0).await.map_err(provider_error_to_state_error)?; let class_hash: GenericClassHash = match contract_class { starknet::core::types::ContractClass::Sierra(sierra_class) => { @@ -125,24 +114,24 @@ impl StateReader for AsyncRpcStateReader where T: JsonRpcTransport + Sync + Send + 'static, { - fn get_storage_at(&mut self, contract_address: ContractAddress, key: StorageKey) -> StateResult { + fn get_storage_at(&self, contract_address: ContractAddress, key: StorageKey) -> StateResult { execute_coroutine(self.get_storage_at_async(contract_address, key)).map_err(to_state_err)? } - fn get_nonce_at(&mut self, contract_address: ContractAddress) -> StateResult { + fn get_nonce_at(&self, contract_address: ContractAddress) -> StateResult { execute_coroutine(self.get_nonce_at_async(contract_address)).map_err(to_state_err)? } - fn get_class_hash_at(&mut self, contract_address: ContractAddress) -> StateResult { + fn get_class_hash_at(&self, contract_address: ContractAddress) -> StateResult { execute_coroutine(self.get_class_hash_at_async(contract_address)) .map_err(|e| StateError::StateReadError(e.to_string()))? } - fn get_compiled_contract_class(&mut self, class_hash: ClassHash) -> StateResult { + fn get_compiled_contract_class(&self, class_hash: ClassHash) -> StateResult { execute_coroutine(self.get_compiled_contract_class_async(class_hash)).map_err(to_state_err)? } - fn get_compiled_class_hash(&mut self, class_hash: ClassHash) -> StateResult { + fn get_compiled_class_hash(&self, class_hash: ClassHash) -> StateResult { execute_coroutine(self.get_compiled_class_hash_async(class_hash)).map_err(to_state_err)? } } diff --git a/crates/rpc-replay/src/transactions.rs b/crates/rpc-replay/src/transactions.rs index 63ee70d23..95a20f70c 100644 --- a/crates/rpc-replay/src/transactions.rs +++ b/crates/rpc-replay/src/transactions.rs @@ -7,8 +7,6 @@ use starknet::core::types::{InvokeTransaction, ResourceBoundsMapping, Transactio use starknet_api::core::PatriciaKey; use starknet_api::transaction::TransactionHash; -use crate::utils::felt_vm2api; - pub fn resource_bounds_core_to_api( resource_bounds: &ResourceBoundsMapping, ) -> starknet_api::transaction::ResourceBoundsMapping { @@ -47,51 +45,45 @@ pub fn starknet_rs_to_blockifier( Transaction::Invoke(tx) => { let (tx_hash, api_tx) = match tx { InvokeTransaction::V0(tx) => { - let _tx_hash = TransactionHash(felt_vm2api(tx.transaction_hash)); + let _tx_hash = TransactionHash(tx.transaction_hash); unimplemented!("starknet_rs_to_blockifier with InvokeTransaction::V0"); } InvokeTransaction::V1(tx) => { - let tx_hash = TransactionHash(felt_vm2api(tx.transaction_hash)); + let tx_hash = TransactionHash(tx.transaction_hash); let api_tx = starknet_api::transaction::InvokeTransaction::V1( starknet_api::transaction::InvokeTransactionV1 { max_fee: starknet_api::transaction::Fee(tx.max_fee.to_biguint().try_into()?), signature: starknet_api::transaction::TransactionSignature( - tx.signature.clone().into_iter().map(felt_vm2api).collect(), + tx.signature.clone().into_iter().collect(), ), - nonce: starknet_api::core::Nonce(felt_vm2api(tx.nonce)), + nonce: starknet_api::core::Nonce(tx.nonce), sender_address: starknet_api::core::ContractAddress( - PatriciaKey::try_from(felt_vm2api(tx.sender_address)).unwrap(), + PatriciaKey::try_from(tx.sender_address).unwrap(), ), calldata: starknet_api::transaction::Calldata(Arc::new( - tx.calldata.clone().into_iter().map(felt_vm2api).collect(), + tx.calldata.clone().into_iter().collect(), )), }, ); (tx_hash, api_tx) } InvokeTransaction::V3(tx) => { - let tx_hash = TransactionHash(felt_vm2api(tx.transaction_hash)); + let tx_hash = TransactionHash(tx.transaction_hash); let api_tx = starknet_api::transaction::InvokeTransaction::V3( starknet_api::transaction::InvokeTransactionV3 { resource_bounds: resource_bounds_core_to_api(&tx.resource_bounds), tip: starknet_api::transaction::Tip(tx.tip), - signature: starknet_api::transaction::TransactionSignature( - tx.signature.iter().copied().map(felt_vm2api).collect(), - ), - nonce: starknet_api::core::Nonce(felt_vm2api(tx.nonce)), + signature: starknet_api::transaction::TransactionSignature(tx.signature.to_vec()), + nonce: starknet_api::core::Nonce(tx.nonce), sender_address: starknet_api::core::ContractAddress( - PatriciaKey::try_from(felt_vm2api(tx.sender_address)).unwrap(), + PatriciaKey::try_from(tx.sender_address).unwrap(), ), - calldata: starknet_api::transaction::Calldata(Arc::new( - tx.calldata.iter().copied().map(felt_vm2api).collect(), - )), + calldata: starknet_api::transaction::Calldata(Arc::new(tx.calldata.to_vec())), nonce_data_availability_mode: da_mode_core_to_api(tx.nonce_data_availability_mode), fee_data_availability_mode: da_mode_core_to_api(tx.fee_data_availability_mode), - paymaster_data: starknet_api::transaction::PaymasterData( - tx.paymaster_data.iter().copied().map(felt_vm2api).collect(), - ), + paymaster_data: starknet_api::transaction::PaymasterData(tx.paymaster_data.to_vec()), account_deployment_data: starknet_api::transaction::AccountDeploymentData( - tx.account_deployment_data.iter().copied().map(felt_vm2api).collect(), + tx.account_deployment_data.to_vec(), ), }, ); diff --git a/crates/rpc-replay/src/utils.rs b/crates/rpc-replay/src/utils.rs index 5c7056263..c7e659c07 100644 --- a/crates/rpc-replay/src/utils.rs +++ b/crates/rpc-replay/src/utils.rs @@ -1,5 +1,4 @@ use starknet::core::types::Felt; -use starknet_api::hash::StarkFelt; /// Executes a coroutine from a synchronous context. /// Fails if no Tokio runtime is present. @@ -11,14 +10,6 @@ where Ok(tokio::task::block_in_place(|| tokio_runtime_handle.block_on(coroutine))) } -pub fn felt_api2vm(felt: StarkFelt) -> Felt { - Felt::from_bytes_be_slice(felt.bytes()) -} - -pub fn felt_vm2api(felt: Felt) -> StarkFelt { - StarkFelt::new_unchecked(felt.to_bytes_be()) -} - pub fn felt_to_u128(felt: &Felt) -> u128 { let digits = felt.to_be_digits(); ((digits[2] as u128) << 64) + digits[3] as u128 diff --git a/crates/rpc-replay/tests/test_replay_block.rs b/crates/rpc-replay/tests/test_replay_block.rs index d9bbb42f2..40b5178ab 100644 --- a/crates/rpc-replay/tests/test_replay_block.rs +++ b/crates/rpc-replay/tests/test_replay_block.rs @@ -1,5 +1,6 @@ use blockifier::state::cached_state::CachedState; use blockifier::transaction::transactions::ExecutableTransaction as _; +use blockifier::versioned_constants::StarknetVersion; use rpc_replay::block_context::build_block_context; use rpc_replay::rpc_state_reader::AsyncRpcStateReader; use rpc_replay::transactions::starknet_rs_to_blockifier; @@ -7,6 +8,7 @@ use rstest::rstest; use starknet::core::types::{BlockId, BlockWithTxs}; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Url}; +use starknet_api::core::ChainId; #[rstest] #[ignore = "Requires a local Pathfinder node"] @@ -27,7 +29,7 @@ async fn test_replay_block() { let state_reader = AsyncRpcStateReader::new(provider, BlockId::Number(block_with_txs.block_number - 1)); let mut state = CachedState::from(state_reader); - let block_context = build_block_context("SN_SEPOLIA".to_string(), &block_with_txs); + let block_context = build_block_context(ChainId::Sepolia, &block_with_txs, StarknetVersion::V0_13_1); for tx in block_with_txs.transactions.iter() { let blockifier_tx = starknet_rs_to_blockifier(tx).unwrap(); diff --git a/crates/starknet-os-types/src/casm_contract_class.rs b/crates/starknet-os-types/src/casm_contract_class.rs index ef1e62626..cb3a4ec2c 100644 --- a/crates/starknet-os-types/src/casm_contract_class.rs +++ b/crates/starknet-os-types/src/casm_contract_class.rs @@ -95,7 +95,7 @@ impl GenericCasmContractClass { let compiled_class = self.get_cairo_lang_contract_class()?; let class_hash_felt = compiled_class.compiled_class_hash(); - Ok(GenericClassHash::from_bytes_be(class_hash_felt.to_be_bytes())) + Ok(GenericClassHash::from_bytes_be(class_hash_felt.to_bytes_be())) } pub fn class_hash(&self) -> Result { diff --git a/crates/starknet-os-types/src/chain_id.rs b/crates/starknet-os-types/src/chain_id.rs index 7a51e97ca..c08cd08a9 100644 --- a/crates/starknet-os-types/src/chain_id.rs +++ b/crates/starknet-os-types/src/chain_id.rs @@ -5,3 +5,24 @@ use starknet_types_core::felt::Felt; pub fn chain_id_to_felt(chain_id: &ChainId) -> Felt { Felt::from_bytes_be_slice(chain_id.to_string().as_bytes()) } + +/// Builds a ChainId from a felt. +/// This function reads the felt as ASCII bytes. Leading zeroes are skipped. +pub fn chain_id_from_felt(felt: Felt) -> ChainId { + // Skip leading zeroes + let chain_id_bytes: Vec<_> = felt.to_bytes_be().into_iter().skip_while(|byte| *byte == 0u8).collect(); + let chain_id_str = String::from_utf8_lossy(&chain_id_bytes); + ChainId::from(chain_id_str.into_owned()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_chain_id_from_felt() { + let chain_id_felt = Felt::from_dec_str("393402133025997798000961").unwrap(); + let chain_id = chain_id_from_felt(chain_id_felt); + assert_eq!(chain_id, ChainId::Sepolia); + } +} diff --git a/crates/starknet-os-types/src/hash.rs b/crates/starknet-os-types/src/hash.rs index aacced374..b8a0eada2 100644 --- a/crates/starknet-os-types/src/hash.rs +++ b/crates/starknet-os-types/src/hash.rs @@ -3,8 +3,6 @@ use std::ops::Deref; use num_bigint::BigUint; use serde::{Deserialize, Serialize}; use starknet_api::core::{ClassHash, CompiledClassHash}; -use starknet_api::hash::{StarkFelt, StarkHash}; -use starknet_api::StarknetApiError; use starknet_types_core::felt::Felt; const EMPTY_HASH: [u8; 32] = [0; 32]; @@ -80,27 +78,15 @@ impl From for Hash { } } -impl TryFrom for StarkFelt { - type Error = StarknetApiError; - - fn try_from(hash: Hash) -> Result { - Self::new(hash.0) - } -} - -impl TryFrom for CompiledClassHash { - type Error = StarknetApiError; - - fn try_from(hash: Hash) -> Result { - Ok(Self(hash.try_into()?)) +impl From for CompiledClassHash { + fn from(hash: Hash) -> Self { + Self(hash.into()) } } -impl TryFrom for ClassHash { - type Error = StarknetApiError; - - fn try_from(hash: Hash) -> Result { - Ok(Self(hash.try_into()?)) +impl From for ClassHash { + fn from(hash: Hash) -> Self { + Self(hash.into()) } } @@ -119,22 +105,20 @@ impl GenericClassHash { impl From for GenericClassHash { fn from(class_hash: ClassHash) -> Self { - let hash = Hash::from_bytes_be_slice(class_hash.0.bytes()); + let hash = Hash(class_hash.0.to_bytes_be()); Self(hash) } } impl From for ClassHash { fn from(class_hash: GenericClassHash) -> Self { - let stark_hash = StarkHash::new_unchecked(class_hash.0.0); - ClassHash(stark_hash) + class_hash.0.into() } } impl From for CompiledClassHash { fn from(class_hash: GenericClassHash) -> Self { - let stark_hash = StarkHash::new_unchecked(class_hash.0.0); - CompiledClassHash(stark_hash) + class_hash.0.into() } } diff --git a/crates/starknet-os/src/config.rs b/crates/starknet-os/src/config.rs index 54d05d02e..aca727c6c 100644 --- a/crates/starknet-os/src/config.rs +++ b/crates/starknet-os/src/config.rs @@ -1,7 +1,8 @@ use std::fs::File; use std::path::PathBuf; -use blockifier::block::{BlockInfo, GasPrices}; +use blockifier::blockifier::block::{BlockInfo, GasPrices}; +use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; use blockifier::transaction::objects::FeeType; use blockifier::versioned_constants::VersionedConstants; @@ -10,9 +11,7 @@ use serde::{Deserialize, Serialize}; use serde_with::serde_as; use starknet_api::block::{BlockNumber, BlockTimestamp}; use starknet_api::core::{ChainId, ContractAddress, PatriciaKey}; -use starknet_api::hash::{pedersen_hash_array, StarkFelt, StarkHash}; -use starknet_api::{contract_address, patricia_key}; -use starknet_crypto::FieldElement; +use starknet_api::{contract_address, felt, patricia_key}; use crate::error::SnOsError; use crate::utils::ChainIdNum; @@ -54,16 +53,6 @@ pub struct StarknetOsConfig { pub deprecated_fee_token_address: ContractAddress, } -impl StarknetOsConfig { - pub fn hash(&self) -> StarkHash { - pedersen_hash_array(&[ - StarkFelt::from(FieldElement::from_byte_slice_be(STARKNET_OS_CONFIG_HASH_VERSION.as_bytes()).unwrap()), - StarkFelt::from(u128::from_str_radix(&self.chain_id.0, 16).unwrap()), - *self.fee_token_address.0.key(), - ]) - } -} - #[derive(Debug, Serialize, Clone, Deserialize, PartialEq)] pub struct GasPriceBounds { pub min_wei_l1_gas_price: u128, @@ -91,7 +80,7 @@ impl Default for StarknetGeneralConfig { fn default() -> Self { Self { starknet_os_config: StarknetOsConfig { - chain_id: ChainId("SN_GOERLI".to_string()), + chain_id: ChainId::Sepolia, fee_token_address: contract_address!(DEFAULT_FEE_TOKEN_ADDR), deprecated_fee_token_address: contract_address!(DEFAULT_DEPRECATED_FEE_TOKEN_ADDR), }, @@ -152,7 +141,9 @@ impl StarknetGeneralConfig { }, }; - BlockContext::new_unchecked(&block_info, &chain_info, &versioned_constants) + let bouncer_config = BouncerConfig::max(); + + BlockContext::new(block_info, chain_info, versioned_constants, bouncer_config) } } diff --git a/crates/starknet-os/src/execution/deprecated_syscall_handler.rs b/crates/starknet-os/src/execution/deprecated_syscall_handler.rs index 965cae89d..9e1c78624 100644 --- a/crates/starknet-os/src/execution/deprecated_syscall_handler.rs +++ b/crates/starknet-os/src/execution/deprecated_syscall_handler.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use blockifier::block::BlockInfo; +use blockifier::blockifier::block::BlockInfo; use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; use cairo_vm::vm::errors::hint_errors::HintError; use cairo_vm::vm::vm_core::VirtualMachine; @@ -15,7 +15,6 @@ use crate::cairo_types::syscalls::{ TxInfo, }; use crate::starknet::starknet_storage::PerContractStorage; -use crate::utils::felt_api2vm; /// DeprecatedSyscallHandler implementation for execution of system calls in the StarkNet OS #[derive(Debug)] @@ -81,15 +80,7 @@ where // the result array. vm.insert_value((syscall_ptr + retdata_size_offset)?, result.retdata.0.len())?; let new_segment = vm.add_temporary_segment(); - let retdata = result - .retdata - .0 - .iter() - .map(|sf| { - let felt = felt_api2vm(*sf); - MaybeRelocatable::Int(felt) - }) - .collect(); + let retdata: Vec<_> = result.retdata.0.iter().map(|felt| MaybeRelocatable::Int(*felt)).collect(); vm.load_data(new_segment, &retdata)?; vm.insert_value((syscall_ptr + retdata_offset)?, new_segment)?; @@ -173,7 +164,6 @@ where let exec_helper = sys_hand.exec_wrapper.execution_helper.read().await; let caller_address = exec_helper.call_info.as_ref().expect("A call should have some call info").call.caller_address.0.key(); - let caller_address = felt_api2vm(*caller_address); // TODO: create proper struct for this (similar to GetCallerAddress and friends) // TODO: abstract this similar to pythonic _write_syscall_response() @@ -194,7 +184,7 @@ where exec_helper.call_info.as_ref().map(|info| info.call.storage_address).ok_or(HintError::SyscallError( "Missing storage address from call info".to_string().into_boxed_str(), ))?; - let contract_address_felt = felt_api2vm(*contract_address.0.key()); + let contract_address_felt = *contract_address.0.key(); let response_offset = GetContractAddress::response_offset() + GetContractAddressResponse::contract_address_offset(); @@ -209,7 +199,7 @@ where ) -> Result<(), HintError> { let syscall_handler = self.deprecated_syscall_handler.read().await; - let sequencer_address = felt_api2vm(*syscall_handler.block_info.sequencer_address.0.key()); + let sequencer_address = *syscall_handler.block_info.sequencer_address.0.key(); let response_offset = GetSequencerAddress::response_offset() + GetSequencerAddressResponse::sequencer_address_offset(); @@ -273,17 +263,12 @@ where HintError::SyscallError("No more storage reads available to replay".to_string().into_boxed_str()), )?; - vm.insert_value((syscall_ptr + 2usize).unwrap(), value).unwrap(); + vm.insert_value((syscall_ptr + 2usize)?, value)?; Ok(()) } pub async fn storage_write(&self, _syscall_ptr: Relocatable) -> Result<(), HintError> { - let sys_hand = self.deprecated_syscall_handler.write().await; - - let _ = sys_hand.exec_wrapper.execution_helper.write().await.execute_code_read_iter.next().ok_or( - HintError::SyscallError("No more storage writes available to replay".to_string().into_boxed_str()), - )?; - + // Nothing to do Ok(()) } @@ -302,7 +287,8 @@ where mod test { use std::borrow::Cow; - use blockifier::block::{BlockInfo, GasPrices}; + use blockifier::blockifier::block::{BlockInfo, GasPrices}; + use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; use blockifier::execution::call_info::Retdata; use blockifier::execution::entry_point_execution::CallResult; @@ -314,8 +300,7 @@ mod test { use rstest::{fixture, rstest}; use starknet_api::block::{BlockNumber, BlockTimestamp}; use starknet_api::core::{ChainId, ContractAddress, PatriciaKey}; - use starknet_api::hash::{StarkFelt, StarkHash}; - use starknet_api::{contract_address, patricia_key}; + use starknet_api::{contract_address, felt, patricia_key}; use crate::config::STORED_BLOCK_HASH_BUFFER; use crate::crypto::pedersen::PedersenHash; @@ -328,7 +313,7 @@ mod test { #[fixture] fn block_context() -> BlockContext { let chain_info = ChainInfo { - chain_id: ChainId("SN_GOERLI".to_string()), + chain_id: ChainId::Sepolia, fee_token_addresses: FeeTokenAddresses { strk_fee_token_address: contract_address!("0x1"), eth_fee_token_address: contract_address!("0x2"), @@ -348,7 +333,7 @@ mod test { use_kzg_da: false, }; - BlockContext::new_unchecked(&block_info, &chain_info, VersionedConstants::latest_constants()) + BlockContext::new(block_info, chain_info, VersionedConstants::latest_constants().clone(), BouncerConfig::max()) } #[fixture] @@ -380,7 +365,7 @@ mod test { // segment and insert its size somewhere in syscall_ptr. let call_results = vec![CallResult { failed: false, - retdata: Retdata(vec![StarkFelt::THREE, StarkFelt::TWO, StarkFelt::ONE]), + retdata: Retdata(vec![Felt252::THREE, Felt252::TWO, Felt252::ONE]), gas_consumed: 1, }]; exec_helper.execution_helper.write().await.result_iter = call_results.into_iter(); diff --git a/crates/starknet-os/src/execution/helper.rs b/crates/starknet-os/src/execution/helper.rs index 9129ab2c7..c66c669db 100644 --- a/crates/starknet-os/src/execution/helper.rs +++ b/crates/starknet-os/src/execution/helper.rs @@ -150,7 +150,7 @@ where .iter() .filter_map(|call| { if matches!(call.call.entry_point_type, EntryPointType::Constructor) { - Some(Felt252::from_bytes_be_slice(call.call.storage_address.0.key().bytes())) + Some(Felt252::from(call.call.storage_address)) } else { None } @@ -171,13 +171,7 @@ where .into_iter(); // unpack storage reads - eh_ref.execute_code_read_iter = call_info - .storage_read_values - .iter() - .map(|felt| Felt252::from_bytes_be_slice(felt.bytes())) - .collect::>() - .into_iter(); - + eh_ref.execute_code_read_iter = call_info.storage_read_values.clone().into_iter(); eh_ref.call_info = Some(call_info); } pub async fn exit_call(&mut self) { @@ -224,6 +218,7 @@ where let mut commitments = HashMap::new(); for (key, storage) in storage_by_address.iter_mut() { + log::debug!("Computing commitment for contract address {}", key.to_hex_string()); let commitment_info = storage.compute_commitment().await?; commitments.insert(*key, commitment_info); } diff --git a/crates/starknet-os/src/execution/syscall_handler.rs b/crates/starknet-os/src/execution/syscall_handler.rs index 6e92d40c0..b08367bae 100644 --- a/crates/starknet-os/src/execution/syscall_handler.rs +++ b/crates/starknet-os/src/execution/syscall_handler.rs @@ -22,7 +22,6 @@ use crate::execution::syscall_handler_utils::{ ReadOnlySegment, SyscallExecutionError, SyscallHandler, SyscallResult, SyscallSelector, WriteResponseResult, }; use crate::starknet::starknet_storage::PerContractStorage; -use crate::utils::felt_api2vm; /// DeprecatedSyscallHandler implementation for execution of system calls in the StarkNet OS #[derive(Debug)] @@ -162,14 +161,14 @@ impl SyscallHandler for CallContractHandler { *remaining_gas -= result.gas_consumed; - let retdata = result.retdata.0.iter().map(|sf| felt_api2vm(*sf)).collect(); + let retdata = result.retdata.0; if result.failed { return Err(SyscallExecutionError::SyscallError { error_data: retdata }); } let start_ptr = vm.add_temporary_segment(); - vm.load_data(start_ptr, &retdata.iter().map(MaybeRelocatable::from).collect())?; + vm.load_data(start_ptr, &retdata.iter().map(MaybeRelocatable::from).collect::>())?; Ok(ReadOnlySegment { start_ptr, length: retdata.len() }) } @@ -216,14 +215,14 @@ impl SyscallHandler for DeployHandler { *remaining_gas -= result.gas_consumed; - let retdata = result.retdata.0.iter().map(|sf| felt_api2vm(*sf)).collect(); + let retdata = result.retdata.0; if result.failed { return Err(SyscallExecutionError::SyscallError { error_data: retdata }); } let start_ptr = vm.add_temporary_segment(); - vm.load_data(start_ptr, &retdata.iter().map(MaybeRelocatable::from).collect())?; + vm.load_data(start_ptr, &retdata.iter().map(MaybeRelocatable::from).collect::>())?; let constructor_retdata = ReadOnlySegment { start_ptr, length: retdata.len() }; @@ -377,14 +376,14 @@ impl SyscallHandler for LibraryCallHandler { *remaining_gas -= result.gas_consumed; - let retdata = result.retdata.0.iter().map(|sf| felt_api2vm(*sf)).collect(); + let retdata = result.retdata.0; if result.failed { return Err(SyscallExecutionError::SyscallError { error_data: retdata }); } let start_ptr = vm.add_temporary_segment(); - vm.load_data(start_ptr, &retdata.iter().map(MaybeRelocatable::from).collect())?; + vm.load_data(start_ptr, &retdata.iter().map(MaybeRelocatable::from).collect::>())?; Ok(ReadOnlySegment { start_ptr, length: retdata.len() }) } diff --git a/crates/starknet-os/src/execution/syscall_handler_utils.rs b/crates/starknet-os/src/execution/syscall_handler_utils.rs index 9e8ffa149..503bf137d 100644 --- a/crates/starknet-os/src/execution/syscall_handler_utils.rs +++ b/crates/starknet-os/src/execution/syscall_handler_utils.rs @@ -261,7 +261,8 @@ fn write_failure( // Write the error data to a new memory segment. let revert_reason_start = vm.add_memory_segment(); - let revert_reason_end = vm.load_data(revert_reason_start, &error_data.into_iter().map(Into::into).collect())?; + let revert_reason_end = + vm.load_data(revert_reason_start, &error_data.into_iter().map(Into::into).collect::>())?; // Write the start and end pointers of the error data. write_maybe_relocatable(vm, ptr, revert_reason_start)?; diff --git a/crates/starknet-os/src/hints/block_context.rs b/crates/starknet-os/src/hints/block_context.rs index 87e71834d..1d8653adc 100644 --- a/crates/starknet-os/src/hints/block_context.rs +++ b/crates/starknet-os/src/hints/block_context.rs @@ -24,7 +24,7 @@ use crate::hints::vars; use crate::io::classes::write_class; use crate::io::input::StarknetOsInput; use crate::starknet::core::os::contract_class::compiled_class_hash_objects::BytecodeSegmentStructureImpl; -use crate::utils::{custom_hint_error, felt_api2vm, get_constant}; +use crate::utils::{custom_hint_error, get_constant}; pub const LOAD_CLASS_FACTS: &str = indoc! {r#" ids.compiled_class_facts = segments.add() @@ -234,7 +234,7 @@ pub fn fee_token_address( let os_input = exec_scopes.get::(vars::scopes::OS_INPUT)?; let fee_token_address = *os_input.general_config.starknet_os_config.fee_token_address.0.key(); log::debug!("fee_token_address: {}", fee_token_address); - insert_value_into_ap(vm, felt_api2vm(fee_token_address)) + insert_value_into_ap(vm, fee_token_address) } pub const DEPRECATED_FEE_TOKEN_ADDRESS: &str = @@ -249,7 +249,7 @@ pub fn deprecated_fee_token_address( let os_input = exec_scopes.get::(vars::scopes::OS_INPUT)?; let deprecated_fee_token_address = *os_input.general_config.starknet_os_config.deprecated_fee_token_address.0.key(); log::debug!("deprecated_fee_token_address: {}", deprecated_fee_token_address); - insert_value_into_ap(vm, felt_api2vm(deprecated_fee_token_address)) + insert_value_into_ap(vm, deprecated_fee_token_address) } pub const SEQUENCER_ADDRESS: &str = "memory[ap] = to_felt_or_relocatable(syscall_handler.block_info.sequencer_address)"; @@ -261,7 +261,7 @@ pub fn sequencer_address( _constants: &HashMap, ) -> Result<(), HintError> { let block_context = exec_scopes.get_ref::(vars::scopes::BLOCK_CONTEXT)?; - insert_value_into_ap(vm, felt_api2vm(*block_context.block_info().sequencer_address.0.key())) + insert_value_into_ap(vm, *block_context.block_info().sequencer_address.0.key()) } pub const GET_BLOCK_MAPPING: &str = indoc! {r#" diff --git a/crates/starknet-os/src/hints/execution.rs b/crates/starknet-os/src/hints/execution.rs index df92d0abc..d12142c0b 100644 --- a/crates/starknet-os/src/hints/execution.rs +++ b/crates/starknet-os/src/hints/execution.rs @@ -138,7 +138,8 @@ pub fn prepare_constructor_execution( ap_tracking, )?; - let constructor_calldata = tx.constructor_calldata.unwrap_or_default().iter().map(|felt| felt.into()).collect(); + let constructor_calldata = + tx.constructor_calldata.unwrap_or_default().iter().map(|felt| felt.into()).collect::>(); let constructor_calldata_base = vm.add_memory_segment(); vm.load_data(constructor_calldata_base, &constructor_calldata)?; insert_value_from_var_name(vars::ids::CONSTRUCTOR_CALLDATA, constructor_calldata_base, vm, ids_data, ap_tracking) @@ -586,7 +587,7 @@ pub fn tx_calldata( ) -> Result<(), HintError> { let tx = exec_scopes.get::(vars::scopes::TX)?; let calldata = - tx.calldata.ok_or(custom_hint_error("tx.calldata is None"))?.iter().map(|felt| felt.into()).collect(); + tx.calldata.ok_or(custom_hint_error("tx.calldata is None"))?.iter().map(|felt| felt.into()).collect::>(); let calldata_base = vm.add_memory_segment(); vm.load_data(calldata_base, &calldata)?; insert_value_into_ap(vm, calldata_base) @@ -849,7 +850,7 @@ pub fn gen_signature_arg( let tx = exec_scopes.get::(vars::scopes::TX)?; let signature = tx.signature.ok_or(custom_hint_error("tx.signature is None"))?; let signature_start_base = vm.add_memory_segment(); - let signature = signature.iter().map(|f| MaybeRelocatable::Int(*f)).collect(); + let signature = signature.iter().map(|f| MaybeRelocatable::Int(*f)).collect::>(); vm.load_data(signature_start_base, &signature)?; insert_value_from_var_name(vars::ids::SIGNATURE_START, signature_start_base, vm, ids_data, ap_tracking)?; diff --git a/crates/starknet-os/src/hints/mod.rs b/crates/starknet-os/src/hints/mod.rs index 72f767181..275ee8683 100644 --- a/crates/starknet-os/src/hints/mod.rs +++ b/crates/starknet-os/src/hints/mod.rs @@ -567,7 +567,7 @@ where .tx_execution_info .as_ref() .ok_or(HintError::CustomHint("ExecutionHelper should have tx_execution_info".to_owned().into_boxed_str())) - .map(|tx_execution_info| tx_execution_info.actual_fee) + .map(|tx_execution_info| tx_execution_info.transaction_receipt.fee) })??; insert_value_into_ap(vm, Felt252::from(actual_fee.0)) diff --git a/crates/starknet-os/src/hints/tests.rs b/crates/starknet-os/src/hints/tests.rs index 87546aca4..0906d1dbb 100644 --- a/crates/starknet-os/src/hints/tests.rs +++ b/crates/starknet-os/src/hints/tests.rs @@ -1,6 +1,7 @@ #[cfg(test)] pub mod tests { use blockifier::context::BlockContext; + use blockifier::fee::actual_cost::TransactionReceipt; use blockifier::transaction::objects::TransactionExecutionInfo; use cairo_vm::serde::deserialize_program::ApTracking; use cairo_vm::types::exec_scope::ExecutionScopes; @@ -60,11 +61,13 @@ pub mod tests { validate_call_info: None, execute_call_info: None, fee_transfer_call_info: None, - actual_fee: Fee(1234), - da_gas: Default::default(), - actual_resources: Default::default(), revert_error: None, - bouncer_resources: Default::default(), + transaction_receipt: TransactionReceipt { + fee: Fee(1234), + gas: Default::default(), + da_gas: Default::default(), + resources: Default::default(), + }, } } diff --git a/crates/starknet-os/src/io/classes.rs b/crates/starknet-os/src/io/classes.rs index 7c3e2bd90..ee7dd1d56 100644 --- a/crates/starknet-os/src/io/classes.rs +++ b/crates/starknet-os/src/io/classes.rs @@ -14,7 +14,7 @@ use crate::starknet::core::os::contract_class::compiled_class_hash_objects::{ BytecodeLeaf, BytecodeSegment, BytecodeSegmentStructureImpl, BytecodeSegmentedNode, }; use crate::starkware_utils::commitment_tree::base_types::Length; -use crate::utils::{custom_hint_error, felt_api2vm}; +use crate::utils::custom_hint_error; /// Returns the serialization of a contract as a list of field elements. pub fn get_deprecated_contract_class_struct( @@ -26,7 +26,7 @@ pub fn get_deprecated_contract_class_struct( let mut externals: Vec = Vec::new(); for elem in deprecated_class.entry_points_by_type.get(&EntryPointType::External).unwrap().iter() { - externals.push(MaybeRelocatable::from(felt_api2vm(elem.selector.0))); + externals.push(MaybeRelocatable::from(elem.selector.0)); externals.push(MaybeRelocatable::from(Felt252::from(elem.offset.0))); } vm.insert_value((class_base + 1)?, Felt252::from(externals.len() / 2))?; @@ -37,7 +37,7 @@ pub fn get_deprecated_contract_class_struct( let mut l1_handlers: Vec = Vec::new(); for elem in deprecated_class.entry_points_by_type.get(&EntryPointType::L1Handler).unwrap().iter() { - l1_handlers.push(MaybeRelocatable::from(felt_api2vm(elem.selector.0))); + l1_handlers.push(MaybeRelocatable::from(elem.selector.0)); l1_handlers.push(MaybeRelocatable::from(Felt252::from(elem.offset.0))); } vm.insert_value((class_base + 3)?, Felt252::from(l1_handlers.len() / 2))?; @@ -48,7 +48,7 @@ pub fn get_deprecated_contract_class_struct( let mut constructors: Vec = Vec::new(); for elem in deprecated_class.entry_points_by_type.get(&EntryPointType::Constructor).unwrap().iter() { - constructors.push(MaybeRelocatable::from(felt_api2vm(elem.selector.0))); + constructors.push(MaybeRelocatable::from(elem.selector.0)); constructors.push(MaybeRelocatable::from(Felt252::from(elem.offset.0))); } vm.insert_value((class_base + 5)?, Felt252::from(constructors.len() / 2))?; diff --git a/crates/starknet-os/src/starknet/business_logic/fact_state/state.rs b/crates/starknet-os/src/starknet/business_logic/fact_state/state.rs index 360d4b8f3..28d428c69 100644 --- a/crates/starknet-os/src/starknet/business_logic/fact_state/state.rs +++ b/crates/starknet-os/src/starknet/business_logic/fact_state/state.rs @@ -8,9 +8,7 @@ use blockifier::state::state_api::{StateReader, StateResult}; use cairo_vm::types::errors::math_errors::MathError; use cairo_vm::Felt252; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; -use starknet_api::hash::StarkFelt; use starknet_api::state::StorageKey; -use starknet_crypto::FieldElement; use starknet_os_types::casm_contract_class::GenericCasmContractClass; use starknet_os_types::deprecated_compiled_class::GenericDeprecatedCompiledClass; use starknet_os_types::hash::Hash; @@ -28,9 +26,10 @@ use crate::starknet::starknet_storage::StorageLeaf; use crate::starkware_utils::commitment_tree::base_types::{Height, TreeIndex}; use crate::starkware_utils::commitment_tree::binary_fact_tree::BinaryFactTree; use crate::starkware_utils::commitment_tree::errors::TreeError; +use crate::starkware_utils::commitment_tree::leaf_fact::LeafFact; use crate::starkware_utils::commitment_tree::patricia_tree::patricia_tree::PatriciaTree; use crate::storage::storage::{DbObject, FactFetchingContext, HashFunctionType, Storage, StorageError}; -use crate::utils::{execute_coroutine, felt_api2vm, felt_vm2api}; +use crate::utils::execute_coroutine; /// A class representing a combination of the onchain and offchain state. #[derive(Debug)] @@ -166,7 +165,7 @@ where ) -> Result { let empty_state = Self::empty(ffc).await?; - let mut storage_updates: HashMap> = HashMap::new(); + let mut storage_updates: HashMap> = HashMap::new(); for ((address, key), value) in blockifier_state.storage_view { storage_updates.entry(address).or_default().insert(key, value); } @@ -205,33 +204,23 @@ where address_to_class_hash: HashMap, address_to_nonce: HashMap, class_hash_to_compiled_class_hash: HashMap, - storage_updates: HashMap>, + storage_updates: HashMap>, ) -> Result { - let address_to_class_hash: HashMap<_, _> = address_to_class_hash - .into_iter() - .map(|(address, class_hash)| (felt_api2vm(*address.0.key()), felt_api2vm(class_hash.0))) - .collect(); + let address_to_class_hash: HashMap<_, _> = + address_to_class_hash.into_iter().map(|(address, class_hash)| (*address.0.key(), class_hash.0)).collect(); - let address_to_nonce: HashMap<_, _> = address_to_nonce - .into_iter() - .map(|(address, nonce)| (felt_api2vm(*address.0.key()), felt_api2vm(nonce.0))) - .collect(); + let address_to_nonce: HashMap<_, _> = + address_to_nonce.into_iter().map(|(address, nonce)| (*address.0.key(), nonce.0)).collect(); let class_hash_to_compiled_class_hash: HashMap<_, _> = class_hash_to_compiled_class_hash .into_iter() - .map(|(class_hash, compiled_class_hash)| (felt_api2vm(class_hash.0), felt_api2vm(compiled_class_hash.0))) + .map(|(class_hash, compiled_class_hash)| (class_hash.0, compiled_class_hash.0)) .collect(); let storage_updates: HashMap<_, HashMap<_, _>> = storage_updates .into_iter() .map(|(address, contract_storage_updates)| { - ( - felt_api2vm(*address.0.key()), - contract_storage_updates - .into_iter() - .map(|(k, v)| (felt_api2vm(*k.0.key()), felt_api2vm(v))) - .collect(), - ) + (*address.0.key(), contract_storage_updates.into_iter().map(|(k, v)| (*k.0.key(), v)).collect()) }) .collect(); @@ -325,7 +314,7 @@ where } async fn get_contract_state_async(&self, contract_address: ContractAddress) -> StateResult { - let contract_address: TreeIndex = felt_api2vm(*contract_address.0.key()).to_biguint(); + let contract_address: TreeIndex = contract_address.0.key().to_biguint(); let mut ffc = self.ffc.clone(); @@ -350,7 +339,7 @@ where } async fn get_compiled_class_hash_async(&self, class_hash: ClassHash) -> StateResult { - let class_hash_as_index: TreeIndex = felt_api2vm(class_hash.0).to_biguint(); + let class_hash_as_index: TreeIndex = class_hash.0.to_biguint(); log::debug!("class_hash_as_index: {:?}", class_hash_as_index); log::debug!("have contract_class_tree? {:?}", self.contract_classes.is_some()); @@ -361,6 +350,7 @@ where log::debug!("Should get something from get_leaf()..."); + // TODO: `get_leaf()` should not return an option let contract_class_leaf = >::get_leaf( contract_class_tree, @@ -370,6 +360,11 @@ where .await? .ok_or(StateError::UndeclaredClassHash(class_hash))?; + // Return an error if we get an empty leaf + if >::is_empty(&contract_class_leaf) { + return Err(StateError::UndeclaredClassHash(class_hash))?; + } + contract_class_leaf.compiled_class_hash } // The tree is not initialized; may happen if the reader is based on an old state @@ -377,34 +372,34 @@ where None => Felt252::ZERO, }; - Ok(CompiledClassHash(felt_vm2api(compiled_class_hash))) + Ok(CompiledClassHash(compiled_class_hash)) } async fn get_deprecated_compiled_class( - &mut self, + &self, compiled_class_hash: CompiledClassHash, ) -> Result, StorageError> { let storage = self.ffc.acquire_storage().await; - DeprecatedCompiledClassFact::get(storage.deref(), compiled_class_hash.0.bytes()) + DeprecatedCompiledClassFact::get(storage.deref(), &compiled_class_hash.0.to_bytes_be()) .await .map(|option| option.map(|fact| fact.contract_definition)) } async fn get_compiled_class( - &mut self, + &self, compiled_class_hash: CompiledClassHash, ) -> Result, StorageError> { let storage = self.ffc.acquire_storage().await; - CompiledClassFact::get(storage.deref(), compiled_class_hash.0.bytes()) + CompiledClassFact::get(storage.deref(), &compiled_class_hash.0.to_bytes_be()) .await .map(|option| option.map(|fact| fact.compiled_class)) } /// Returns the contract class of the given class hash. async fn get_compiled_contract_class_async( - &mut self, + &self, compiled_class_hash: CompiledClassHash, ) -> StateResult { log::debug!("SharedState as StateReader: get_compiled_contract_class {:?}", compiled_class_hash); @@ -430,22 +425,20 @@ where Err(StateError::UndeclaredClassHash(ClassHash(compiled_class_hash.0))) } - async fn get_storage_at_async( - &mut self, - contract_address: ContractAddress, - key: StorageKey, - ) -> StateResult { - let storage_key: TreeIndex = felt_api2vm(*key.0.key()).to_biguint(); + async fn get_storage_at_async(&self, contract_address: ContractAddress, key: StorageKey) -> StateResult { + let storage_key: TreeIndex = key.0.key().to_biguint(); + + let mut ffc = self.ffc.clone(); let contract_state = self.get_contract_state_async(contract_address).await?; let storage_items: HashMap = - contract_state.storage_commitment_tree.get_leaves(&mut self.ffc, &[storage_key.clone()], &mut None).await?; + contract_state.storage_commitment_tree.get_leaves(&mut ffc, &[storage_key.clone()], &mut None).await?; let state = storage_items .get(&storage_key) .ok_or(StateError::StateReadError(format!("get_storage_at_async: {:?}", storage_key)))?; - Ok(felt_vm2api(state.value)) + Ok(state.value) } } @@ -457,7 +450,7 @@ where /// Returns the storage value under the given key in the given contract instance (represented by /// its address). /// Default: 0 for an uninitialized contract address. - fn get_storage_at(&mut self, contract_address: ContractAddress, key: StorageKey) -> StateResult { + fn get_storage_at(&self, contract_address: ContractAddress, key: StorageKey) -> StateResult { log::debug!("SharedState as StateReader: get_storage_at {:?} / {:?}", contract_address, key); let value = execute_coroutine(self.get_storage_at_async(contract_address, key)).unwrap(); // TODO: unwrap log::debug!(" -> {:?}", value); @@ -466,40 +459,37 @@ where /// Returns the nonce of the given contract instance. /// Default: 0 for an uninitialized contract address. - fn get_nonce_at(&mut self, contract_address: ContractAddress) -> StateResult { + fn get_nonce_at(&self, contract_address: ContractAddress) -> StateResult { log::debug!("SharedState as StateReader: get_nonce_at {:?}", contract_address); let contract_state = self.get_contract_state(contract_address)?; - let nonce = Nonce(felt_vm2api(contract_state.nonce)); + let nonce = Nonce(contract_state.nonce); log::debug!(" -> {:?}", nonce); Ok(nonce) } /// Returns the class hash of the contract class at the given contract instance. /// Default: 0 (uninitialized class hash) for an uninitialized contract address. - fn get_class_hash_at(&mut self, contract_address: ContractAddress) -> StateResult { + fn get_class_hash_at(&self, contract_address: ContractAddress) -> StateResult { log::debug!("SharedState as StateReader: get_class_hash_at {:?}", contract_address); let contract_state = self.get_contract_state(contract_address)?; // TODO: this can be simplified once hashes are stored as [u8; 32]. Until then, this is fine. - let felt = FieldElement::from_byte_slice_be(&contract_state.contract_hash) - .expect("Conversion to felt should not fail"); + let felt = Felt252::from_bytes_be_slice(&contract_state.contract_hash); log::debug!(" -> {:?}", felt); - Ok(ClassHash(StarkFelt::from(felt))) + Ok(ClassHash(felt)) } /// Returns the contract class of the given class hash. - fn get_compiled_contract_class(&mut self, class_hash: ClassHash) -> StateResult { + fn get_compiled_contract_class(&self, class_hash: ClassHash) -> StateResult { execute_coroutine(async { - let compiled_class_hash = self.get_compiled_class_hash_async(class_hash).await.unwrap(); + let compiled_class_hash = self.get_compiled_class_hash_async(class_hash).await?; self.get_compiled_contract_class_async(compiled_class_hash).await }) .unwrap() // TODO: unwrap } /// Returns the compiled class hash of the given class hash. - fn get_compiled_class_hash(&mut self, class_hash: ClassHash) -> StateResult { + fn get_compiled_class_hash(&self, class_hash: ClassHash) -> StateResult { log::debug!("SharedState as StateReader: get_compiled_class_hash {:?}", class_hash); execute_coroutine(self.get_compiled_class_hash_async(class_hash)).unwrap() // TODO: unwrap } - - // TODO: do we care about `fn get_free_token_balance()`? } diff --git a/crates/starknet-os/src/storage/storage_utils.rs b/crates/starknet-os/src/storage/storage_utils.rs index 5ba77101a..43b34aad9 100644 --- a/crates/starknet-os/src/storage/storage_utils.rs +++ b/crates/starknet-os/src/storage/storage_utils.rs @@ -1,5 +1,4 @@ use blockifier::state::cached_state::CachedState; -use blockifier::state::state_api::State; use cairo_vm::Felt252; use starknet_os_types::hash::Hash; @@ -63,12 +62,16 @@ where } } +// TODO: move this function to where it is used, this should not be a public function of +// the starknet-os library pub async fn unpack_blockifier_state_async( mut blockifier_state: CachedState>, ) -> Result<(SharedState, SharedState), TreeError> { let final_state = { let state = blockifier_state.state.clone(); - state.apply_commitment_state_diff(blockifier_state.to_state_diff()).await? + state + .apply_commitment_state_diff(blockifier_state.to_state_diff().expect("failed to build state diff").into()) + .await? }; let initial_state = blockifier_state.state; diff --git a/crates/starknet-os/src/utils.rs b/crates/starknet-os/src/utils.rs index 606a044f0..65937282e 100644 --- a/crates/starknet-os/src/utils.rs +++ b/crates/starknet-os/src/utils.rs @@ -3,22 +3,13 @@ use std::collections::HashMap; use cairo_vm::types::exec_scope::ExecutionScopes; use cairo_vm::vm::errors::hint_errors::HintError; use cairo_vm::Felt252; -use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Number; use serde_with::{DeserializeAs, SerializeAs}; use starknet_api::core::ChainId; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; +use starknet_os_types::chain_id::chain_id_to_felt; use tokio::task; -pub fn felt_vm2api(felt: Felt252) -> StarkFelt { - stark_felt!(felt.to_hex_string().as_str()) -} - -pub fn felt_api2vm(felt: StarkFelt) -> Felt252 { - Felt252::from_hex(&felt.to_string()).expect("Couldn't parse bytes") -} - pub(crate) struct Felt252Str; impl<'de> DeserializeAs<'de, Felt252> for Felt252Str { @@ -96,8 +87,10 @@ impl<'de> DeserializeAs<'de, ChainId> for ChainIdNum { where D: Deserializer<'de>, { - let felt_num = u128::deserialize(deserializer)?; - Ok(ChainId(format!("{felt_num:x}"))) + let bytes = u128::deserialize(deserializer)?.to_be_bytes(); + let chain_id_str = String::from_utf8_lossy(&bytes); + + Ok(ChainId::from(chain_id_str.into_owned())) } } @@ -106,7 +99,8 @@ impl SerializeAs for ChainIdNum { where S: Serializer, { - serializer.serialize_u128(u128::from_str_radix(&value.0, 16).map_err(ser::Error::custom)?) + let chain_id_felt = chain_id_to_felt(value); + chain_id_felt.serialize(serializer) } } @@ -159,7 +153,6 @@ pub(crate) fn custom_hint_error>(error: S) -> HintError { #[cfg(test)] mod tests { - use bitvec::prelude::*; use serde_with::serde_as; use super::*; @@ -171,30 +164,9 @@ mod tests { chain_id: ChainId, } - #[test] - fn felt_conversions() { - let vm_felt = Felt252::from_hex("0xDEADBEEF").unwrap(); - let api_felt = stark_felt!("DEADBEEF"); - - assert_eq!(vm_felt, felt_api2vm(api_felt)); - assert_eq!(api_felt, felt_vm2api(vm_felt)); - - let mut bv = bitvec![u8, Msb0; 0; 219]; - bv.extend_from_bitslice(0xDEADBEEF_u32.view_bits::()); - } - #[test] fn chain_id_num_ok() { - let c = ChainIdOnly { chain_id: ChainId("534e5f474f45524c49".to_string()) }; - - serde_json::to_string(&c).unwrap(); - } - - #[test] - #[should_panic] - fn chain_id_num_fail() { - let c = ChainIdOnly { chain_id: ChainId("SN_GOERLI".to_string()) }; - + let c = ChainIdOnly { chain_id: ChainId::Sepolia }; serde_json::to_string(&c).unwrap(); } } diff --git a/tests/integration/common/block_utils.rs b/tests/integration/common/block_utils.rs index bfbb03d60..9bcda9549 100644 --- a/tests/integration/common/block_utils.rs +++ b/tests/integration/common/block_utils.rs @@ -2,13 +2,12 @@ use std::collections::{HashMap, HashSet}; use blockifier::context::BlockContext; use blockifier::execution::contract_class::ContractClass::{V0, V1}; -use blockifier::state::cached_state::CachedState; -use blockifier::state::state_api::{State, StateReader}; +use blockifier::state::cached_state::{CachedState, CommitmentStateDiff}; +use blockifier::state::state_api::StateReader; use blockifier::transaction::objects::TransactionExecutionInfo; use cairo_vm::Felt252; use num_bigint::BigUint; use starknet_api::core::{ClassHash, ContractAddress, PatriciaKey}; -use starknet_api::hash::StarkHash; use starknet_os::config::{StarknetGeneralConfig, StarknetOsConfig, STORED_BLOCK_HASH_BUFFER}; use starknet_os::crypto::pedersen::PedersenHash; use starknet_os::crypto::poseidon::PoseidonHash; @@ -22,12 +21,9 @@ use starknet_os::starknet::starknet_storage::{CommitmentInfo, OsSingleStarknetSt use starknet_os::starkware_utils::commitment_tree::base_types::{Height, TreeIndex}; use starknet_os::storage::storage::Storage; use starknet_os::storage::storage_utils::build_starknet_storage_async; -use starknet_os::utils::{felt_api2vm, felt_vm2api}; use starknet_os_types::casm_contract_class::GenericCasmContractClass; use starknet_os_types::deprecated_compiled_class::GenericDeprecatedCompiledClass; -use crate::common::transaction_utils::to_felt252; - pub async fn os_hints( block_context: &BlockContext, mut blockifier_state: CachedState>, @@ -48,18 +44,19 @@ where .map(|address_biguint| { // TODO: biguint is exacerbating the type conversion problem, ideas...? let address: ContractAddress = - ContractAddress(PatriciaKey::try_from(felt_vm2api(Felt252::from(address_biguint))).unwrap()); + ContractAddress(PatriciaKey::try_from(Felt252::from(address_biguint)).unwrap()); let contract_state = blockifier_state.state.get_contract_state(address).unwrap(); - (to_felt252(address.0.key()), contract_state) + (*address.0.key(), contract_state) }) .collect(); // provide an empty ContractState for any newly deployed contract - let state_diff = blockifier_state.to_state_diff(); + let state_diff = + CommitmentStateDiff::from(blockifier_state.to_state_diff().expect("unable to generate state diff")); let deployed_addresses = state_diff.address_to_class_hash; for (address, _class_hash) in &deployed_addresses { contracts.insert( - to_felt252(address.0.key()), + *address.0.key(), ContractState::empty(Height(251), &mut blockifier_state.state.ffc).await.unwrap(), ); } @@ -69,11 +66,11 @@ where let mut class_hash_to_compiled_class_hash: HashMap = state_diff .class_hash_to_compiled_class_hash .iter() - .map(|(class_hash, _compiled_class_hash)| (felt_api2vm(class_hash.0), Felt252::ZERO)) + .map(|(class_hash, _compiled_class_hash)| (class_hash.0, Felt252::ZERO)) .collect(); for c in contracts.keys() { - let address = ContractAddress::try_from(StarkHash::new(c.to_bytes_be()).unwrap()).unwrap(); + let address = ContractAddress(PatriciaKey::try_from(*c).unwrap()); let class_hash = blockifier_state.get_class_hash_at(address).unwrap(); let blockifier_class = blockifier_state.get_compiled_contract_class(class_hash).unwrap(); match blockifier_class { @@ -83,7 +80,7 @@ where compiled_classes.get(&class_hash).unwrap_or_else(|| panic!("No class given for {:?}", class_hash)); let compiled_class_hash = compiled_class.class_hash().expect("Failed to compute class hash"); let compiled_class_hash = Felt252::from(compiled_class_hash); - class_hash_to_compiled_class_hash.insert(to_felt252(&class_hash.0), compiled_class_hash); + class_hash_to_compiled_class_hash.insert(class_hash.0, compiled_class_hash); compiled_class_hash_to_compiled_class.insert(compiled_class_hash, compiled_class.clone()); } @@ -125,7 +122,7 @@ where let general_config = StarknetGeneralConfig { starknet_os_config: StarknetOsConfig { - chain_id: default_general_config.starknet_os_config.chain_id, + chain_id: block_context.chain_info().chain_id.clone(), fee_token_address: block_context.chain_info().fee_token_addresses.strk_fee_token_address, deprecated_fee_token_address: block_context.chain_info().fee_token_addresses.eth_fee_token_address, }, @@ -140,7 +137,7 @@ where .visited_pcs .iter() .map(|(class_hash, visited_pcs)| { - let class_hash_felt = felt_api2vm(class_hash.0); + let class_hash_felt = class_hash.0; let compiled_class_hash_felt = class_hash_to_compiled_class_hash.get(&class_hash_felt).unwrap(); (*compiled_class_hash_felt, visited_pcs.iter().copied().map(Felt252::from).collect::>()) }) @@ -169,7 +166,7 @@ where .class_hash_to_compiled_class_hash .keys() .chain(compiled_classes.keys()) - .map(|class_hash| BigUint::from_bytes_be(class_hash.0.bytes())) + .map(|class_hash| class_hash.to_biguint()) .collect(); let contract_class_commitment_info = @@ -183,7 +180,7 @@ where .unwrap_or_else(|e| panic!("Could not create contract class commitment info: {:?}", e)); let deprecated_compiled_classes: HashMap<_, _> = - deprecated_compiled_classes.into_iter().map(|(k, v)| (felt_api2vm(k.0), v)).collect(); + deprecated_compiled_classes.into_iter().map(|(k, v)| (k.0, v)).collect(); let os_input = StarknetOsInput { contract_state_commitment_info, diff --git a/tests/integration/common/state.rs b/tests/integration/common/state.rs index df355bfc7..95043cc65 100644 --- a/tests/integration/common/state.rs +++ b/tests/integration/common/state.rs @@ -10,8 +10,6 @@ use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use rstest::fixture; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress}; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; use starknet_os::crypto::pedersen::PedersenHash; use starknet_os::starknet::business_logic::fact_state::state::SharedState; use starknet_os::starknet::business_logic::utils::{write_class_facts, write_deprecated_compiled_class_fact}; @@ -272,7 +270,7 @@ impl<'a> StarknetStateBuilder<'a> { for (name, contract) in cairo0_contracts { let deprecated_compiled_class = contract.deprecated_compiled_class; let class_hash = write_deprecated_compiled_class_fact(deprecated_compiled_class.clone(), ffc).await?; - let class_hash = ClassHash::try_from(class_hash).expect("Class hash is not in prime field"); + let class_hash = ClassHash::from(class_hash); Self::add_cairo0_contract_to_state(class_hash, deprecated_compiled_class.clone(), dict_state_reader); @@ -299,7 +297,7 @@ impl<'a> StarknetStateBuilder<'a> { let deprecated_compiled_class = contract.contract.deprecated_compiled_class; let class_hash = write_deprecated_compiled_class_fact(deprecated_compiled_class.clone(), ffc).await?; - let class_hash = ClassHash::try_from(class_hash).expect("Class hash is not in prime field"); + let class_hash = ClassHash::from(class_hash); // Add entries in the dict state Self::add_cairo0_contract_to_state(class_hash, deprecated_compiled_class.clone(), dict_state_reader); @@ -345,9 +343,8 @@ impl<'a> StarknetStateBuilder<'a> { let (contract_class_hash, compiled_class_hash) = write_class_facts(contract_class.clone().into(), compiled_contract_class.clone(), ffc).await?; - let class_hash = ClassHash::try_from(contract_class_hash).expect("Class hash is not in prime field"); - let compiled_class_hash = - CompiledClassHash::try_from(compiled_class_hash).expect("Compiled class hash is not in prime field"); + let class_hash = ClassHash::from(contract_class_hash); + let compiled_class_hash = CompiledClassHash::from(compiled_class_hash); Self::add_cairo1_contract_to_state( class_hash, @@ -385,9 +382,8 @@ impl<'a> StarknetStateBuilder<'a> { let (contract_class_hash, compiled_class_hash) = write_class_facts(contract_class.clone().into(), compiled_contract_class.clone(), ffc).await?; - let class_hash = ClassHash::try_from(contract_class_hash).expect("Class hash is not in prime field"); - let compiled_class_hash = - CompiledClassHash::try_from(compiled_class_hash).expect("Compiled class hash is not in prime field"); + let class_hash = ClassHash::from(contract_class_hash); + let compiled_class_hash = CompiledClassHash::from(compiled_class_hash); // Add entries in the dict state Self::add_cairo1_contract_to_state( @@ -445,8 +441,8 @@ impl<'a> StarknetStateBuilder<'a> { ) { let storage_view = &mut dict_state_reader.storage_view; let balance_key = get_fee_token_var_address(account_address); - storage_view.insert((fee_config.eth_fee_token_address, balance_key), stark_felt!(balance.eth)); - storage_view.insert((fee_config.strk_fee_token_address, balance_key), stark_felt!(balance.strk)); + storage_view.insert((fee_config.eth_fee_token_address, balance_key), balance.eth.into()); + storage_view.insert((fee_config.strk_fee_token_address, balance_key), balance.strk.into()); } /// Converts the dict state reader and FFC into a shared state object. diff --git a/tests/integration/common/transaction_utils.rs b/tests/integration/common/transaction_utils.rs index 1b49ad16e..e17ce3078 100644 --- a/tests/integration/common/transaction_utils.rs +++ b/tests/integration/common/transaction_utils.rs @@ -15,14 +15,13 @@ use cairo_vm::Felt252; use num_bigint::BigUint; use rstest::rstest; use starknet_api::core::{calculate_contract_address, ChainId, ClassHash, ContractAddress, PatriciaKey}; -use starknet_api::hash::{StarkFelt, StarkHash}; use starknet_api::state::StorageKey; use starknet_api::transaction::{ DeclareTransactionV0V1, DeclareTransactionV2, DeclareTransactionV3, DeployAccountTransactionV1, DeployAccountTransactionV3, InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, Resource, - ResourceBoundsMapping, + ResourceBoundsMapping, TransactionHash, }; -use starknet_api::{contract_address, patricia_key, stark_felt}; +use starknet_api::{contract_address, felt, patricia_key}; use starknet_crypto::{pedersen_hash, FieldElement}; use starknet_os::config::{BLOCK_HASH_CONTRACT_ADDRESS, STORED_BLOCK_HASH_BUFFER}; use starknet_os::crypto::pedersen::PedersenHash; @@ -37,7 +36,6 @@ use starknet_os::starknet::business_logic::fact_state::state::SharedState; use starknet_os::starknet::core::os::transaction_hash::{L1_GAS, L2_GAS}; use starknet_os::starknet::starknet_storage::OsSingleStarknetStorage; use starknet_os::storage::storage::Storage; -use starknet_os::utils::felt_api2vm; use starknet_os::{config, run_os}; use starknet_os_types::casm_contract_class::GenericCasmContractClass; use starknet_os_types::chain_id::chain_id_to_felt; @@ -45,10 +43,6 @@ use starknet_os_types::deprecated_compiled_class::GenericDeprecatedCompiledClass use crate::common::block_utils::os_hints; -pub fn to_felt252(stark_felt: &StarkFelt) -> Felt252 { - Felt252::from_bytes_be_slice(stark_felt.bytes()) -} - const DECLARE_PREFIX: &[u8] = b"declare"; const DEPLOY_ACCOUNT_PREFIX: &[u8] = b"deploy_account"; const INVOKE_PREFIX: &[u8] = b"invoke"; @@ -424,17 +418,17 @@ fn account_tx_to_internal_tx(account_tx: &AccountTransaction, chain_id: &ChainId } } fn to_internal_l1_handler_tx(l1_tx: &L1HandlerTransaction, chain_id: &ChainId) -> InternalTransaction { - let contract_address = felt_api2vm(*l1_tx.tx.contract_address.0); - let entry_point_selector = felt_api2vm(l1_tx.tx.entry_point_selector.0); + let contract_address = *l1_tx.tx.contract_address.0; + let entry_point_selector = l1_tx.tx.entry_point_selector.0; let txinfo = l1_tx.create_tx_info(); let signature = match txinfo { TransactionInfo::Deprecated(tx) => tx.common_fields.signature, TransactionInfo::Current(tx) => tx.common_fields.signature, }; - let signature = signature.0.iter().map(to_felt252).collect(); - let calldata: Vec<_> = l1_tx.tx.calldata.0.iter().map(to_felt252).collect(); + let signature = signature.0.to_vec(); + let calldata: Vec<_> = l1_tx.tx.calldata.0.iter().copied().collect(); let chain_id_felt = chain_id_to_felt(chain_id); - let nonce = felt_api2vm(l1_tx.tx.nonce.0); + let nonce = l1_tx.tx.nonce.0; let fee = Felt252::ZERO; let hash_value = l1_tx_compute_hash(contract_address, entry_point_selector, &calldata, fee, chain_id_felt, nonce); @@ -463,15 +457,15 @@ pub fn to_internal_declare_v1_tx( let sender_address; let class_hash; let max_fee = tx.max_fee.0.into(); - let signature = tx.signature.0.iter().map(to_felt252).collect(); + let signature = tx.signature.0.to_vec(); let chain_id_felt = chain_id_to_felt(chain_id); - let nonce = felt_api2vm(tx.nonce.0); + let nonce = tx.nonce.0; match account_tx.create_tx_info() { TransactionInfo::Current(_) => unreachable!("v1 transactions can only contain a `Deprecated` variant"), TransactionInfo::Deprecated(context) => { - sender_address = felt_api2vm(*context.common_fields.sender_address.0.key()); - class_hash = felt_api2vm(tx.class_hash.0); + sender_address = *context.common_fields.sender_address.0.key(); + class_hash = tx.class_hash.0; hash_value = tx_hash_declare_v1(sender_address, max_fee, class_hash, chain_id_felt, nonce); } @@ -500,29 +494,27 @@ fn to_internal_deploy_v1_tx( TransactionInfo::Current(_) => unreachable!("TxV1 can only have deprecated variant"), TransactionInfo::Deprecated(context) => context.common_fields.sender_address, }; - let sender_address_felt = felt_api2vm(*sender_address.key()); - - let contract_address = felt_api2vm( - *calculate_contract_address( - tx.contract_address_salt, - tx.class_hash, - &tx.constructor_calldata, - contract_address!("0x0"), - ) - .unwrap() - .key(), - ); + let sender_address_felt = *sender_address.key(); + + let contract_address = *calculate_contract_address( + tx.contract_address_salt, + tx.class_hash, + &tx.constructor_calldata, + contract_address!("0x0"), + ) + .unwrap() + .key(); let max_fee: Felt252 = tx.max_fee.0.into(); - let signature = Some(tx.signature.0.iter().map(to_felt252).collect()); + let signature = Some(tx.signature.0.to_vec()); let entry_point_selector = Some(Felt252::ZERO); let chain_id_felt = chain_id_to_felt(chain_id); - let nonce = felt_api2vm(tx.nonce.0); + let nonce = tx.nonce.0; - let class_hash = felt_api2vm(tx.class_hash.0); + let class_hash = tx.class_hash.0; - let constructor_calldata: Vec<_> = tx.constructor_calldata.0.iter().map(to_felt252).collect(); - let contract_address_salt = felt_api2vm(tx.contract_address_salt.0); + let constructor_calldata: Vec<_> = tx.constructor_calldata.0.iter().copied().collect(); + let contract_address_salt = tx.contract_address_salt.0; let hash_value = tx_hash_deploy_account_v1( contract_address, @@ -561,24 +553,18 @@ pub fn to_internal_declare_v2_tx( let sender_address; let class_hash; let max_fee = tx.max_fee.0.into(); - let signature = tx.signature.0.iter().map(to_felt252).collect(); - let nonce = felt_api2vm(tx.nonce.0); + let signature = tx.signature.0.to_vec(); + let nonce = tx.nonce.0; let chain_id_felt = chain_id_to_felt(chain_id); match account_tx.create_tx_info() { TransactionInfo::Current(_) => panic!("Not implemented"), TransactionInfo::Deprecated(context) => { - sender_address = felt_api2vm(*context.common_fields.sender_address.0.key()); - class_hash = felt_api2vm(tx.class_hash.0); - - hash_value = tx_hash_declare_v2( - sender_address, - max_fee, - class_hash, - felt_api2vm(tx.compiled_class_hash.0), - chain_id_felt, - nonce, - ); + sender_address = *context.common_fields.sender_address.0.key(); + class_hash = tx.class_hash.0; + + hash_value = + tx_hash_declare_v2(sender_address, max_fee, class_hash, tx.compiled_class_hash.0, chain_id_felt, nonce); } } @@ -590,7 +576,7 @@ pub fn to_internal_declare_v2_tx( entry_point_type: Some("EXTERNAL".to_string()), signature: Some(signature), class_hash: Some(class_hash), - compiled_class_hash: Some(felt_api2vm(tx.compiled_class_hash.0)), + compiled_class_hash: Some(tx.compiled_class_hash.0), r#type: "DECLARE".to_string(), max_fee: Some(max_fee), ..Default::default() @@ -599,21 +585,21 @@ pub fn to_internal_declare_v2_tx( /// Convert a DeclareTransactionV2 to a SNOS InternalTransaction pub fn to_internal_declare_v3_tx(tx: &DeclareTransactionV3, chain_id: &ChainId) -> InternalTransaction { - let signature = Some(tx.signature.0.iter().map(to_felt252).collect()); - let entry_point_selector = to_felt252(&selector_from_name("__execute__").0); - let sender_address = to_felt252(tx.sender_address.0.key()); - let nonce = felt_api2vm(tx.nonce.0); + let signature = Some(tx.signature.0.to_vec()); + let entry_point_selector = selector_from_name("__execute__").0; + let sender_address = *tx.sender_address.0.key(); + let nonce = tx.nonce.0; let chain_id_felt = chain_id_to_felt(chain_id); - let tip = felt_api2vm(tx.tip.0.into()); + let tip = tx.tip.0.into(); let nonce_data_availability_mode = Felt252::from(tx.nonce_data_availability_mode as u64); let fee_data_availability_mode = Felt252::from(tx.fee_data_availability_mode as u64); let resource_bounds = &tx.resource_bounds; - let paymaster_data: Vec = tx.paymaster_data.0.iter().map(to_felt252).collect(); - let account_deployment_data: Vec = tx.account_deployment_data.0.iter().map(to_felt252).collect(); - let class_hash = felt_api2vm(tx.class_hash.0); - let compiled_class_hash = felt_api2vm(tx.compiled_class_hash.0); + let paymaster_data: Vec = tx.paymaster_data.0.to_vec(); + let account_deployment_data: Vec = tx.account_deployment_data.0.to_vec(); + let class_hash = tx.class_hash.0; + let compiled_class_hash = tx.compiled_class_hash.0; let hash_value = tx_hash_declare_v3( nonce, sender_address, @@ -652,10 +638,10 @@ pub fn to_internal_declare_v3_tx(tx: &DeclareTransactionV3, chain_id: &ChainId) /// Convert a InvokeTransactionV0 to a SNOS InternalTransaction pub fn to_internal_invoke_v0_tx(tx: &InvokeTransactionV0, chain_id: &ChainId) -> InternalTransaction { let max_fee = tx.max_fee.0.into(); - let signature = Some(tx.signature.0.iter().map(to_felt252).collect()); - let entry_point_selector = to_felt252(&tx.entry_point_selector.0); - let calldata: Vec<_> = tx.calldata.0.iter().map(to_felt252).collect(); - let contract_address = to_felt252(tx.contract_address.0.key()); + let signature = Some(tx.signature.0.to_vec()); + let entry_point_selector = tx.entry_point_selector.0; + let calldata: Vec<_> = tx.calldata.0.iter().copied().collect(); + let contract_address = *tx.contract_address.0.key(); let chain_id_felt = chain_id_to_felt(chain_id); let hash_value = tx_hash_invoke_v0(contract_address, entry_point_selector, calldata.clone(), max_fee, chain_id_felt); @@ -679,11 +665,11 @@ pub fn to_internal_invoke_v0_tx(tx: &InvokeTransactionV0, chain_id: &ChainId) -> /// Convert a InvokeTransactionV1 to a SNOS InternalTransaction pub fn to_internal_invoke_v1_tx(tx: &InvokeTransactionV1, chain_id: &ChainId) -> InternalTransaction { let max_fee = tx.max_fee.0.into(); - let signature = Some(tx.signature.0.iter().map(to_felt252).collect()); - let entry_point_selector = Some(to_felt252(&selector_from_name("__execute__").0)); - let calldata = Some(tx.calldata.0.iter().map(to_felt252).collect()); - let contract_address = to_felt252(tx.sender_address.0.key()); - let nonce = felt_api2vm(tx.nonce.0); + let signature = Some(tx.signature.0.to_vec()); + let entry_point_selector = Some(selector_from_name("__execute__").0); + let calldata = Some(tx.calldata.0.iter().copied().collect()); + let contract_address = *tx.sender_address.0.key(); + let nonce = tx.nonce.0; let chain_id_felt = chain_id_to_felt(chain_id); let hash_value = tx_hash_invoke_v1(contract_address, calldata.clone().unwrap(), max_fee, chain_id_felt, nonce); @@ -705,20 +691,20 @@ pub fn to_internal_invoke_v1_tx(tx: &InvokeTransactionV1, chain_id: &ChainId) -> /// Convert a InvokeTransactionV3 to a SNOS InternalTransaction pub fn to_internal_invoke_v3_tx(tx: &InvokeTransactionV3, chain_id: &ChainId) -> InternalTransaction { - let signature = Some(tx.signature.0.iter().map(to_felt252).collect()); - let entry_point_selector = to_felt252(&selector_from_name("__execute__").0); - let calldata: Vec<_> = tx.calldata.0.iter().map(to_felt252).collect(); - let sender_address = to_felt252(tx.sender_address.0.key()); - let nonce = felt_api2vm(tx.nonce.0); + let signature = Some(tx.signature.0.to_vec()); + let entry_point_selector = selector_from_name("__execute__").0; + let calldata: Vec<_> = tx.calldata.0.iter().copied().collect(); + let sender_address = *tx.sender_address.0.key(); + let nonce = tx.nonce.0; let chain_id_felt = chain_id_to_felt(chain_id); - let tip = felt_api2vm(tx.tip.0.into()); + let tip = tx.tip.0.into(); let nonce_data_availability_mode = Felt252::from(tx.nonce_data_availability_mode as u64); let fee_data_availability_mode = Felt252::from(tx.fee_data_availability_mode as u64); let resource_bounds = &tx.resource_bounds; - let paymaster_data: Vec = tx.paymaster_data.0.iter().map(to_felt252).collect(); - let account_deployment_data: Vec = tx.account_deployment_data.0.iter().map(to_felt252).collect(); + let paymaster_data: Vec = tx.paymaster_data.0.to_vec(); + let account_deployment_data: Vec = tx.account_deployment_data.0.to_vec(); let hash_value = tx_hash_invoke_v3( nonce, sender_address, @@ -762,21 +748,21 @@ pub fn to_internal_deploy_v3_tx( AccountTransaction::DeployAccount(a) => a.contract_address, _ => unreachable!(), }; - let signature = Some(tx.signature.0.iter().map(to_felt252).collect()); + let signature = Some(tx.signature.0.to_vec()); let entry_point_selector = Some(Felt252::ZERO); - let calldata: Vec<_> = tx.constructor_calldata.0.iter().map(to_felt252).collect(); + let calldata: Vec<_> = tx.constructor_calldata.0.iter().copied().collect(); - let nonce = felt_api2vm(tx.nonce.0); + let nonce = tx.nonce.0; let chain_id_felt = chain_id_to_felt(chain_id); - let tip = felt_api2vm(tx.tip.0.into()); + let tip = tx.tip.0.into(); let nonce_data_availability_mode = Felt252::from(tx.nonce_data_availability_mode as u64); let fee_data_availability_mode = Felt252::from(tx.fee_data_availability_mode as u64); let resource_bounds = &tx.resource_bounds; - let paymaster_data: Vec = tx.paymaster_data.0.iter().map(to_felt252).collect(); - let contract_address_salt = felt_api2vm(tx.contract_address_salt.0); - let class_hash = to_felt252(&tx.class_hash.0); + let paymaster_data: Vec = tx.paymaster_data.0.to_vec(); + let contract_address_salt = tx.contract_address_salt.0; + let class_hash = tx.class_hash.0; let contract_address = calculate_contract_address( tx.contract_address_salt, @@ -785,11 +771,11 @@ pub fn to_internal_deploy_v3_tx( ContractAddress::from(0_u8), ) .unwrap(); - let contract_address = felt_api2vm(*contract_address.0); + let contract_address_felt = *contract_address.0.key(); let hash_value = tx_hash_deploy_v3( nonce, - contract_address, + contract_address_felt, chain_id_felt, nonce_data_availability_mode, fee_data_availability_mode, @@ -805,8 +791,8 @@ pub fn to_internal_deploy_v3_tx( hash_value, version: Some(Felt252::THREE), nonce: Some(nonce), - sender_address: Some(to_felt252(&sender_address.0)), - contract_address: Some(contract_address), + sender_address: Some(*sender_address.0), + contract_address: Some(contract_address_felt), entry_point_selector, entry_point_type: Some("CONSTRUCTOR".to_string()), r#type: "DEPLOY_ACCOUNT".to_string(), @@ -824,6 +810,18 @@ pub fn to_internal_deploy_v3_tx( } } +/// Retrieves the transaction hash from a Blockifier `Transaction` object. +fn get_tx_hash(tx: &Transaction) -> TransactionHash { + match tx { + Transaction::AccountTransaction(account_tx) => match account_tx { + AccountTransaction::Declare(declare_tx) => declare_tx.tx_hash, + AccountTransaction::DeployAccount(deploy_tx) => deploy_tx.tx_hash, + AccountTransaction::Invoke(invoke_tx) => invoke_tx.tx_hash, + }, + Transaction::L1HandlerTransaction(l1_handler_tx) => l1_handler_tx.tx_hash, + } +} + async fn execute_txs( mut state: CachedState>, block_context: &BlockContext, @@ -836,23 +834,33 @@ where { let upper_bound_block_number = block_context.block_info().block_number.0 - STORED_BLOCK_HASH_BUFFER; let block_number = StorageKey::from(upper_bound_block_number); - let block_hash = stark_felt!(66_u64); + let block_hash = felt!(66_u64); - let block_hash_contract_address = ContractAddress::try_from(stark_felt!(BLOCK_HASH_CONTRACT_ADDRESS)).unwrap(); + let block_hash_contract_address = ContractAddress::try_from(felt!(BLOCK_HASH_CONTRACT_ADDRESS)).unwrap(); state.set_storage_at(block_hash_contract_address, block_number, block_hash).unwrap(); let internal_txs: Vec<_> = txs.iter().map(|tx| to_internal_tx(tx, &block_context.chain_info().chain_id)).collect(); + let n_txs = internal_txs.len(); + let execution_infos = txs .into_iter() - .map(|tx| { + .enumerate() + .map(|(index, tx)| { + let tx_hash = get_tx_hash(&tx).to_hex_string(); let tx_result = tx.execute(&mut state, block_context, true, true); match tx_result { Err(e) => { - panic!("Transaction failed in blockifier: {}", e); + panic!("Transaction {} ({}/{}) failed in blockifier: {}", tx_hash, index + 1, n_txs, e); } Ok(info) => { if info.is_reverted() { - log::error!("Transaction reverted: {:?}", info.revert_error); + log::error!( + "Transaction {} ({}/{}) reverted: {:?}", + tx_hash, + index + 1, + n_txs, + info.revert_error + ); log::warn!("TransactionExecutionInfo: {:?}", info); panic!("A transaction reverted during execution: {:?}", info); } diff --git a/tests/integration/declare_txn_tests.rs b/tests/integration/declare_txn_tests.rs index 896aa9f60..5a55ce200 100644 --- a/tests/integration/declare_txn_tests.rs +++ b/tests/integration/declare_txn_tests.rs @@ -1,17 +1,17 @@ use blockifier::context::BlockContext; use blockifier::declare_tx_args; use blockifier::execution::contract_class::ClassInfo; -use blockifier::test_utils::NonceManager; +use blockifier::test_utils::{NonceManager, BALANCE}; use blockifier::transaction::test_utils::{calculate_class_info_for_testing, max_fee}; -use rstest::rstest; +use rstest::{fixture, rstest}; use starknet_api::core::CompiledClassHash; use starknet_api::transaction::{Fee, Resource, ResourceBounds, ResourceBoundsMapping, TransactionVersion}; use starknet_os::crypto::poseidon::PoseidonHash; use starknet_os::starknet::business_logic::utils::write_class_facts; use crate::common::block_context; -use crate::common::blockifier_contracts::load_cairo1_feature_contract; -use crate::common::state::{initial_state_cairo0, initial_state_cairo1, StarknetTestState}; +use crate::common::blockifier_contracts::{load_cairo0_feature_contract, load_cairo1_feature_contract}; +use crate::common::state::{init_logging, initial_state_cairo1, StarknetStateBuilder, StarknetTestState}; use crate::common::transaction_utils::execute_txs_and_run_os; // Copied from the non-public Blockifier fn @@ -52,8 +52,8 @@ async fn declare_v3_cairo1_account( let sender_address = account_contract.address; let contract_class = casm_class.to_blockifier_contract_class().unwrap(); - let class_hash = starknet_api::core::ClassHash::try_from(contract_class_hash).unwrap(); - let compiled_class_hash = CompiledClassHash::try_from(compiled_class_hash).unwrap(); + let class_hash = starknet_api::core::ClassHash::from(contract_class_hash); + let compiled_class_hash = CompiledClassHash::from(compiled_class_hash); let class_info = ClassInfo::new(&contract_class.into(), sierra_class.sierra_program.len(), 0).unwrap(); @@ -111,8 +111,8 @@ async fn declare_cairo1_account( let sender_address = account_contract.address; let contract_class = casm_class.to_blockifier_contract_class().unwrap(); - let class_hash = starknet_api::core::ClassHash::try_from(contract_class_hash).unwrap(); - let compiled_class_hash = CompiledClassHash::try_from(compiled_class_hash).unwrap(); + let class_hash = starknet_api::core::ClassHash::from(contract_class_hash); + let compiled_class_hash = CompiledClassHash::from(compiled_class_hash); let class_info = ClassInfo::new(&contract_class.into(), sierra_class.sierra_program.len(), 0).unwrap(); @@ -140,26 +140,38 @@ async fn declare_cairo1_account( .expect("OS run failed"); } +#[fixture] +async fn initial_state_declare_cairo0( + block_context: BlockContext, + #[from(init_logging)] _logging: (), +) -> StarknetTestState { + let account_with_dummy_validate = load_cairo0_feature_contract("account_with_dummy_validate"); + + StarknetStateBuilder::new(&block_context) + .deploy_cairo0_contract(account_with_dummy_validate.0, account_with_dummy_validate.1) + .set_default_balance(BALANCE, BALANCE) + .build() + .await +} + #[rstest] // We need to use the multi_thread runtime to use task::block_in_place for sync -> async calls. #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn declare_v1_cairo0_account( - #[future] initial_state_cairo0: StarknetTestState, + #[future] initial_state_declare_cairo0: StarknetTestState, block_context: BlockContext, max_fee: Fee, ) { - let initial_state = initial_state_cairo0.await; - - let mut nonce_manager = NonceManager::default(); - + let initial_state = initial_state_declare_cairo0.await; let sender_address = initial_state.deployed_cairo0_contracts.get("account_with_dummy_validate").unwrap().address; - let test_contract = initial_state.deployed_cairo0_contracts.get("test_contract").unwrap(); - let tx_version = TransactionVersion::ONE; + let (_, test_contract) = load_cairo0_feature_contract("test_contract"); + let class_hash = test_contract.class_hash().unwrap(); - let class_hash = test_contract.declaration.class_hash; + let mut nonce_manager = NonceManager::default(); + let tx_version = TransactionVersion::ONE; - let blockifier_class = test_contract.declaration.class.get_blockifier_contract_class().unwrap().clone(); + let blockifier_class = test_contract.to_blockifier_contract_class().unwrap(); let class_info = calculate_class_info_for_testing(blockifier_class.into()); let declare_tx = blockifier::test_utils::declare::declare_tx( @@ -168,7 +180,7 @@ async fn declare_v1_cairo0_account( sender_address, version: tx_version, nonce: nonce_manager.next(sender_address), - class_hash: class_hash, + class_hash: class_hash.into(), }, class_info, ); diff --git a/tests/integration/deploy_txn_tests.rs b/tests/integration/deploy_txn_tests.rs index 2aa70bcf3..fdaed6d00 100644 --- a/tests/integration/deploy_txn_tests.rs +++ b/tests/integration/deploy_txn_tests.rs @@ -4,11 +4,11 @@ use blockifier::test_utils::deploy_account::deploy_account_tx; use blockifier::test_utils::{NonceManager, BALANCE}; use blockifier::transaction::account_transaction::AccountTransaction; use blockifier::transaction::test_utils::max_fee; +use cairo_vm::Felt252; use rstest::{fixture, rstest}; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, PatriciaKey}; -use starknet_api::hash::{StarkFelt, StarkHash}; use starknet_api::transaction::{Calldata, ContractAddressSalt, Fee, TransactionVersion}; -use starknet_api::{class_hash, contract_address, patricia_key, stark_felt}; +use starknet_api::{class_hash, contract_address, felt, patricia_key}; use crate::common::block_context; use crate::common::blockifier_contracts::{load_cairo0_feature_contract, load_cairo1_feature_contract}; @@ -19,7 +19,7 @@ use crate::common::transaction_utils::execute_txs_and_run_os; struct DeployArgs { contract_address_salt: ContractAddressSalt, class_hash: ClassHash, - constructor_calldata: Vec, + constructor_calldata: Vec, deployer_address: ContractAddress, } @@ -44,7 +44,7 @@ pub async fn initial_state_for_deploy_v1( let deploy_args = DeployArgs { contract_address_salt: ContractAddressSalt::default(), class_hash, - constructor_calldata: vec![stark_felt!(0u128), stark_felt!(101u128)], + constructor_calldata: vec![felt!(0u128), felt!(101u128)], // The deployer address is always be 0 for deploy v1 deployer_address: contract_address!("0x0"), }; @@ -127,7 +127,7 @@ pub async fn initial_state_for_deploy_v3( let deploy_args = DeployArgs { contract_address_salt: ContractAddressSalt::default(), class_hash, - constructor_calldata: vec![stark_felt!(0u128), stark_felt!(101u128)], + constructor_calldata: vec![felt!(0u128), felt!(101u128)], // The deployer address is always be 0 for deploy v1 deployer_address: contract_address!("0x0"), }; diff --git a/tests/integration/deprecated_syscalls_tests.rs b/tests/integration/deprecated_syscalls_tests.rs index 9fc1f36cf..77a750848 100644 --- a/tests/integration/deprecated_syscalls_tests.rs +++ b/tests/integration/deprecated_syscalls_tests.rs @@ -5,6 +5,7 @@ //! Each test in this file calls a single entrypoint and returns to test syscalls individually. use std::collections::HashMap; +use std::str::FromStr; use blockifier::abi::abi_utils::selector_from_name; use blockifier::context::BlockContext; @@ -18,11 +19,9 @@ use blockifier::transaction::transaction_execution::Transaction; use cairo_vm::Felt252; use num_traits::ToPrimitive; use rstest::rstest; -use starknet_api::core::{calculate_contract_address, ChainId}; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; +use starknet_api::core::calculate_contract_address; +use starknet_api::felt; use starknet_api::transaction::{Calldata, ContractAddressSalt, Fee, TransactionHash, TransactionVersion}; -use starknet_os::utils::{felt_api2vm, felt_vm2api}; use starknet_os_types::chain_id::chain_id_to_felt; use crate::common::block_context; @@ -53,7 +52,7 @@ async fn test_syscall_library_call_cairo0( let test_contract_class_hash = test_contract.declaration.class_hash; let selector_felt = selector_from_name("return_result"); - let return_result_calldata = vec![stark_felt!(1u128), stark_felt!(42u128)]; + let return_result_calldata = vec![felt!(1u128), felt!(42u128)]; let entrypoint_args = &[vec![test_contract_class_hash.0], vec![selector_felt.0], return_result_calldata].concat(); @@ -95,7 +94,7 @@ async fn test_syscall_get_block_number_cairo0( let sender_address = initial_state.deployed_cairo0_contracts.get("account_with_dummy_validate").unwrap().address; let contract_address = initial_state.deployed_cairo0_contracts.get("test_contract").unwrap().address; - let expected_block_number = stark_felt!(block_context.block_info().block_number.0); + let expected_block_number = felt!(block_context.block_info().block_number.0); let tx_version = TransactionVersion::ZERO; let mut nonce_manager = NonceManager::default(); @@ -135,7 +134,7 @@ async fn test_syscall_get_block_timestamp_cairo0( let sender_address = initial_state.deployed_cairo0_contracts.get("account_with_dummy_validate").unwrap().address; let contract_address = initial_state.deployed_cairo0_contracts.get("test_contract").unwrap().address; - let expected_block_timestamp = stark_felt!(block_context.block_info().block_timestamp.0); + let expected_block_timestamp = felt!(block_context.block_info().block_timestamp.0); let tx_version = TransactionVersion::ZERO; let mut nonce_manager = NonceManager::default(); @@ -177,7 +176,7 @@ async fn test_syscall_get_tx_info_cairo0( let tx_version = TransactionVersion::ZERO; - let expected_chain_id = felt_vm2api(chain_id_to_felt(&ChainId("SN_GOERLI".to_string()))); + let expected_chain_id = chain_id_to_felt(&block_context.chain_info().chain_id); let mut nonce_manager = NonceManager::default(); let nonce = nonce_manager.next(sender_address); @@ -185,9 +184,8 @@ async fn test_syscall_get_tx_info_cairo0( // Note: we use `test_get_tx_info_no_tx_hash_check()` instead of `test_get_tx_info()` // because it is pretty much impossible to generate a tx whose hash is equal to the expected // hash that must be set in the calldata. - let tx_hash = TransactionHash( - StarkFelt::try_from("0x8704f5e69650b81810a420373c21885aa6e75a8c46e34095e12a2a5231815f").unwrap(), - ); + let tx_hash = + TransactionHash(Felt252::from_str("0x8704f5e69650b81810a420373c21885aa6e75a8c46e34095e12a2a5231815f").unwrap()); let tx = { let mut invoke_tx = invoke_tx(invoke_tx_args! { max_fee, @@ -195,7 +193,7 @@ async fn test_syscall_get_tx_info_cairo0( calldata: create_calldata(contract_address, "test_get_tx_info_no_tx_hash_check", &[ tx_version.0, // expected version *sender_address.key(), // expected contract address - stark_felt!(max_fee.0), // expected max fee + felt!(max_fee.0), // expected max fee expected_chain_id, // expected chain ID nonce.0, // expected nonce ]), @@ -224,19 +222,16 @@ async fn test_syscall_get_tx_info_cairo0( let contract_changes_by_address: HashMap<_, _> = os_output.contracts.iter().map(|change| (change.addr, change)).collect(); let test_contract_changes = contract_changes_by_address - .get(&felt_api2vm(*contract_address.0.key())) + .get(contract_address.0.key()) .expect("The test contract should appear as modified in the OS output"); // Values based on the code of `test_contract.cairo`. // Note that if the nonce is 0 it will not appear as a change, so check for that. let expected_storage_changes = { - let mut changes = HashMap::from([ - (Felt252::from(300), felt_api2vm(tx_hash.0)), - (Felt252::from(311), felt_api2vm(expected_chain_id)), - ]); + let mut changes = HashMap::from([(Felt252::from(300), tx_hash.0), (Felt252::from(311), expected_chain_id)]); - if nonce.0 != StarkFelt::ZERO { - changes.insert(Felt252::from(322), felt_api2vm(nonce.0)); + if nonce.0 != Felt252::ZERO { + changes.insert(Felt252::from(322), nonce.0); } changes }; @@ -344,12 +339,12 @@ async fn test_syscall_deploy_cairo0( let class_hash = test_contract.declaration.class_hash; let contract_address_salt = ContractAddressSalt::default(); - let constructor_args = vec![StarkFelt::from(100u64), StarkFelt::from(200u64)]; + let constructor_args = vec![Felt252::from(100u64), Felt252::from(200u64)]; let test_deploy_args = &[ vec![class_hash.0, contract_address_salt.0], - vec![StarkFelt::from(constructor_args.len() as u64)], + vec![Felt252::from(constructor_args.len() as u64)], constructor_args.clone(), - vec![StarkFelt::ZERO], + vec![Felt252::ZERO], ] .concat(); @@ -385,7 +380,7 @@ async fn test_syscall_deploy_cairo0( // Check that the new contract address appears in the OS output let contract_changes_by_address: HashMap<_, _> = os_output.contracts.iter().map(|change| (change.addr, change)).collect(); - assert!(contract_changes_by_address.contains_key(&felt_api2vm(*expected_contract_address.key()))); + assert!(contract_changes_by_address.contains_key(expected_contract_address.key())); // Check other output fields assert_eq!(os_output.block_number.to_u64().unwrap(), block_context.block_info().block_number.0); @@ -453,15 +448,15 @@ async fn test_syscall_get_contract_address_cairo0( let class_hash = test_contract.declaration.class_hash; let contract_address_salt = ContractAddressSalt::default(); - let constructor_args = vec![StarkFelt::from(100u64), StarkFelt::from(200u64)]; + let constructor_args = vec![Felt252::from(100u64), Felt252::from(200u64)]; // Build the args required for calling test_contract_address. Check the Cairo code for // more details. let test_contract_address_args = &[ vec![contract_address_salt.0, class_hash.0], - vec![StarkFelt::from(constructor_args.len() as u64)], + vec![Felt252::from(constructor_args.len() as u64)], constructor_args.clone(), - vec![StarkFelt::ZERO], // deployer_address + vec![Felt252::ZERO], // deployer_address ] .concat(); @@ -508,12 +503,12 @@ async fn test_syscall_emit_event_cairo0( let contract_address = test_contract.address; let tx_version = TransactionVersion::ZERO; - let keys = vec![stark_felt!(2019_u16), stark_felt!(2020_u16)]; - let data = vec![stark_felt!(2021_u16), stark_felt!(2022_u16), stark_felt!(2023_u16)]; + let keys = vec![felt!(2019_u16), felt!(2020_u16)]; + let data = vec![felt!(2021_u16), felt!(2022_u16), felt!(2023_u16)]; let entrypoint_args = &[ - vec![stark_felt!(u128::try_from(keys.len()).unwrap())], + vec![felt!(u128::try_from(keys.len()).unwrap())], keys, - vec![stark_felt!(u128::try_from(data.len()).unwrap())], + vec![felt!(u128::try_from(data.len()).unwrap())], data, ] .concat(); @@ -561,7 +556,7 @@ async fn test_syscall_send_message_to_l1_cairo0( const PAYLOAD_2: u64 = 34; let tx_version = TransactionVersion::ZERO; - let to_address = stark_felt!(ADDRESS); + let to_address = felt!(ADDRESS); let entrypoint_args = &[vec![to_address]].concat(); @@ -586,12 +581,7 @@ async fn test_syscall_send_message_to_l1_cairo0( .expect("OS run failed"); let output = os_output.messages_to_l1; - let expected: [Felt252; 5] = [ - felt_api2vm(*contract_address.0.key()), - ADDRESS.into(), - PAYLOAD_SIZE.into(), - PAYLOAD_1.into(), - PAYLOAD_2.into(), - ]; + let expected: [Felt252; 5] = + [*contract_address.0.key(), ADDRESS.into(), PAYLOAD_SIZE.into(), PAYLOAD_1.into(), PAYLOAD_2.into()]; assert_eq!(&*output, expected); } diff --git a/tests/integration/l1_handler_txn_tests.rs b/tests/integration/l1_handler_txn_tests.rs index fcf300d04..95352a894 100644 --- a/tests/integration/l1_handler_txn_tests.rs +++ b/tests/integration/l1_handler_txn_tests.rs @@ -7,8 +7,7 @@ use blockifier::transaction::transactions::L1HandlerTransaction; use futures::Future; use rstest::{fixture, rstest}; use starknet_api::core::{ContractAddress, EntryPointSelector}; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; +use starknet_api::felt; use starknet_api::transaction::{Calldata, Fee, TransactionVersion}; use crate::common::state::{init_logging, initial_state_cairo0, initial_state_syscalls, StarknetTestState}; @@ -49,7 +48,7 @@ async fn l1_handler( let tx_version = TransactionVersion::ZERO; - let calldata_args = vec![stark_felt!(1234_u16), stark_felt!(42_u16)]; + let calldata_args = vec![felt!(1234_u16), felt!(42_u16)]; let l1_tx = L1HandlerTransaction { paid_fee_on_l1: max_fee, tx: starknet_api::transaction::L1HandlerTransaction { diff --git a/tests/integration/os.rs b/tests/integration/os.rs index 09fd5cbf7..c88707abd 100644 --- a/tests/integration/os.rs +++ b/tests/integration/os.rs @@ -3,9 +3,9 @@ use blockifier::invoke_tx_args; use blockifier::test_utils::{create_calldata, NonceManager}; use blockifier::transaction::test_utils; use blockifier::transaction::test_utils::max_fee; +use cairo_vm::Felt252; use rstest::rstest; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; +use starknet_api::felt; use starknet_api::transaction::{Fee, TransactionVersion}; use starknet_os::config::STORED_BLOCK_HASH_BUFFER; @@ -35,7 +35,7 @@ async fn return_result_cairo0_account( calldata: create_calldata( contract_address, "return_result", - &[stark_felt!(123_u8)], + &[felt!(123_u8)], ), version: tx_version, nonce: nonce_manager.next(sender_address), @@ -75,7 +75,7 @@ async fn return_result_cairo1_account( calldata: create_calldata( contract_address, "return_result", - &[stark_felt!(2_u8)], + &[felt!(2_u8)], ), version: tx_version, nonce: nonce_manager.next(sender_address), @@ -111,12 +111,12 @@ async fn syscalls_cairo1( let contract_address = initial_state.deployed_cairo1_contracts.get("test_contract").unwrap().address; // test_emit_event - let keys = vec![stark_felt!(2019_u16), stark_felt!(2020_u16)]; - let data = vec![stark_felt!(2021_u16), stark_felt!(2022_u16), stark_felt!(2023_u16)]; + let keys = vec![felt!(2019_u16), felt!(2020_u16)]; + let data = vec![felt!(2021_u16), felt!(2022_u16), felt!(2023_u16)]; let entrypoint_args = &[ - vec![stark_felt!(u128::try_from(keys.len()).unwrap())], + vec![felt!(u128::try_from(keys.len()).unwrap())], keys, - vec![stark_felt!(u128::try_from(data.len()).unwrap())], + vec![felt!(u128::try_from(data.len()).unwrap())], data, ] .concat(); @@ -133,7 +133,7 @@ async fn syscalls_cairo1( let test_storage_read_write_tx = test_utils::account_invoke_tx(invoke_tx_args! { max_fee, sender_address: sender_address, - calldata: create_calldata(contract_address, "test_storage_read_write", &[StarkFelt::TWO, StarkFelt::ONE]), + calldata: create_calldata(contract_address, "test_storage_read_write", &[Felt252::TWO, Felt252::ONE]), version: tx_version, nonce: nonce_manager.next(sender_address), }); @@ -142,15 +142,15 @@ async fn syscalls_cairo1( let test_get_block_hash_tx = test_utils::account_invoke_tx(invoke_tx_args! { max_fee, sender_address: sender_address, - calldata: create_calldata(contract_address, "test_get_block_hash", &[stark_felt!(block_context.block_info().block_number.0 - STORED_BLOCK_HASH_BUFFER)]), + calldata: create_calldata(contract_address, "test_get_block_hash", &[felt!(block_context.block_info().block_number.0 - STORED_BLOCK_HASH_BUFFER)]), version: tx_version, nonce: nonce_manager.next(sender_address), }); // test_send_message_to_l1 - let to_address = stark_felt!(1234_u16); - let payload = vec![stark_felt!(2019_u16), stark_felt!(2020_u16), stark_felt!(2021_u16)]; - let entrypoint_args = &[vec![to_address, stark_felt!(payload.len() as u64)], payload].concat(); + let to_address = felt!(1234_u16); + let payload = vec![felt!(2019_u16), felt!(2020_u16), felt!(2021_u16)]; + let entrypoint_args = &[vec![to_address, felt!(payload.len() as u64)], payload].concat(); let test_send_message_to_l1_tx = test_utils::account_invoke_tx(invoke_tx_args! { max_fee, @@ -165,11 +165,11 @@ async fn syscalls_cairo1( initial_state.deployed_cairo1_contracts.get("test_contract").unwrap().declaration.class_hash.0; let entrypoint_args = &[ test_contract_class_hash, // class hash - stark_felt!(255_u8), // contract_address_salt - stark_felt!(2_u8), // calldata length - stark_felt!(3_u8), // calldata: arg1 - stark_felt!(3_u8), // calldata: arg2 - stark_felt!(0_u8), // deploy_from_zero + felt!(255_u8), // contract_address_salt + felt!(2_u8), // calldata length + felt!(3_u8), // calldata: arg1 + felt!(3_u8), // calldata: arg2 + felt!(0_u8), // deploy_from_zero ]; let test_deploy_tx = test_utils::account_invoke_tx(invoke_tx_args! { diff --git a/tests/integration/run_os.rs b/tests/integration/run_os.rs index 1aa46eebb..265a889fa 100644 --- a/tests/integration/run_os.rs +++ b/tests/integration/run_os.rs @@ -2,7 +2,8 @@ use std::collections::HashMap; use std::sync::Arc; use blockifier::abi::abi_utils::selector_from_name; -use blockifier::block::BlockInfo; +use blockifier::blockifier::block::BlockInfo; +use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; use blockifier::state::cached_state::CachedState; use blockifier::test_utils::declare::declare_tx; @@ -16,10 +17,10 @@ use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transactions::{ExecutableTransaction, L1HandlerTransaction}; use blockifier::versioned_constants::VersionedConstants; use blockifier::{declare_tx_args, deploy_account_tx_args, invoke_tx_args}; +use cairo_vm::Felt252; use rstest::{fixture, rstest}; use starknet_api::core::{calculate_contract_address, ChainId, ContractAddress, EntryPointSelector}; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; +use starknet_api::felt; use starknet_api::transaction::{ Calldata, ContractAddressSalt, Fee, TransactionHash, TransactionSignature, TransactionVersion, }; @@ -29,7 +30,6 @@ use starknet_os::io::output::StarknetOsOutput; use starknet_os::starknet::business_logic::fact_state::state::SharedState; use starknet_os::storage::dict_storage::DictStorage; use starknet_os::storage::storage_utils::unpack_blockifier_state_async; -use starknet_os::utils::felt_api2vm; use crate::common::block_context; use crate::common::blockifier_contracts::load_cairo0_feature_contract; @@ -139,7 +139,7 @@ async fn prepare_extensive_os_test_params( let test_contract = cairo0_contracts.get("test_contract_run_os").unwrap(); for (salt, calldata) in salts.into_iter().zip(calldatas.into_iter()) { - let constructor_calldata: Vec<_> = calldata.iter().map(|&felt| stark_felt!(felt)).collect(); + let constructor_calldata: Vec<_> = calldata.iter().map(|&felt| felt!(felt)).collect(); deployed_txs_addresses.push( add_declare_and_deploy_contract_txs( "test_contract_run_os", @@ -298,7 +298,7 @@ async fn prepare_extensive_os_test_params( ], )); - let calldata_args = vec![stark_felt!(85_u16), stark_felt!(2_u16)]; + let calldata_args = vec![felt!(85_u16), felt!(2_u16)]; let l1_tx = L1HandlerTransaction { paid_fee_on_l1: max_fee(), tx: starknet_api::transaction::L1HandlerTransaction { @@ -331,23 +331,25 @@ async fn prepare_extensive_os_test_params( let inner_invoke_tx = { let tx_args = invoke_tx_args! { sender_address: deploy_account_address, + version: TransactionVersion::ONE, calldata: create_calldata(test_contract1_address, "test_call_contract", &[ delegate_proxy_address.into(), selector_from_name("test_get_tx_info").0, 1u128.into(), - (*deploy_account_address.0), + *deploy_account_address.0, ]), nonce: nonce_manager.next(deploy_account_address), signature: TransactionSignature(vec![100u128.into()]), max_fee: Fee(0x10000000000000000000000000u128), // 2**100 }; let mut tx = invoke_tx(tx_args); - tx.tx_hash = TransactionHash(stark_felt!("0x19c90daecc4e3ed29743b0331024b3014b9f2c4620ee7ec441b4a7ec330583")); + tx.tx_hash = TransactionHash(felt!("0x538ed2ab8c30b384fda9cc92736a2212a0082444cce35135cdff5700885b156")); tx }; - txs.push(Transaction::AccountTransaction(AccountTransaction::Invoke(inner_invoke_tx))); + let tx = Transaction::AccountTransaction(AccountTransaction::Invoke(inner_invoke_tx)); + txs.push(tx); let test_contract2 = cairo0_contracts.get("test_contract2").unwrap(); @@ -410,7 +412,10 @@ async fn prepare_extensive_os_test_params( fn build_block_context(chain_id: ChainId, fee_token_address: ContractAddress) -> BlockContext { let block_info = BlockInfo::create_for_testing(); - let versioned_constants = VersionedConstants::create_for_account_testing(); + let mut versioned_constants = VersionedConstants::create_for_account_testing(); + // Recent versions of Blockifier disable redeclaration of Cairo0 classes. We do that quite + // a bit in the test so the easy way out is to disable this feature. + versioned_constants.disable_cairo0_redeclaration = false; let chain_info = ChainInfo { chain_id, @@ -420,7 +425,9 @@ fn build_block_context(chain_id: ChainId, fee_token_address: ContractAddress) -> }, }; - BlockContext::new_unchecked(&block_info, &chain_info, &versioned_constants) + let bouncer_config = BouncerConfig::max(); + + BlockContext::new(block_info, chain_info, versioned_constants, bouncer_config) } #[allow(clippy::too_many_arguments)] @@ -431,8 +438,8 @@ fn add_declare_and_deploy_contract_txs( deploy_account_address: &ContractAddress, nonce_manager: &mut NonceManager, txs: &mut Vec, - salt: StarkFelt, - constructor_calldata: Vec, + salt: Felt252, + constructor_calldata: Vec, ) -> Result { let contract = cairo0_contracts.get(contract).ok_or("Contract not found")?; @@ -455,7 +462,7 @@ fn add_declare_and_deploy_contract_txs( contract.class_hash.0, // Class hash. salt, // Salt. ]; - ctor_calldata.push(stark_felt!(constructor_calldata.len() as u128)); // Constructor calldata length. + ctor_calldata.push(felt!(constructor_calldata.len() as u128)); // Constructor calldata length. ctor_calldata.extend(constructor_calldata.iter()); let invoke_tx = account_invoke_tx(invoke_tx_args! { sender_address: *deploy_account_address, @@ -516,19 +523,19 @@ fn validate_os_output(os_output: &StarknetOsOutput, tx_contracts: &[ContractAddr let output_messages_to_l1 = &os_output.messages_to_l1; let expected_messages_to_l1 = [ - felt_api2vm(*tx_contracts[0].0.key()), // from address - 85.into(), // to address - 2.into(), // PAYLOAD_SIZE - 12.into(), // PAYLOAD_1 - 34.into(), // PAYLOAD_1 + *tx_contracts[0].0.key(), // from address + 85.into(), // to address + 2.into(), // PAYLOAD_SIZE + 12.into(), // PAYLOAD_1 + 34.into(), // PAYLOAD_1 ]; assert_eq!(output_messages_to_l1, &expected_messages_to_l1); let expected_messages_to_l2 = [ - 85.into(), // from address - felt_api2vm(*tx_contracts[3].0.key()), // the delegate_proxy_address - 0.into(), // Nonce - felt_api2vm(selector_from_name("deposit").0), + 85.into(), // from address + *tx_contracts[3].0.key(), // the delegate_proxy_address + 0.into(), // Nonce + selector_from_name("deposit").0, 1u64.into(), // PAYLOAD_SIZE 2u64.into(), // PAYLOAD_1 ]; @@ -566,7 +573,7 @@ pub async fn initial_state_full_itests( async fn run_os_tests(#[future] initial_state_full_itests: StarknetTestState) { let initial_state = initial_state_full_itests.await; - let chain_id = ChainId("SN_GOERLI".to_string()); + let chain_id = ChainId::Sepolia; let mut nonce_manager = NonceManager::default(); let dummy_token = initial_state.declared_cairo0_contracts.get("token_for_testing").unwrap(); diff --git a/tests/integration/syscalls_tests.rs b/tests/integration/syscalls_tests.rs index 0cbbf54b5..9203e7a5d 100644 --- a/tests/integration/syscalls_tests.rs +++ b/tests/integration/syscalls_tests.rs @@ -6,8 +6,7 @@ use blockifier::transaction::test_utils; use blockifier::transaction::test_utils::max_fee; use blockifier::transaction::transaction_execution::Transaction; use rstest::rstest; -use starknet_api::hash::StarkFelt; -use starknet_api::stark_felt; +use starknet_api::felt; use starknet_api::transaction::{Fee, TransactionVersion}; use crate::common::block_context; @@ -38,7 +37,7 @@ async fn test_syscall_library_call_cairo1( let test_contract_class_hash = test_contract.declaration.class_hash; let selector_felt = selector_from_name("recurse"); - let return_result_calldata = vec![stark_felt!(1u128), stark_felt!(42u128)]; + let return_result_calldata = vec![felt!(1u128), felt!(42u128)]; let entrypoint_args = &[vec![test_contract_class_hash.0], vec![selector_felt.0], return_result_calldata].concat();