diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index fb655df210..7b0300d12e 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -9,8 +9,11 @@ use blockifier::state::cached_state::{ CachedState, GlobalContractCache, GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST, }; use blockifier::state::state_api::State; +use blockifier::transaction::objects::TransactionExecutionInfo; +use blockifier::transaction::transaction_execution::Transaction; use blockifier::versioned_constants::VersionedConstants; use pyo3::prelude::*; +use serde::Serialize; use starknet_api::block::{BlockNumber, BlockTimestamp}; use starknet_api::core::{ChainId, ContractAddress}; use starknet_api::hash::StarkFelt; @@ -20,6 +23,7 @@ use crate::errors::{ NativeBlockifierResult, }; use crate::py_state_diff::{PyBlockInfo, PyStateDiff}; +use crate::py_transaction::py_tx; 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; @@ -30,6 +34,14 @@ use crate::transaction_executor::{RawTransactionExecutionInfo, TransactionExecut #[path = "py_block_executor_test.rs"] mod py_block_executor_test; +#[pyclass] +#[derive(Debug, Serialize)] +pub(crate) struct TypedTransactionExecutionInfo { + #[serde(flatten)] + pub info: TransactionExecutionInfo, + pub tx_type: String, +} + #[pyclass] pub struct PyBlockExecutor { pub general_config: PyGeneralConfig, @@ -104,7 +116,14 @@ impl PyBlockExecutor { raw_contract_class: Option<&str>, ) -> NativeBlockifierResult<(RawTransactionExecutionInfo, PyBouncerInfo)> { let charge_fee = true; - self.tx_executor().execute(tx, raw_contract_class, charge_fee) + let tx_type: &str = tx.getattr("tx_type")?.getattr("name")?.extract()?; + let tx: Transaction = py_tx(tx, raw_contract_class)?; + let (tx_execution_info, py_bouncer_info) = self.tx_executor().execute(tx, charge_fee)?; + let typed_tx_execution_info = + TypedTransactionExecutionInfo { info: tx_execution_info, tx_type: tx_type.to_string() }; + let raw_tx_execution_info = serde_json::to_vec(&typed_tx_execution_info)?; + + Ok((raw_tx_execution_info, py_bouncer_info)) } /// Returns the state diff and a list of contract class hash with the corresponding list of diff --git a/crates/native_blockifier/src/py_validator.rs b/crates/native_blockifier/src/py_validator.rs index 5a8b7155ab..fb09fe8911 100644 --- a/crates/native_blockifier/src/py_validator.rs +++ b/crates/native_blockifier/src/py_validator.rs @@ -7,7 +7,10 @@ use blockifier::state::cached_state::{ }; use blockifier::state::state_api::StateReader; use blockifier::transaction::account_transaction::AccountTransaction; -use blockifier::transaction::objects::{TransactionExecutionResult, TransactionInfo}; +use blockifier::transaction::objects::{ + TransactionExecutionInfo, TransactionExecutionResult, TransactionInfo, +}; +use blockifier::transaction::transaction_execution::Transaction; use blockifier::versioned_constants::VersionedConstants; use pyo3::prelude::*; use starknet_api::core::Nonce; @@ -16,11 +19,11 @@ use starknet_api::hash::StarkFelt; use crate::errors::NativeBlockifierResult; use crate::py_block_executor::{into_block_context_args, PyGeneralConfig}; use crate::py_state_diff::PyBlockInfo; -use crate::py_transaction::py_account_tx; +use crate::py_transaction::{py_account_tx, py_tx}; 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::{RawTransactionExecutionInfo, TransactionExecutor}; +use crate::transaction_executor::TransactionExecutor; /// Manages transaction validation for pre-execution flows. #[pyclass] @@ -77,8 +80,7 @@ impl PyValidator { // before `__validate_deploy__`. The execution already includes all necessary validations, // so they are skipped here. if let AccountTransaction::DeployAccount(_deploy_account_tx) = account_tx { - let (_raw_tx_execution_info, _py_bouncer_info) = - self.execute(tx, raw_contract_class)?; + let (_tx_execution_info, _py_bouncer_info) = self.execute(tx, raw_contract_class)?; // TODO(Ayelet, 09/11/2023): Check call succeeded. return Ok(()); @@ -132,20 +134,21 @@ impl PyValidator { Ok(Self { max_nonce_for_validation_skip: Nonce(StarkFelt::ONE), tx_executor }) } +} +impl PyValidator { /// Applicable solely to account deployment transactions: the execution of the constructor /// is required before they can be validated. fn execute( &mut self, tx: &PyAny, raw_contract_class: Option<&str>, - ) -> NativeBlockifierResult<(RawTransactionExecutionInfo, PyBouncerInfo)> { + ) -> NativeBlockifierResult<(TransactionExecutionInfo, PyBouncerInfo)> { let limit_execution_steps_by_resource_bounds = true; - self.tx_executor.execute(tx, raw_contract_class, limit_execution_steps_by_resource_bounds) + let tx: Transaction = py_tx(tx, raw_contract_class)?; + self.tx_executor.execute(tx, limit_execution_steps_by_resource_bounds) } -} -impl PyValidator { fn perform_pre_validation_stage( &mut self, account_tx: &AccountTransaction, diff --git a/crates/native_blockifier/src/transaction_executor.rs b/crates/native_blockifier/src/transaction_executor.rs index c01eb7837a..c98ff3e833 100644 --- a/crates/native_blockifier/src/transaction_executor.rs +++ b/crates/native_blockifier/src/transaction_executor.rs @@ -16,26 +16,15 @@ 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 as VmExecutionResources; -use pyo3::prelude::*; -use serde::Serialize; use starknet_api::core::ClassHash; use crate::errors::{NativeBlockifierError, NativeBlockifierResult}; use crate::py_state_diff::PyStateDiff; -use crate::py_transaction::py_tx; use crate::py_transaction_execution_info::PyBouncerInfo; use crate::py_utils::PyFelt; pub(crate) type RawTransactionExecutionInfo = Vec; -#[pyclass] -#[derive(Debug, Serialize)] -pub(crate) struct TypedTransactionExecutionInfo { - #[serde(flatten)] - info: TransactionExecutionInfo, - tx_type: String, -} - // TODO(Gilad): make this hold TransactionContext instead of BlockContext. pub struct TransactionExecutor { pub block_context: BlockContext, @@ -73,12 +62,9 @@ impl TransactionExecutor { /// (used for counting purposes). pub fn execute( &mut self, - tx: &PyAny, - raw_contract_class: Option<&str>, + tx: Transaction, charge_fee: bool, - ) -> NativeBlockifierResult<(RawTransactionExecutionInfo, PyBouncerInfo)> { - let tx_type: &str = tx.getattr("tx_type")?.getattr("name")?.extract()?; - let tx: Transaction = py_tx(tx, raw_contract_class)?; + ) -> NativeBlockifierResult<(TransactionExecutionInfo, PyBouncerInfo)> { let l1_handler_payload_size: usize = if let Transaction::L1HandlerTransaction(l1_handler_tx) = &tx { l1_handler_tx.payload_size() @@ -125,11 +111,7 @@ impl TransactionExecutor { let state_diff_size = 0; // Finalize counting logic. - let typed_tx_execution_info = TypedTransactionExecutionInfo { - info: tx_execution_info, - tx_type: tx_type.to_string(), - }; - let actual_resources = &typed_tx_execution_info.info.actual_resources; + let actual_resources = &tx_execution_info.actual_resources; let py_bouncer_info = PyBouncerInfo::calculate( actual_resources, additional_os_resources, @@ -140,8 +122,8 @@ impl TransactionExecutor { self.staged_for_commit_state = Some( transactional_state.stage(tx_executed_class_hashes, tx_visited_storage_entries), ); - let raw_tx_execution_info = serde_json::to_vec(&typed_tx_execution_info)?; - Ok((raw_tx_execution_info, py_bouncer_info)) + + Ok((tx_execution_info, py_bouncer_info)) } Err(error) => { transactional_state.abort();