diff --git a/Cargo.lock b/Cargo.lock index 751938de7b..b08b41945e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1493,7 +1493,6 @@ dependencies = [ "cairo-lang-runner", "cairo-lang-sierra", "cairo-lang-starknet-classes", - "cairo-lang-utils", "cairo-native", "cairo-vm", "criterion", diff --git a/crates/blockifier_reexecution/src/state_reader.rs b/crates/blockifier_reexecution/src/state_reader.rs index 9cf218d9f1..eadb24337f 100644 --- a/crates/blockifier_reexecution/src/state_reader.rs +++ b/crates/blockifier_reexecution/src/state_reader.rs @@ -2,6 +2,7 @@ pub mod compile; mod errors; #[cfg(test)] pub mod raw_rpc_json_test; +pub mod reexecution_state_reader; #[cfg(test)] #[cfg(feature = "blockifier_regression_https_testing")] pub mod rpc_https_test; diff --git a/crates/blockifier_reexecution/src/state_reader/errors.rs b/crates/blockifier_reexecution/src/state_reader/errors.rs index e2d5a0c1dc..8d15f1de1c 100644 --- a/crates/blockifier_reexecution/src/state_reader/errors.rs +++ b/crates/blockifier_reexecution/src/state_reader/errors.rs @@ -1,3 +1,4 @@ +use blockifier::execution::errors::ContractClassError; use blockifier::state::errors::StateError; use blockifier::transaction::errors::TransactionExecutionError; use blockifier::versioned_constants::VersionedConstantsError; @@ -21,4 +22,6 @@ pub enum ReexecutionError { TransactionExecutionError(#[from] TransactionExecutionError), #[error(transparent)] VersionedConstants(#[from] VersionedConstantsError), + #[error(transparent)] + ContractClassError(#[from] ContractClassError), } diff --git a/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs b/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs new file mode 100644 index 0000000000..7b5adf00f7 --- /dev/null +++ b/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs @@ -0,0 +1,42 @@ +use blockifier::execution::contract_class::ClassInfo; +use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; +use starknet_api::core::ClassHash; +use starknet_api::transaction::{Transaction, TransactionHash}; + +use crate::state_reader::errors::ReexecutionError; +use crate::state_reader::test_state_reader::ReexecutionResult; + +pub(crate) trait ReexecutionStateReader { + fn get_class_info(&self, class_hash: ClassHash) -> ReexecutionResult; + + // TODO(Aner): extend/refactor to accomodate all types of transactions. + fn api_txs_to_blockifier_txs( + &self, + txs_and_hashes: Vec<(Transaction, TransactionHash)>, + ) -> ReexecutionResult> { + txs_and_hashes + .into_iter() + .map(|(tx, tx_hash)| match tx { + Transaction::Invoke(_) | Transaction::DeployAccount(_) => { + BlockifierTransaction::from_api(tx, tx_hash, None, None, None, false) + .map_err(ReexecutionError::from) + } + Transaction::Declare(ref declare_tx) => { + let class_info = self + .get_class_info(declare_tx.class_hash()) + .map_err(ReexecutionError::from)?; + BlockifierTransaction::from_api( + tx, + tx_hash, + Some(class_info), + None, + None, + false, + ) + .map_err(ReexecutionError::from) + } + _ => unimplemented!("unimplemented transaction type: {:?}", tx), + }) + .collect::, _>>() + } +} diff --git a/crates/blockifier_reexecution/src/state_reader/rpc_https_test.rs b/crates/blockifier_reexecution/src/state_reader/rpc_https_test.rs index 51ef7a5129..a94a818bfb 100644 --- a/crates/blockifier_reexecution/src/state_reader/rpc_https_test.rs +++ b/crates/blockifier_reexecution/src/state_reader/rpc_https_test.rs @@ -15,6 +15,7 @@ use starknet_api::transaction::{ use starknet_core::types::ContractClass::{Legacy, Sierra}; use crate::state_reader::compile::legacy_to_contract_class_v0; +use crate::state_reader::reexecution_state_reader::ReexecutionStateReader; use crate::state_reader::test_state_reader::{ConsecutiveTestStateReaders, TestStateReader}; const EXAMPLE_INVOKE_TX_HASH: &str = @@ -180,3 +181,12 @@ pub fn test_get_declare_tx_by_hash( pub fn test_get_statediff_rpc(test_state_reader: TestStateReader) { assert!(test_state_reader.get_state_diff().is_ok()); } + +#[rstest] +#[case(EXAMPLE_DECLARE_V1_BLOCK_NUMBER)] +#[case(EXAMPLE_DECLARE_V2_BLOCK_NUMBER)] +#[case(EXAMPLE_DECLARE_V3_BLOCK_NUMBER)] +pub fn test_get_all_blockifier_tx_in_block(#[case] block_number: u64) { + let state_reader = TestStateReader::new_for_testing(BlockNumber(block_number)); + state_reader.api_txs_to_blockifier_txs(state_reader.get_all_txs_in_block().unwrap()).unwrap(); +} diff --git a/crates/blockifier_reexecution/src/state_reader/test_state_reader.rs b/crates/blockifier_reexecution/src/state_reader/test_state_reader.rs index 6c30e7321d..3e5080d0c4 100644 --- a/crates/blockifier_reexecution/src/state_reader/test_state_reader.rs +++ b/crates/blockifier_reexecution/src/state_reader/test_state_reader.rs @@ -3,25 +3,26 @@ use blockifier::blockifier::config::TransactionExecutorConfig; use blockifier::blockifier::transaction_executor::TransactionExecutor; use blockifier::bouncer::BouncerConfig; use blockifier::context::BlockContext; -use blockifier::execution::contract_class::ContractClass as BlockifierContractClass; +use blockifier::execution::contract_class::{ClassInfo, ContractClass as BlockifierContractClass}; use blockifier::state::cached_state::{CachedState, CommitmentStateDiff}; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader, StateResult}; use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; use blockifier::versioned_constants::VersionedConstants; +use papyrus_execution::DEPRECATED_CONTRACT_SIERRA_SIZE; use serde_json::{json, to_value}; use starknet_api::block::{BlockNumber, StarknetVersion}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_api::transaction::{Transaction, TransactionHash}; use starknet_core::types::ContractClass as StarknetContractClass; -use starknet_core::types::ContractClass::{Legacy, Sierra}; use starknet_gateway::config::RpcStateReaderConfig; use starknet_gateway::errors::serde_err_to_state_err; use starknet_gateway::rpc_objects::{BlockHeader, GetBlockWithTxHashesParams, ResourcePrice}; use starknet_gateway::rpc_state_reader::RpcStateReader; use starknet_types_core::felt::Felt; +use super::reexecution_state_reader::ReexecutionStateReader; use crate::state_reader::compile::{legacy_to_contract_class_v0, sierra_to_contact_class_v1}; use crate::state_reader::errors::ReexecutionError; use crate::state_reader::serde_utils::{ @@ -31,7 +32,6 @@ use crate::state_reader::serde_utils::{ }; use crate::state_reader::utils::{ disjoint_hashmap_union, - from_api_txs_to_blockifier_txs, get_chain_info, get_rpc_state_reader_config, }; @@ -64,8 +64,8 @@ impl StateReader for TestStateReader { class_hash: ClassHash, ) -> StateResult { match self.get_contract_class(&class_hash)? { - Sierra(sierra) => sierra_to_contact_class_v1(sierra), - Legacy(legacy) => legacy_to_contract_class_v0(legacy), + StarknetContractClass::Sierra(sierra) => sierra_to_contact_class_v1(sierra), + StarknetContractClass::Legacy(legacy) => legacy_to_contract_class_v0(legacy), } } @@ -231,6 +231,27 @@ impl TestStateReader { } } +impl ReexecutionStateReader for TestStateReader { + fn get_class_info(&self, class_hash: ClassHash) -> ReexecutionResult { + match self.get_contract_class(&class_hash)? { + StarknetContractClass::Sierra(sierra) => { + let abi_length = sierra.abi.len(); + let sierra_length = sierra.sierra_program.len(); + Ok(ClassInfo::new(&sierra_to_contact_class_v1(sierra)?, sierra_length, abi_length)?) + } + StarknetContractClass::Legacy(legacy) => { + let abi_length = + legacy.abi.clone().expect("legendary contract should have abi").len(); + Ok(ClassInfo::new( + &legacy_to_contract_class_v0(legacy)?, + DEPRECATED_CONTRACT_SIERRA_SIZE, + abi_length, + )?) + } + } + } +} + /// Trait of the functions \ queries required for reexecution. pub trait ConsecutiveStateReaders { fn get_transaction_executor( @@ -276,7 +297,8 @@ impl ConsecutiveStateReaders for ConsecutiveTestStateReaders { } fn get_next_block_txs(&self) -> ReexecutionResult> { - from_api_txs_to_blockifier_txs(self.next_block_state_reader.get_all_txs_in_block()?) + self.next_block_state_reader + .api_txs_to_blockifier_txs(self.next_block_state_reader.get_all_txs_in_block()?) } fn get_next_block_state_diff(&self) -> ReexecutionResult { diff --git a/crates/blockifier_reexecution/src/state_reader/utils.rs b/crates/blockifier_reexecution/src/state_reader/utils.rs index 86270885c1..b252bba0a8 100644 --- a/crates/blockifier_reexecution/src/state_reader/utils.rs +++ b/crates/blockifier_reexecution/src/state_reader/utils.rs @@ -1,13 +1,9 @@ use blockifier::context::{ChainInfo, FeeTokenAddresses}; -use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; use indexmap::IndexMap; use papyrus_execution::{eth_fee_contract_address, strk_fee_contract_address}; use starknet_api::core::ChainId; -use starknet_api::transaction::{Transaction, TransactionHash}; use starknet_gateway::config::RpcStateReaderConfig; -use crate::state_reader::test_state_reader::ReexecutionResult; - pub const RPC_NODE_URL: &str = "https://free-rpc.nethermind.io/mainnet-juno/"; pub const JSON_RPC_VERSION: &str = "2.0"; @@ -32,21 +28,6 @@ pub fn get_chain_info() -> ChainInfo { ChainInfo { chain_id: ChainId::Mainnet, fee_token_addresses: get_fee_token_addresses() } } -// TODO(Aner): extend/refactor to accomodate all types of transactions. -#[allow(dead_code)] -pub(crate) fn from_api_txs_to_blockifier_txs( - txs_and_hashes: Vec<(Transaction, TransactionHash)>, -) -> ReexecutionResult> { - Ok(txs_and_hashes - .into_iter() - .map(|(tx, tx_hash)| match tx { - Transaction::Invoke(_) => { - BlockifierTransaction::from_api(tx, tx_hash, None, None, None, false) - } - _ => unimplemented!(), - }) - .collect::>()?) -} // TODO(Aner): import the following functions instead, to reduce code duplication. pub(crate) fn disjoint_hashmap_union( map1: IndexMap, diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index 60305adc9f..7314e50205 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -419,7 +419,8 @@ pub type AbiSize = usize; /// The size of the sierra program. pub type SierraSize = usize; -const DEPRECATED_CONTRACT_SIERRA_SIZE: SierraSize = 0; +/// The size of the sierra program for deprecated contracts. +pub const DEPRECATED_CONTRACT_SIERRA_SIZE: SierraSize = 0; /// The transaction input to be executed. // TODO(yair): This should use broadcasted transactions instead of regular transactions, but the