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

Simulate txn #1281

Merged
merged 26 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 9 additions & 8 deletions crates/pallets/starknet/src/blockifier_state_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ use alloc::collections::{BTreeMap, BTreeSet};
use core::marker::PhantomData;

use blockifier::execution::contract_class::ContractClass;
use blockifier::state::cached_state::{CommitmentStateDiff, ContractStorageKey};
use blockifier::state::cached_state::{CommitmentStateDiff, ContractStorageKey, StateChangesCount};
use blockifier::state::errors::StateError;
use blockifier::state::state_api::{State, StateReader, StateResult};
use indexmap::IndexMap;
use mp_felt::Felt252Wrapper;
use mp_state::{
DeclaredClassesCount, DeclaredCompiledClassesCount, StateChanges, UpdatedContractsCount, UpdatedStorageVarsCount,
};
use mp_state::StateChanges;
use starknet_api::api_core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::hash::StarkFelt;
use starknet_api::state::StorageKey;
Expand All @@ -33,12 +31,15 @@ impl<T> StateChanges for BlockifierStateAdapter<T>
where
T: Config,
{
fn count_state_changes(
&self,
) -> (UpdatedContractsCount, UpdatedStorageVarsCount, DeclaredClassesCount, DeclaredCompiledClassesCount) {
fn count_state_changes(&self) -> StateChangesCount {
let keys = self.storage_update.keys();
let n_contract_updated = BTreeSet::from_iter(keys.clone().map(|&(contract_address, _)| contract_address)).len();
(n_contract_updated, keys.len(), self.class_hash_update, self.compiled_class_hash_update)
StateChangesCount {
n_modified_contracts: n_contract_updated,
n_storage_updates: keys.len(),
n_class_hash_updates: self.class_hash_update,
n_compiled_class_hash_updates: self.compiled_class_hash_update,
}
}
}

Expand Down
52 changes: 23 additions & 29 deletions crates/pallets/starknet/src/execution_config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use mp_simulations::SimulationFlag;
use mp_transactions::execution::ExecutionConfig;
use sp_core::Get;

Expand All @@ -8,47 +9,40 @@ use crate::Config;
/// flags for each transaction mode (e.g. normal, estimate fee, simulate, ...).
pub struct RuntimeExecutionConfigBuilder(ExecutionConfig);

impl Default for RuntimeExecutionConfigBuilder {
fn default() -> Self {
impl RuntimeExecutionConfigBuilder {
pub fn new<T: Config>() -> Self {
Self(ExecutionConfig {
is_query: false,
disable_transaction_fee: false,
disable_fee_charge: false,
disable_nonce_validation: false,
disable_validation: false,
disable_nonce_validation: T::DisableNonceValidation::get(),
disable_transaction_fee: T::DisableTransactionFee::get(),
})
}
}

impl RuntimeExecutionConfigBuilder {
#[must_use]
tdelabro marked this conversation as resolved.
Show resolved Hide resolved
pub fn with_query_mode(mut self) -> Self {
self.0.is_query = true;
self
}
pub fn with_transaction_fee_disabled(mut self) -> Self {
self.0.disable_transaction_fee = true;
self
}
pub fn with_fee_charge_disabled(mut self) -> Self {
self.0.disable_fee_charge = true;
self
}
pub fn with_nonce_validation_disabled(mut self) -> Self {
self.0.disable_nonce_validation = true;
self
}
pub fn with_validation_disabled(mut self) -> Self {
self.0.disable_validation = true;
#[must_use]
tdelabro marked this conversation as resolved.
Show resolved Hide resolved
pub fn with_simulation_mode(mut self, simulation_flags: &[SimulationFlag]) -> Self {
tdelabro marked this conversation as resolved.
Show resolved Hide resolved
for sim in simulation_flags {
match sim {
SimulationFlag::SkipFeeCharge => {
self.0.disable_fee_charge = true;
}
SimulationFlag::SkipValidate => {
self.0.disable_validation = true;
}
}
if self.0.disable_fee_charge && self.0.disable_validation {
break;
}
}
self
}

/// Builds the [`ExecutionConfig`] from the current set
/// of configuration flags and the runtime configuration.
#[must_use]
pub fn build<T: Config>(self) -> ExecutionConfig {
let mut execution_config = self.0;
execution_config.disable_transaction_fee |= T::DisableTransactionFee::get();
execution_config.disable_nonce_validation |= T::DisableNonceValidation::get();
execution_config
pub fn build(self) -> ExecutionConfig {
self.0
}
}
21 changes: 6 additions & 15 deletions crates/pallets/starknet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ pub mod pallet {
.execute(
&mut BlockifierStateAdapter::<T>::default(),
&Self::get_block_context(),
&RuntimeExecutionConfigBuilder::default().build::<T>(),
&RuntimeExecutionConfigBuilder::new::<T>().build(),
)
.map_err(|e| {
log::error!("failed to execute invoke tx: {:?}", e);
Expand Down Expand Up @@ -570,7 +570,7 @@ pub mod pallet {
.execute(
&mut BlockifierStateAdapter::<T>::default(),
&Self::get_block_context(),
&RuntimeExecutionConfigBuilder::default().build::<T>(),
&RuntimeExecutionConfigBuilder::new::<T>().build(),
)
.map_err(|_| Error::<T>::TransactionExecutionFailed)?;

Expand Down Expand Up @@ -619,7 +619,7 @@ pub mod pallet {
.execute(
&mut BlockifierStateAdapter::<T>::default(),
&Self::get_block_context(),
&RuntimeExecutionConfigBuilder::default().build::<T>(),
&RuntimeExecutionConfigBuilder::new::<T>().build(),
)
.map_err(|e| {
log::error!("failed to deploy accout: {:?}", e);
Expand Down Expand Up @@ -674,7 +674,7 @@ pub mod pallet {
.execute(
&mut BlockifierStateAdapter::<T>::default(),
&Self::get_block_context(),
&RuntimeExecutionConfigBuilder::default().build::<T>(),
&RuntimeExecutionConfigBuilder::new::<T>().build(),
)
.map_err(|e| {
log::error!("Failed to consume l1 message: {}", e);
Expand Down Expand Up @@ -1096,12 +1096,11 @@ impl<T: Config> Pallet<T> {
pub fn estimate_fee(transactions: Vec<UserTransaction>) -> Result<Vec<(u64, u64)>, DispatchError> {
let chain_id = Self::chain_id();

// is_query is true so disable_transaction_fee could be true or false
let execution_results = execute_txs_and_rollback::<T>(
&transactions,
&Self::get_block_context(),
chain_id,
&RuntimeExecutionConfigBuilder::default().with_query_mode().build::<T>(),
&RuntimeExecutionConfigBuilder::new::<T>().with_query_mode().build(),
)?;

let mut results = vec![];
Expand Down Expand Up @@ -1130,19 +1129,11 @@ impl<T: Config> Pallet<T> {
) -> Result<Vec<SimulatedTransaction>, DispatchError> {
let chain_id = Self::chain_id();

let mut execution_config_builder = RuntimeExecutionConfigBuilder::default();
if simulation_flags.contains(&SimulationFlag::SkipFeeCharge) {
execution_config_builder = execution_config_builder.with_fee_charge_disabled();
}
if simulation_flags.contains(&SimulationFlag::SkipValidate) {
execution_config_builder = execution_config_builder.with_validation_disabled();
}

let execution_results = execute_txs_and_rollback::<T>(
&transactions,
&Self::get_block_context(),
chain_id,
&execution_config_builder.build::<T>(),
&RuntimeExecutionConfigBuilder::new::<T>().with_simulation_mode(&simulation_flags).build(),
)?;

fn get_function_invocation(
Expand Down
10 changes: 1 addition & 9 deletions crates/primitives/fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use blockifier::block_context::BlockContext;
use blockifier::execution::entry_point::{
CallEntryPoint, CallInfo, CallType, EntryPointExecutionContext, ExecutionResources,
};
use blockifier::state::cached_state::StateChangesCount;
use blockifier::state::state_api::State;
use blockifier::transaction::errors::TransactionExecutionError;
use blockifier::transaction::objects::{AccountTransactionContext, ResourcesMapping, TransactionExecutionResult};
Expand Down Expand Up @@ -63,14 +62,7 @@ pub fn compute_transaction_resources<S: State + StateChanges>(
tx_type: TransactionType,
l1_handler_payload_size: Option<usize>,
) -> TransactionExecutionResult<ResourcesMapping> {
let (n_modified_contracts, n_storage_updates, n_class_hash_updates, n_compiled_class_hash_updates) =
state.count_state_changes();
let state_changes_count = StateChangesCount {
n_storage_updates,
n_class_hash_updates,
n_compiled_class_hash_updates,
n_modified_contracts,
};
let state_changes_count = state.count_state_changes();
let non_optional_call_infos: Vec<&CallInfo> =
vec![execute_call_info, validate_call_info].into_iter().flatten().collect();

Expand Down
17 changes: 2 additions & 15 deletions crates/primitives/state/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

use blockifier::execution::contract_class::ContractClass;
use blockifier::state::cached_state::ContractStorageKey;
use blockifier::state::cached_state::{ContractStorageKey, StateChangesCount};
use blockifier::state::errors::StateError;
use blockifier::state::state_api::{StateReader, StateResult};
use starknet_api::api_core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
Expand All @@ -11,25 +11,12 @@ use starknet_api::stdlib::collections::HashMap;

type ContractClassMapping = HashMap<ClassHash, ContractClass>;

pub type UpdatedContractsCount = usize;
pub type UpdatedStorageVarsCount = usize;
pub type DeclaredClassesCount = usize;
pub type DeclaredCompiledClassesCount = usize;
/// This trait allows to get the state changes of a starknet tx and therefore enables computing the
/// fees.
pub trait StateChanges {
/// This function counts the storage var updates implied by a transaction and the newly declared
/// class hashes.
///
/// # Returns
///
/// * `UpdatedContractsCount` - The number of modified contracts in the transaction.
/// * `UpdatedStorageVarsCount` - The number of modified storage vars in the transaction.
/// * `UpdatedClassHashesCount` - The number of newly declared classes.
/// * `UpdatedCompiledClassHashesCount` - The number of newly declared compiled classes.
fn count_state_changes(
&self,
) -> (UpdatedContractsCount, UpdatedStorageVarsCount, DeclaredClassesCount, DeclaredCompiledClassesCount);
fn count_state_changes(&self) -> StateChangesCount;
}

/// A simple implementation of `StateReader` using `HashMap`s as storage.
Expand Down
5 changes: 0 additions & 5 deletions starknet-rpc-test/spec_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,5 @@ use starknet_rpc_test::fixtures::{madara, ThreadSafeMadaraClient};
#[tokio::test]
#[ignore = "Waiting for starknet_providers::jsonrpc upgrade to v0.6.0"]
async fn returns_hardcoded_spec_version(madara: &ThreadSafeMadaraClient) -> Result<(), anyhow::Error> {
madara.get_starknet_client().await;

// TODO: test it when starknet_providers::jsonrpc upgrades to v0.6.0
// assert_eq!(rpc.spec_version().await?, SPEC_VERSION);

Ok(())
}