From 59436ca705b89fc978b6f858f11a731655957245 Mon Sep 17 00:00:00 2001 From: Barak Date: Tue, 13 Feb 2024 11:44:49 +0200 Subject: [PATCH] refactor(execution, native_blockifier): move TransactionExecutor to blockifier --- crates/blockifier/src/blockifier.rs | 1 + .../src/blockifier}/transaction_executor.rs | 63 +++++++++++-------- crates/blockifier/src/lib.rs | 1 + crates/native_blockifier/src/errors.rs | 2 + crates/native_blockifier/src/lib.rs | 1 - .../src/py_block_executor.rs | 6 +- crates/native_blockifier/src/py_validator.rs | 6 +- 7 files changed, 47 insertions(+), 33 deletions(-) create mode 100644 crates/blockifier/src/blockifier.rs rename crates/{native_blockifier/src => blockifier/src/blockifier}/transaction_executor.rs (88%) diff --git a/crates/blockifier/src/blockifier.rs b/crates/blockifier/src/blockifier.rs new file mode 100644 index 0000000000..10ead4735d --- /dev/null +++ b/crates/blockifier/src/blockifier.rs @@ -0,0 +1 @@ +pub mod transaction_executor; diff --git a/crates/native_blockifier/src/transaction_executor.rs b/crates/blockifier/src/blockifier/transaction_executor.rs similarity index 88% rename from crates/native_blockifier/src/transaction_executor.rs rename to crates/blockifier/src/blockifier/transaction_executor.rs index c1f0545fc1..3e247f97da 100644 --- a/crates/native_blockifier/src/transaction_executor.rs +++ b/crates/blockifier/src/blockifier/transaction_executor.rs @@ -2,27 +2,37 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::vec::IntoIter; -use blockifier::context::BlockContext; -use blockifier::execution::bouncer::BouncerInfo; -use blockifier::execution::call_info::{CallInfo, MessageL1CostInfo}; -use blockifier::fee::actual_cost::ActualCost; -use blockifier::fee::gas_usage::get_onchain_data_segment_length; -use blockifier::state::cached_state::{ - CachedState, CommitmentStateDiff, StagedTransactionalState, StateChangesKeys, StorageEntry, - TransactionalState, -}; -use blockifier::state::state_api::{State, StateReader}; -use blockifier::transaction::account_transaction::AccountTransaction; -use blockifier::transaction::objects::TransactionExecutionInfo; -use blockifier::transaction::transaction_execution::Transaction; -use blockifier::transaction::transactions::{ExecutableTransaction, ValidatableTransaction}; use cairo_vm::vm::runners::builtin_runner::HASH_BUILTIN_NAME; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::core::ClassHash; +use thiserror::Error; + +use crate::context::BlockContext; +use crate::execution::bouncer::BouncerInfo; +use crate::execution::call_info::{CallInfo, MessageL1CostInfo}; +use crate::fee::actual_cost::ActualCost; +use crate::fee::gas_usage::get_onchain_data_segment_length; +use crate::state::cached_state::{ + CachedState, CommitmentStateDiff, StagedTransactionalState, StateChangesKeys, StorageEntry, + TransactionalState, +}; +use crate::state::errors::StateError; +use crate::state::state_api::{State, StateReader}; +use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::errors::TransactionExecutionError; +use crate::transaction::objects::TransactionExecutionInfo; +use crate::transaction::transaction_execution::Transaction; +use crate::transaction::transactions::{ExecutableTransaction, ValidatableTransaction}; + +#[derive(Debug, Error)] +pub enum TransactionExecutorError { + #[error(transparent)] + StateError(#[from] StateError), + #[error(transparent)] + TransactionExecutionError(#[from] TransactionExecutionError), +} -use crate::errors::{NativeBlockifierError, NativeBlockifierResult}; - -pub(crate) type RawTransactionExecutionInfo = Vec; +pub type TransactionExecutorResult = Result; // TODO(Gilad): make this hold TransactionContext instead of BlockContext. pub struct TransactionExecutor { @@ -44,7 +54,7 @@ pub struct TransactionExecutor { } impl TransactionExecutor { - pub fn new(state: CachedState, block_context: BlockContext) -> NativeBlockifierResult { + pub fn new(state: CachedState, block_context: BlockContext) -> Self { log::debug!("Initializing Transaction Executor..."); let tx_executor = Self { block_context, @@ -58,7 +68,7 @@ impl TransactionExecutor { }; log::debug!("Initialized Transaction Executor."); - Ok(tx_executor) + tx_executor } /// Executes the given transaction on the state maintained by the executor. @@ -68,7 +78,7 @@ impl TransactionExecutor { &mut self, tx: Transaction, charge_fee: bool, - ) -> NativeBlockifierResult<(TransactionExecutionInfo, BouncerInfo)> { + ) -> TransactionExecutorResult<(TransactionExecutionInfo, BouncerInfo)> { let l1_handler_payload_size: Option = if let Transaction::L1HandlerTransaction(l1_handler_tx) = &tx { Some(l1_handler_tx.payload_size()) @@ -80,9 +90,8 @@ impl TransactionExecutor { let mut transactional_state = CachedState::create_transactional(&mut self.state); let validate = true; - let tx_execution_result = tx - .execute_raw(&mut transactional_state, &self.block_context, charge_fee, validate) - .map_err(NativeBlockifierError::from); + let tx_execution_result = + tx.execute_raw(&mut transactional_state, &self.block_context, charge_fee, validate); match tx_execution_result { Ok(tx_execution_info) => { // Prepare bouncer info; the countings here should be linear in the transactional @@ -143,7 +152,7 @@ impl TransactionExecutor { } Err(error) => { transactional_state.abort(); - Err(error) + Err(TransactionExecutorError::TransactionExecutionError(error)) } } } @@ -152,7 +161,7 @@ impl TransactionExecutor { &mut self, account_tx: &AccountTransaction, mut remaining_gas: u64, - ) -> NativeBlockifierResult<(Option, ActualCost)> { + ) -> TransactionExecutorResult<(Option, ActualCost)> { let mut execution_resources = ExecutionResources::default(); let tx_context = Arc::new(self.block_context.to_tx_context(account_tx)); let tx_info = &tx_context.tx_info; @@ -245,7 +254,7 @@ pub fn get_casm_hash_calculation_resources( state: &mut TransactionalState<'_, S>, block_executed_class_hashes: &HashSet, tx_executed_class_hashes: &HashSet, -) -> NativeBlockifierResult { +) -> TransactionExecutorResult { let newly_executed_class_hashes: HashSet<&ClassHash> = tx_executed_class_hashes.difference(block_executed_class_hashes).collect(); @@ -267,7 +276,7 @@ pub fn get_casm_hash_calculation_resources( pub fn get_particia_update_resources( block_visited_storage_entries: &HashSet, tx_visited_storage_entries: &HashSet, -) -> NativeBlockifierResult { +) -> TransactionExecutorResult { let newly_visited_storage_entries: HashSet<&StorageEntry> = tx_visited_storage_entries.difference(block_visited_storage_entries).collect(); let n_newly_visited_leaves = newly_visited_storage_entries.len(); diff --git a/crates/blockifier/src/lib.rs b/crates/blockifier/src/lib.rs index 88d0b5752b..b6b2e390dd 100644 --- a/crates/blockifier/src/lib.rs +++ b/crates/blockifier/src/lib.rs @@ -1,5 +1,6 @@ pub mod abi; pub mod block; +pub mod blockifier; pub mod context; pub mod execution; pub mod fee; diff --git a/crates/native_blockifier/src/errors.rs b/crates/native_blockifier/src/errors.rs index 79383d478f..90ac0746f3 100644 --- a/crates/native_blockifier/src/errors.rs +++ b/crates/native_blockifier/src/errors.rs @@ -1,3 +1,4 @@ +use blockifier::blockifier::transaction_executor::TransactionExecutorError; use blockifier::state::errors::StateError; use blockifier::transaction::errors::{ ParseError, TransactionExecutionError, TransactionPreValidationError, @@ -67,6 +68,7 @@ native_blockifier_errors!( (StateError, StateError, PyStateError), (StorageError, papyrus_storage::StorageError, PyStorageError), (TransactionExecutionError, TransactionExecutionError, PyTransactionExecutionError), + (TransactionExecutorError, TransactionExecutorError, PyTransactionExecutorError), (TransactionPreValidationError, TransactionPreValidationError, PyTransactionPreValidationError) ); diff --git a/crates/native_blockifier/src/lib.rs b/crates/native_blockifier/src/lib.rs index 9d7fe1917e..7e37682d3c 100644 --- a/crates/native_blockifier/src/lib.rs +++ b/crates/native_blockifier/src/lib.rs @@ -16,7 +16,6 @@ pub mod py_validator; pub mod state_readers; pub mod storage; pub mod test_utils; -pub mod transaction_executor; use errors::{add_py_exceptions, UndeclaredClassHashError}; use py_block_executor::PyBlockExecutor; diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index 232b1343bb..662d1bad8d 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use blockifier::block::{ pre_process_block as pre_process_block_blockifier, BlockInfo, BlockNumberHashPair, GasPrices, }; +use blockifier::blockifier::transaction_executor::TransactionExecutor; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; use blockifier::state::cached_state::{CachedState, GlobalContractCache}; use blockifier::state::state_api::State; @@ -26,7 +27,8 @@ use crate::py_transaction_execution_info::PyBouncerInfo; use crate::py_utils::{int_to_chain_id, py_attr, versioned_constants_with_overrides, PyFelt}; use crate::state_readers::papyrus_state::PapyrusReader; use crate::storage::{PapyrusStorage, Storage, StorageConfig}; -use crate::transaction_executor::{RawTransactionExecutionInfo, TransactionExecutor}; + +pub(crate) type RawTransactionExecutionInfo = Vec; #[cfg(test)] #[path = "py_block_executor_test.rs"] @@ -100,7 +102,7 @@ impl PyBlockExecutor { &self.versioned_constants, )?; - let tx_executor = TransactionExecutor::new(state, block_context)?; + let tx_executor = TransactionExecutor::new(state, block_context); self.tx_executor = Some(tx_executor); Ok(()) diff --git a/crates/native_blockifier/src/py_validator.rs b/crates/native_blockifier/src/py_validator.rs index 0eb171cf2a..4954a6393d 100644 --- a/crates/native_blockifier/src/py_validator.rs +++ b/crates/native_blockifier/src/py_validator.rs @@ -1,3 +1,4 @@ +use blockifier::blockifier::transaction_executor::TransactionExecutor; use blockifier::context::{BlockContext, TransactionContext}; use blockifier::execution::call_info::CallInfo; use blockifier::fee::actual_cost::ActualCost; @@ -20,7 +21,6 @@ use crate::py_transaction::{py_account_tx, py_tx, PyClassInfo}; use crate::py_transaction_execution_info::PyBouncerInfo; use crate::py_utils::{versioned_constants_with_overrides, PyFelt}; use crate::state_readers::py_state_reader::PyStateReader; -use crate::transaction_executor::TransactionExecutor; /// Manages transaction validation for pre-execution flows. #[pyclass] @@ -52,7 +52,7 @@ impl PyValidator { // TODO(Yael 24/01/24): calc block_context using pre_process_block let block_context = BlockContext::new_unchecked(&block_info, &chain_info, &versioned_constants); - let tx_executor = TransactionExecutor::new(state, block_context)?; + let tx_executor = TransactionExecutor::new(state, block_context); let validator = Self { max_nonce_for_validation_skip: Nonce(max_nonce_for_validation_skip.0), @@ -131,7 +131,7 @@ impl PyValidator { VersionedConstants::latest_constants(), ); // TODO(Yael 24/01/24): calc block_context using pre_process_block - let tx_executor = TransactionExecutor::new(state, block_context)?; + let tx_executor = TransactionExecutor::new(state, block_context); Ok(Self { max_nonce_for_validation_skip: Nonce(StarkFelt::ONE), tx_executor }) }