Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

refactor(execution, native_blockifier): move TransactionExecutor to b… #1497

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/blockifier/src/blockifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod transaction_executor;
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>;
pub type TransactionExecutorResult<T> = Result<T, TransactionExecutorError>;

// TODO(Gilad): make this hold TransactionContext instead of BlockContext.
pub struct TransactionExecutor<S: StateReader> {
Expand All @@ -44,7 +54,7 @@ pub struct TransactionExecutor<S: StateReader> {
}

impl<S: StateReader> TransactionExecutor<S> {
pub fn new(state: CachedState<S>, block_context: BlockContext) -> NativeBlockifierResult<Self> {
pub fn new(state: CachedState<S>, block_context: BlockContext) -> Self {
log::debug!("Initializing Transaction Executor...");
let tx_executor = Self {
block_context,
Expand All @@ -58,7 +68,7 @@ impl<S: StateReader> TransactionExecutor<S> {
};
log::debug!("Initialized Transaction Executor.");

Ok(tx_executor)
tx_executor
}

/// Executes the given transaction on the state maintained by the executor.
Expand All @@ -68,7 +78,7 @@ impl<S: StateReader> TransactionExecutor<S> {
&mut self,
tx: Transaction,
charge_fee: bool,
) -> NativeBlockifierResult<(TransactionExecutionInfo, BouncerInfo)> {
) -> TransactionExecutorResult<(TransactionExecutionInfo, BouncerInfo)> {
let l1_handler_payload_size: Option<usize> =
if let Transaction::L1HandlerTransaction(l1_handler_tx) = &tx {
Some(l1_handler_tx.payload_size())
Expand All @@ -80,9 +90,8 @@ impl<S: StateReader> TransactionExecutor<S> {
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
Expand Down Expand Up @@ -143,7 +152,7 @@ impl<S: StateReader> TransactionExecutor<S> {
}
Err(error) => {
transactional_state.abort();
Err(error)
Err(TransactionExecutorError::TransactionExecutionError(error))
}
}
}
Expand All @@ -152,7 +161,7 @@ impl<S: StateReader> TransactionExecutor<S> {
&mut self,
account_tx: &AccountTransaction,
mut remaining_gas: u64,
) -> NativeBlockifierResult<(Option<CallInfo>, ActualCost)> {
) -> TransactionExecutorResult<(Option<CallInfo>, 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;
Expand Down Expand Up @@ -245,7 +254,7 @@ pub fn get_casm_hash_calculation_resources<S: StateReader>(
state: &mut TransactionalState<'_, S>,
block_executed_class_hashes: &HashSet<ClassHash>,
tx_executed_class_hashes: &HashSet<ClassHash>,
) -> NativeBlockifierResult<ExecutionResources> {
) -> TransactionExecutorResult<ExecutionResources> {
let newly_executed_class_hashes: HashSet<&ClassHash> =
tx_executed_class_hashes.difference(block_executed_class_hashes).collect();

Expand All @@ -267,7 +276,7 @@ pub fn get_casm_hash_calculation_resources<S: StateReader>(
pub fn get_particia_update_resources(
block_visited_storage_entries: &HashSet<StorageEntry>,
tx_visited_storage_entries: &HashSet<StorageEntry>,
) -> NativeBlockifierResult<ExecutionResources> {
) -> TransactionExecutorResult<ExecutionResources> {
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();
Expand Down
1 change: 1 addition & 0 deletions crates/blockifier/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod abi;
pub mod block;
pub mod blockifier;
pub mod context;
pub mod execution;
pub mod fee;
Expand Down
2 changes: 2 additions & 0 deletions crates/native_blockifier/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use blockifier::blockifier::transaction_executor::TransactionExecutorError;
use blockifier::state::errors::StateError;
use blockifier::transaction::errors::{
ParseError, TransactionExecutionError, TransactionPreValidationError,
Expand Down Expand Up @@ -67,6 +68,7 @@ native_blockifier_errors!(
(StateError, StateError, PyStateError),
(StorageError, papyrus_storage::StorageError, PyStorageError),
(TransactionExecutionError, TransactionExecutionError, PyTransactionExecutionError),
(TransactionExecutorError, TransactionExecutorError, PyTransactionExecutorError),
(TransactionPreValidationError, TransactionPreValidationError, PyTransactionPreValidationError)
);

Expand Down
1 change: 0 additions & 1 deletion crates/native_blockifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions crates/native_blockifier/src/py_block_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<u8>;

#[cfg(test)]
#[path = "py_block_executor_test.rs"]
Expand Down Expand Up @@ -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(())
Expand Down
6 changes: 3 additions & 3 deletions crates/native_blockifier/src/py_validator.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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]
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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 })
}
Expand Down
Loading