From c00aca4261f1c5da4b2cf8cdcde0ebb49945a491 Mon Sep 17 00:00:00 2001 From: Yael Doweck Date: Sun, 2 Feb 2025 15:47:48 +0200 Subject: [PATCH] refactor(native_blockifier, starknet_consensus_orchestrator): share execution objects --- Cargo.lock | 14 +++- Cargo.toml | 2 + commitlint.config.js | 1 + crates/native_blockifier/Cargo.toml | 2 +- .../src/py_block_executor.rs | 80 +++---------------- crates/shared_execution_objects/Cargo.toml | 17 ++++ .../src/central_objects.rs | 61 ++++++++++++++ crates/shared_execution_objects/src/lib.rs | 7 ++ .../Cargo.toml | 4 +- .../src/cende/central_objects.rs | 58 -------------- .../src/cende/central_objects_test.rs | 2 +- .../src/cende/mod.rs | 4 +- crates/starknet_os/Cargo.toml | 4 +- crates/starknet_os/src/io/os_input.rs | 2 +- 14 files changed, 119 insertions(+), 139 deletions(-) create mode 100644 crates/shared_execution_objects/Cargo.toml create mode 100644 crates/shared_execution_objects/src/central_objects.rs create mode 100644 crates/shared_execution_objects/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9f85dacf891..1ff093b8afc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7300,8 +7300,8 @@ dependencies = [ "pretty_assertions", "pyo3", "pyo3-log", - "serde", "serde_json", + "shared_execution_objects", "starknet-types-core", "starknet_api", "starknet_sierra_multicompile", @@ -10438,6 +10438,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared_execution_objects" +version = "0.0.0" +dependencies = [ + "blockifier", + "serde", + "starknet_api", +] + [[package]] name = "shlex" version = "1.3.0" @@ -11090,6 +11099,7 @@ dependencies = [ "rstest", "serde", "serde_json", + "shared_execution_objects", "starknet-types-core", "starknet_api", "starknet_batcher", @@ -11411,9 +11421,9 @@ dependencies = [ "cairo-vm", "indoc 2.0.5", "serde", + "shared_execution_objects", "starknet-types-core", "starknet_api", - "starknet_consensus_orchestrator", "starknet_patricia", "strum 0.25.0", "strum_macros 0.25.3", diff --git a/Cargo.toml b/Cargo.toml index 6007e3b88ab..96148c47a69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ members = [ "crates/papyrus_storage", "crates/papyrus_sync", "crates/papyrus_test_utils", + "crates/shared_execution_objects", "crates/starknet_api", "crates/starknet_batcher", "crates/starknet_batcher_types", @@ -212,6 +213,7 @@ serde_repr = "0.1.19" serde_yaml = "0.9.16" sha2 = "0.10.8" sha3 = "0.10.8" +shared_execution_objects.path = "crates/shared_execution_objects" simple_logger = "4.0.0" starknet-core = "0.6.0" starknet-crypto = "0.7.1" diff --git a/commitlint.config.js b/commitlint.config.js index 149e3b3727f..e745a64d7eb 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -50,6 +50,7 @@ const Configuration = { 'papyrus_sync', 'papyrus_test_utils', 'release', + 'shared_execution_objects', 'starknet_api', 'starknet_batcher', 'starknet_batcher_types', diff --git a/crates/native_blockifier/Cargo.toml b/crates/native_blockifier/Cargo.toml index 51a4606aa81..ebf52f84ee2 100644 --- a/crates/native_blockifier/Cargo.toml +++ b/crates/native_blockifier/Cargo.toml @@ -41,8 +41,8 @@ papyrus_state_reader.workspace = true papyrus_storage.workspace = true pyo3 = { workspace = true, features = ["hashbrown", "num-bigint"] } pyo3-log.workspace = true -serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["arbitrary_precision"] } +shared_execution_objects.workspace = true starknet-types-core.workspace = true starknet_api.workspace = true starknet_sierra_multicompile.workspace = true diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index 3b8e02c2dbc..58007bdbaf1 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -1,8 +1,5 @@ #![allow(non_local_definitions)] -use std::collections::HashMap; - -use blockifier::abi::constants as abi_constants; use blockifier::blockifier::config::{ContractClassManagerConfig, TransactionExecutorConfig}; use blockifier::blockifier::transaction_executor::{ BlockExecutionSummary, @@ -12,20 +9,15 @@ use blockifier::blockifier::transaction_executor::{ use blockifier::blockifier_versioned_constants::VersionedConstants; use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; -use blockifier::execution::call_info::CallInfo; -use blockifier::fee::receipt::TransactionReceipt; use blockifier::state::contract_class_manager::ContractClassManager; -use blockifier::transaction::objects::{ExecutionResourcesTraits, TransactionExecutionInfo}; use blockifier::transaction::transaction_execution::Transaction; use papyrus_state_reader::papyrus_state::PapyrusReader; use pyo3::prelude::*; use pyo3::types::{PyBytes, PyList}; use pyo3::{FromPyObject, PyAny, Python}; -use serde::Serialize; +use shared_execution_objects::central_objects::CentralTransactionExecutionInfo; use starknet_api::block::BlockNumber; use starknet_api::core::{ChainId, ContractAddress}; -use starknet_api::execution_resources::GasVector; -use starknet_api::transaction::fields::Fee; use starknet_types_core::felt::Felt; use crate::errors::{NativeBlockifierError, NativeBlockifierResult}; @@ -47,65 +39,16 @@ use crate::storage::{ }; pub(crate) type RawTransactionExecutionResult = Vec; +const RESULT_SERIALIZE_ERR: &str = "Failed serializing execution info."; #[cfg(test)] #[path = "py_block_executor_test.rs"] mod py_block_executor_test; -const RESULT_SERIALIZE_ERR: &str = "Failed serializing execution info."; - -/// A mapping from a transaction execution resource to its actual usage. -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] -pub struct ResourcesMapping(pub HashMap); - -/// Stripped down `TransactionExecutionInfo` for Python serialization, containing only the required -/// fields. -#[derive(Debug, Serialize)] -pub(crate) struct ThinTransactionExecutionInfo { - pub validate_call_info: Option, - pub execute_call_info: Option, - pub fee_transfer_call_info: Option, - pub actual_fee: Fee, - pub da_gas: GasVector, - pub actual_resources: ResourcesMapping, - pub revert_error: Option, - pub total_gas: GasVector, -} - -impl ThinTransactionExecutionInfo { - pub fn from_tx_execution_info(tx_execution_info: TransactionExecutionInfo) -> Self { - Self { - validate_call_info: tx_execution_info.validate_call_info, - execute_call_info: tx_execution_info.execute_call_info, - fee_transfer_call_info: tx_execution_info.fee_transfer_call_info, - actual_fee: tx_execution_info.receipt.fee, - da_gas: tx_execution_info.receipt.da_gas, - actual_resources: ThinTransactionExecutionInfo::receipt_to_resources_mapping( - &tx_execution_info.receipt, - ), - revert_error: tx_execution_info.revert_error.map(|error| error.to_string()), - total_gas: tx_execution_info.receipt.gas, - } - } - pub fn serialize(self) -> RawTransactionExecutionResult { - serde_json::to_vec(&self).expect(RESULT_SERIALIZE_ERR) - } - - pub fn receipt_to_resources_mapping(receipt: &TransactionReceipt) -> ResourcesMapping { - let vm_resources = &receipt.resources.computation.vm_resources; - let mut resources = HashMap::from([( - abi_constants::N_STEPS_RESOURCE.to_string(), - vm_resources.total_n_steps() + receipt.resources.computation.n_reverted_steps, - )]); - resources.extend( - vm_resources - .prover_builtins() - .iter() - .map(|(builtin, value)| (builtin.to_str_with_suffix().to_string(), *value)), - ); - - ResourcesMapping(resources) - } +fn serialize_block_execution_info( + py_tx_execution_info: CentralTransactionExecutionInfo, +) -> RawTransactionExecutionResult { + serde_json::to_vec(&py_tx_execution_info).expect(RESULT_SERIALIZE_ERR) } #[pyclass] @@ -198,11 +141,11 @@ impl PyBlockExecutor { ) -> NativeBlockifierResult> { let tx: Transaction = py_tx(tx, optional_py_class_info).expect(PY_TX_PARSING_ERR); let (tx_execution_info, _state_diff) = self.tx_executor().execute(&tx)?; - let thin_tx_execution_info = - ThinTransactionExecutionInfo::from_tx_execution_info(tx_execution_info); + let central_tx_execution_info = CentralTransactionExecutionInfo::from(tx_execution_info); // Serialize and convert to PyBytes. - let serialized_tx_execution_info = thin_tx_execution_info.serialize(); + let serialized_tx_execution_info = + serialize_block_execution_info(central_tx_execution_info); Ok(Python::with_gil(|py| PyBytes::new(py, &serialized_tx_execution_info).into())) } @@ -234,10 +177,9 @@ impl PyBlockExecutor { .map(|result| match result { Ok((tx_execution_info, _state_diff)) => ( true, - ThinTransactionExecutionInfo::from_tx_execution_info( + serialize_block_execution_info(CentralTransactionExecutionInfo::from( tx_execution_info, - ) - .serialize(), + )), ), Err(error) => (false, serialize_failure_reason(error)), }) diff --git a/crates/shared_execution_objects/Cargo.toml b/crates/shared_execution_objects/Cargo.toml new file mode 100644 index 00000000000..8dd9be4589f --- /dev/null +++ b/crates/shared_execution_objects/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "shared_execution_objects" +version.workspace = true +edition.workspace = true +repository.workspace = true +license-file.workspace = true + +[features] +deserialize = ["blockifier/transaction_serde"] + +[dependencies] +blockifier.workspace = true +serde.workspace = true +starknet_api.workspace = true + +[lints] +workspace = true diff --git a/crates/shared_execution_objects/src/central_objects.rs b/crates/shared_execution_objects/src/central_objects.rs new file mode 100644 index 00000000000..1d6160bc95a --- /dev/null +++ b/crates/shared_execution_objects/src/central_objects.rs @@ -0,0 +1,61 @@ +use std::collections::HashMap; + +use blockifier::abi::constants as abi_constants; +use blockifier::execution::call_info::CallInfo; +use blockifier::fee::receipt::TransactionReceipt; +use blockifier::transaction::objects::{ExecutionResourcesTraits, TransactionExecutionInfo}; +use serde::Serialize; +use starknet_api::execution_resources::GasVector; +use starknet_api::transaction::fields::Fee; + +/// A mapping from a transaction execution resource to its actual usage. +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] +pub struct ResourcesMapping(pub HashMap); + +impl From for ResourcesMapping { + fn from(receipt: TransactionReceipt) -> ResourcesMapping { + let vm_resources = &receipt.resources.computation.vm_resources; + let mut resources = HashMap::from([( + abi_constants::N_STEPS_RESOURCE.to_string(), + vm_resources.total_n_steps() + receipt.resources.computation.n_reverted_steps, + )]); + resources.extend( + vm_resources + .prover_builtins() + .iter() + .map(|(builtin, value)| (builtin.to_str_with_suffix().to_string(), *value)), + ); + + ResourcesMapping(resources) + } +} + +/// The TransactionExecutionInfo object as used by the Python code. +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +#[derive(Debug, Serialize)] +pub struct CentralTransactionExecutionInfo { + pub validate_call_info: Option, + pub execute_call_info: Option, + pub fee_transfer_call_info: Option, + pub actual_fee: Fee, + pub da_gas: GasVector, + pub actual_resources: ResourcesMapping, + pub revert_error: Option, + pub total_gas: GasVector, +} + +impl From for CentralTransactionExecutionInfo { + fn from(tx_execution_info: TransactionExecutionInfo) -> CentralTransactionExecutionInfo { + CentralTransactionExecutionInfo { + validate_call_info: tx_execution_info.validate_call_info, + execute_call_info: tx_execution_info.execute_call_info, + fee_transfer_call_info: tx_execution_info.fee_transfer_call_info, + actual_fee: tx_execution_info.receipt.fee, + da_gas: tx_execution_info.receipt.da_gas, + revert_error: tx_execution_info.revert_error.map(|error| error.to_string()), + total_gas: tx_execution_info.receipt.gas, + actual_resources: tx_execution_info.receipt.into(), + } + } +} diff --git a/crates/shared_execution_objects/src/lib.rs b/crates/shared_execution_objects/src/lib.rs new file mode 100644 index 00000000000..625ea25fa5c --- /dev/null +++ b/crates/shared_execution_objects/src/lib.rs @@ -0,0 +1,7 @@ +//! The `shared_execution_objects` crate contains execution objects shared between different crates. + +/// Contains a rust version of objects on the centralized Python side. These objects are used when +/// interacting with the centralized Python. +pub mod central_objects; +// TODO(Yael): add the execution objects from the blockifier: execution_info, bouncer_weights, +// commitment_state_diff. diff --git a/crates/starknet_consensus_orchestrator/Cargo.toml b/crates/starknet_consensus_orchestrator/Cargo.toml index f71c7f47ea9..86b5a35b3b6 100644 --- a/crates/starknet_consensus_orchestrator/Cargo.toml +++ b/crates/starknet_consensus_orchestrator/Cargo.toml @@ -6,9 +6,6 @@ repository.workspace = true license-file.workspace = true description = "Implements the consensus context and orchestrates the node's components accordingly" -[features] -deserialize = ["blockifier/transaction_serde"] - [dependencies] async-trait.workspace = true cairo-lang-starknet-classes.workspace = true @@ -23,6 +20,7 @@ paste.workspace = true reqwest = { workspace = true, features = ["json"] } serde.workspace = true serde_json = { workspace = true, features = ["arbitrary_precision"] } +shared_execution_objects.workspace = true starknet-types-core.workspace = true starknet_api.workspace = true starknet_batcher_types.workspace = true diff --git a/crates/starknet_consensus_orchestrator/src/cende/central_objects.rs b/crates/starknet_consensus_orchestrator/src/cende/central_objects.rs index 6d70234abff..9c415eb888f 100644 --- a/crates/starknet_consensus_orchestrator/src/cende/central_objects.rs +++ b/crates/starknet_consensus_orchestrator/src/cende/central_objects.rs @@ -1,12 +1,7 @@ -use std::collections::HashMap; use std::str::FromStr; -use blockifier::abi::constants as abi_constants; use blockifier::bouncer::BouncerWeights; -use blockifier::execution::call_info::CallInfo; -use blockifier::fee::receipt::TransactionReceipt; use blockifier::state::cached_state::CommitmentStateDiff; -use blockifier::transaction::objects::{ExecutionResourcesTraits, TransactionExecutionInfo}; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_lang_starknet_classes::NestedIntList; use indexmap::{indexmap, IndexMap}; @@ -29,7 +24,6 @@ use starknet_api::core::{ }; use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::executable_transaction::L1HandlerTransaction; -use starknet_api::execution_resources::GasVector; use starknet_api::rpc_transaction::{ InternalRpcDeclareTransactionV3, InternalRpcDeployAccountTransaction, @@ -440,58 +434,6 @@ pub(crate) fn casm_contract_class_central_format( ..compiled_class_hash } } - -/// A mapping from a transaction execution resource to its actual usage. -#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] -#[derive(Debug, Eq, PartialEq, Serialize)] -struct ResourcesMapping(pub HashMap); - -impl From for ResourcesMapping { - fn from(receipt: TransactionReceipt) -> ResourcesMapping { - let vm_resources = &receipt.resources.computation.vm_resources; - let mut resources = HashMap::from([( - abi_constants::N_STEPS_RESOURCE.to_string(), - vm_resources.total_n_steps() + receipt.resources.computation.n_reverted_steps, - )]); - resources.extend( - vm_resources - .prover_builtins() - .iter() - .map(|(builtin, value)| (builtin.to_str_with_suffix().to_string(), *value)), - ); - - ResourcesMapping(resources) - } -} - -#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] -#[derive(Debug, Serialize)] -pub struct CentralTransactionExecutionInfo { - validate_call_info: Option, - execute_call_info: Option, - fee_transfer_call_info: Option, - actual_fee: Fee, - da_gas: GasVector, - actual_resources: ResourcesMapping, - revert_error: Option, - total_gas: GasVector, -} - -impl From for CentralTransactionExecutionInfo { - fn from(tx_execution_info: TransactionExecutionInfo) -> CentralTransactionExecutionInfo { - CentralTransactionExecutionInfo { - validate_call_info: tx_execution_info.validate_call_info, - execute_call_info: tx_execution_info.execute_call_info, - fee_transfer_call_info: tx_execution_info.fee_transfer_call_info, - actual_fee: tx_execution_info.receipt.fee, - da_gas: tx_execution_info.receipt.da_gas, - revert_error: tx_execution_info.revert_error.map(|error| error.to_string()), - total_gas: tx_execution_info.receipt.gas, - actual_resources: tx_execution_info.receipt.into(), - } - } -} - async fn get_contract_classes_if_declare( class_manager: SharedClassManagerClient, tx: &InternalConsensusTransaction, diff --git a/crates/starknet_consensus_orchestrator/src/cende/central_objects_test.rs b/crates/starknet_consensus_orchestrator/src/cende/central_objects_test.rs index 3c65a737dc0..835d52feaac 100644 --- a/crates/starknet_consensus_orchestrator/src/cende/central_objects_test.rs +++ b/crates/starknet_consensus_orchestrator/src/cende/central_objects_test.rs @@ -46,6 +46,7 @@ use mockall::predicate::eq; use num_bigint::BigUint; use rstest::rstest; use serde_json::Value; +use shared_execution_objects::central_objects::CentralTransactionExecutionInfo; use starknet_api::block::{ BlockHash, BlockInfo, @@ -113,7 +114,6 @@ use super::{ CentralInvokeTransaction, CentralStateDiff, CentralTransaction, - CentralTransactionExecutionInfo, CentralTransactionWritten, }; use crate::cende::central_objects::casm_contract_class_central_format; diff --git a/crates/starknet_consensus_orchestrator/src/cende/mod.rs b/crates/starknet_consensus_orchestrator/src/cende/mod.rs index 90953c18569..a9f8f700559 100644 --- a/crates/starknet_consensus_orchestrator/src/cende/mod.rs +++ b/crates/starknet_consensus_orchestrator/src/cende/mod.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod cende_test; -pub mod central_objects; +mod central_objects; use std::collections::BTreeMap; use std::fs; @@ -19,7 +19,6 @@ use central_objects::{ CentralCompressedStateDiff, CentralSierraContractClassEntry, CentralStateDiff, - CentralTransactionExecutionInfo, CentralTransactionWritten, }; #[cfg(test)] @@ -28,6 +27,7 @@ use papyrus_config::dumping::{ser_optional_param, ser_param, SerializeConfig}; use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam}; use reqwest::{Certificate, Client, ClientBuilder, RequestBuilder}; use serde::{Deserialize, Serialize}; +use shared_execution_objects::central_objects::CentralTransactionExecutionInfo; use starknet_api::block::{BlockInfo, BlockNumber, StarknetVersion}; use starknet_api::consensus_transaction::InternalConsensusTransaction; use starknet_api::core::ClassHash; diff --git a/crates/starknet_os/Cargo.toml b/crates/starknet_os/Cargo.toml index ee518d4394f..f6f25cd71f3 100644 --- a/crates/starknet_os/Cargo.toml +++ b/crates/starknet_os/Cargo.toml @@ -10,8 +10,8 @@ description = "The Starknet OS." deserialize = [ "blockifier/transaction_serde", "serde", + "shared_execution_objects/deserialize", "starknet-types-core/serde", - "starknet_consensus_orchestrator/deserialize", "starknet_patricia/deserialize", ] testing = ["dep:strum", "dep:strum_macros"] @@ -22,9 +22,9 @@ cairo-lang-starknet-classes.workspace = true cairo-vm.workspace = true indoc.workspace = true serde = { workspace = true, optional = true, features = ["derive"] } +shared_execution_objects.workspace = true starknet-types-core.workspace = true starknet_api.workspace = true -starknet_consensus_orchestrator.workspace = true starknet_patricia.workspace = true strum = { workspace = true, optional = true } strum_macros = { workspace = true, optional = true } diff --git a/crates/starknet_os/src/io/os_input.rs b/crates/starknet_os/src/io/os_input.rs index 268f419e72f..59f9a7d302c 100644 --- a/crates/starknet_os/src/io/os_input.rs +++ b/crates/starknet_os/src/io/os_input.rs @@ -2,11 +2,11 @@ use std::collections::HashMap; use blockifier::context::ChainInfo; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use shared_execution_objects::central_objects::CentralTransactionExecutionInfo; use starknet_api::block::{BlockHash, BlockNumber}; use starknet_api::core::{ClassHash, ContractAddress}; use starknet_api::deprecated_contract_class::ContractClass; use starknet_api::executable_transaction::Transaction; -use starknet_consensus_orchestrator::cende::central_objects::CentralTransactionExecutionInfo; use starknet_patricia::hash::hash_trait::HashOutput; use starknet_patricia::patricia_merkle_tree::types::SubTreeHeight; use starknet_types_core::felt::Felt;