Skip to content
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
30 changes: 19 additions & 11 deletions crates/blockifier/src/blockifier/transaction_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::blockifier::config::TransactionExecutorConfig;
use crate::bouncer::{Bouncer, BouncerWeights};
use crate::concurrency::worker_logic::WorkerExecutor;
use crate::context::BlockContext;
use crate::state::cached_state::{CachedState, CommitmentStateDiff, TransactionalState};
use crate::state::cached_state::{CachedState, CommitmentStateDiff, StateMaps, TransactionalState};
use crate::state::errors::StateError;
use crate::state::state_api::{StateReader, StateResult};
use crate::state::stateful_compression::{allocate_aliases_in_storage, compress, CompressionError};
Expand All @@ -27,6 +27,8 @@ pub mod transaction_executor_test;
pub const BLOCK_STATE_ACCESS_ERR: &str = "Error: The block state should be `Some`.";
pub const DEFAULT_STACK_SIZE: usize = 60 * 1024 * 1024;

pub type TransactionExecutionOutput = (TransactionExecutionInfo, StateMaps);

#[derive(Debug, Error)]
pub enum TransactionExecutorError {
#[error("Transaction cannot be added to the current block, block capacity reached.")]
Expand Down Expand Up @@ -103,7 +105,7 @@ impl<S: StateReader> TransactionExecutor<S> {
pub fn execute(
&mut self,
tx: &Transaction,
) -> TransactionExecutorResult<TransactionExecutionInfo> {
) -> TransactionExecutorResult<TransactionExecutionOutput> {
let mut transactional_state = TransactionalState::create_transactional(
self.block_state.as_mut().expect(BLOCK_STATE_ACCESS_ERR),
);
Expand All @@ -114,16 +116,17 @@ impl<S: StateReader> TransactionExecutor<S> {
tx.execute_raw(&mut transactional_state, &self.block_context, concurrency_mode);
match tx_execution_result {
Ok(tx_execution_info) => {
let tx_state_changes_keys =
transactional_state.get_actual_state_changes()?.state_maps.into_keys();
let state_diff = transactional_state.to_state_diff()?.state_maps;
let tx_state_changes_keys = state_diff.keys();
self.bouncer.try_update(
&transactional_state,
&tx_state_changes_keys,
&tx_execution_info.summarize(&self.block_context.versioned_constants),
&tx_execution_info.receipt.resources,
)?;
transactional_state.commit();
Ok(tx_execution_info)

Ok((tx_execution_info, state_diff))
}
Err(error) => {
transactional_state.abort();
Expand All @@ -132,14 +135,16 @@ impl<S: StateReader> TransactionExecutor<S> {
}
}

pub fn execute_txs_sequentially_inner(
fn execute_txs_sequentially_inner(
&mut self,
txs: &[Transaction],
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
) -> Vec<TransactionExecutorResult<TransactionExecutionOutput>> {
let mut results = Vec::new();
for tx in txs {
match self.execute(tx) {
Ok(tx_execution_info) => results.push(Ok(tx_execution_info)),
Ok((tx_execution_info, state_diff)) => {
results.push(Ok((tx_execution_info, state_diff)))
}
Err(TransactionExecutorError::BlockFull) => break,
Err(error) => results.push(Err(error)),
}
Expand Down Expand Up @@ -196,6 +201,9 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
if !self.config.concurrency_config.enabled {
log::debug!("Executing transactions sequentially.");
self.execute_txs_sequentially(txs)
.into_iter()
.map(|res| res.map(|(tx_execution_info, _state_diff)| tx_execution_info))
.collect()
} else {
log::debug!("Executing transactions concurrently.");
let chunk_size = self.config.concurrency_config.chunk_size;
Expand Down Expand Up @@ -228,10 +236,10 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
}
}

pub fn execute_txs_sequentially(
fn execute_txs_sequentially(
&mut self,
txs: &[Transaction],
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
) -> Vec<TransactionExecutorResult<TransactionExecutionOutput>> {
#[cfg(not(feature = "cairo_native"))]
return self.execute_txs_sequentially_inner(txs);
#[cfg(feature = "cairo_native")]
Expand Down Expand Up @@ -261,7 +269,7 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
}
}

pub fn execute_chunk(
fn execute_chunk(
&mut self,
chunk: &[Transaction],
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn tx_executor_test_body<S: StateReader>(
// TODO(Arni, 30/03/2024): Consider adding a test for the transaction execution info. If A test
// should not be added, rename the test to `test_bouncer_info`.
// TODO(Arni, 30/03/2024): Test all bouncer weights.
let _tx_execution_info = tx_executor.execute(&tx).unwrap();
let _tx_execution_output = tx_executor.execute(&tx).unwrap();
let bouncer_weights = tx_executor.bouncer.get_accumulated_weights();
assert_eq!(bouncer_weights.state_diff_size, expected_bouncer_weights.state_diff_size);
assert_eq!(
Expand Down
10 changes: 10 additions & 0 deletions crates/blockifier/src/state/cached_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,16 @@ impl StateMaps {
compiled_class_hash_keys: self.compiled_class_hashes.into_keys().collect(),
}
}

pub fn keys(&self) -> StateChangesKeys {
StateChangesKeys {
modified_contracts: self.get_contract_addresses(),
nonce_keys: self.nonces.keys().cloned().collect(),
class_hash_keys: self.class_hashes.keys().cloned().collect(),
storage_keys: self.storage.keys().cloned().collect(),
compiled_class_hash_keys: self.compiled_class_hashes.keys().cloned().collect(),
}
}
}
/// Caches read and write requests.
/// The tracked changes are needed for block state commitment.
Expand Down
2 changes: 1 addition & 1 deletion crates/native_blockifier/src/py_block_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl PyBlockExecutor {
optional_py_class_info: Option<PyClassInfo>,
) -> NativeBlockifierResult<Py<PyBytes>> {
let tx: Transaction = py_tx(tx, optional_py_class_info).expect(PY_TX_PARSING_ERR);
let tx_execution_info = self.tx_executor().execute(&tx)?;
let (tx_execution_info, _state_diff) = self.tx_executor().execute(&tx)?;
let thin_tx_execution_info =
ThinTransactionExecutionInfo::from_tx_execution_info(tx_execution_info);

Expand Down
Loading