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

refactor(native_blockifier): flat fields in bouncerinfo #1394

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
2 changes: 0 additions & 2 deletions crates/blockifier/src/transaction/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ pub enum TransactionExecutionError {
{max_order}."
)]
InvalidOrder { object: String, order: usize, max_order: usize },
#[error("Invalid Transaction Execution Info. Field {field} was not found.")]
InvalidTransactionExecutionInfo { field: String },
#[error("The `validate` entry point should return `VALID`. Got {actual:?}.")]
InvalidValidateReturnData { actual: Retdata },
#[error(
Expand Down
39 changes: 1 addition & 38 deletions crates/blockifier/src/transaction/transaction_utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashMap;

use cairo_vm::vm::runners::builtin_runner::SEGMENT_ARENA_BUILTIN_NAME;
use cairo_vm::vm::runners::cairo_runner::ExecutionResources as VmExecutionResources;
use starknet_api::transaction::TransactionVersion;

use super::objects::GasVector;
Expand All @@ -13,7 +12,7 @@ use crate::fee::os_usage::get_additional_os_resources;
use crate::transaction::errors::TransactionExecutionError;
use crate::transaction::objects::{ResourcesMapping, TransactionExecutionResult};
use crate::transaction::transaction_types::TransactionType;
use crate::utils::{merge_hashmaps, usize_from_u128};
use crate::utils::usize_from_u128;

/// Calculates the total resources needed to include the transaction in a Starknet block as
/// most-recent (recent w.r.t. application on the given state).
Expand Down Expand Up @@ -86,39 +85,3 @@ pub fn verify_contract_class_version(
}
}
}

// TODO(Ayelet, 01/02/2024): Move to VmExecutionResourcesWrapper when merged.
pub fn vm_execution_resources_to_hash_map(
execution_resources: VmExecutionResources,
) -> HashMap<String, usize> {
let mut result = execution_resources.builtin_instance_counter.clone();
result.insert(
String::from("n_steps"),
execution_resources.n_steps + execution_resources.n_memory_holes,
);
result
}

type ResourcesMap = HashMap<String, usize>;

// TODO(Arni, 24/01/2024): Add state_diff_size to tx_weights
pub fn calculate_tx_weights(
additional_os_resources: VmExecutionResources,
actual_resources: ResourcesMap,
message_segment_length: usize,
) -> Result<ResourcesMap, TransactionExecutionError> {
let mut tx_weights: HashMap<String, usize> = HashMap::new();
let mut cairo_resource_usage: HashMap<String, usize> = actual_resources;
let value = cairo_resource_usage.remove("l1_gas_usage").ok_or(
TransactionExecutionError::InvalidTransactionExecutionInfo {
field: "l1_gas_usage".to_string(),
},
)?;
tx_weights.insert("gas_weight".to_string(), value);
let os_cairo_usage: HashMap<String, usize> =
vm_execution_resources_to_hash_map(additional_os_resources);
let cairo_usage = merge_hashmaps(&cairo_resource_usage, &os_cairo_usage);
tx_weights.extend(cairo_usage);
tx_weights.insert("message_segment_length".to_string(), message_segment_length);
Ok(tx_weights)
}
17 changes: 0 additions & 17 deletions crates/blockifier/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::{Add, AddAssign};

use crate::transaction::errors::NumericConversionError;

Expand All @@ -24,21 +22,6 @@ pub const fn const_max(a: u128, b: u128) -> u128 {
[a, b][(a < b) as usize]
}

pub fn merge_hashmaps<K, V>(x: &HashMap<K, V>, y: &HashMap<K, V>) -> HashMap<K, V>
where
K: Hash + Eq + Clone,
V: Add<Output = V> + AddAssign + Default + Clone,
{
let mut result = x.clone();
for (key, value) in y {
result
.entry(key.clone())
.and_modify(|v| v.add_assign(value.clone()))
.or_insert(value.clone());
}
result
}

/// Conversion from usize to u128. Currently, usize has 64 bits, so this conversion should never
/// fail.
pub fn usize_from_u128(val: u128) -> Result<usize, NumericConversionError> {
Expand Down
77 changes: 70 additions & 7 deletions crates/native_blockifier/src/py_transaction_execution_info.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use std::collections::{HashMap, HashSet};

use blockifier::abi::constants;
use blockifier::execution::call_info::{CallInfo, OrderedEvent, OrderedL2ToL1Message};
use blockifier::execution::entry_point::CallType;
use blockifier::transaction::objects::TransactionExecutionInfo;
use blockifier::transaction::objects::{
ResourcesMapping, TransactionExecutionInfo, TransactionExecutionResult,
};
use cairo_vm::serde::deserialize_program::BuiltinName;
use cairo_vm::vm::runners::cairo_runner::ExecutionResources as VmExecutionResources;
use pyo3::prelude::*;
use starknet_api::deprecated_contract_class::EntryPointType;
Expand Down Expand Up @@ -217,14 +221,73 @@ impl From<VmExecutionResources> for PyVmExecutionResources {

#[pyclass]
#[derive(Clone, Default)]
// TODO(Ayelet, 24/01/2024): Consider remove message_segment_length, state_diff_size.
pub struct PyBouncerInfo {
#[pyo3(get)]
// The number of felts needed to store L1<>L2 messages.
pub message_segment_length: usize,
pub state_diff_size: usize, // The number of felts needed to store the state diff.
#[pyo3(get)]
// The number of felts needed to store the state diff.
pub state_diff_size: usize,
pub l1_gas_amount: usize,
#[pyo3(get)]
pub tx_weights: HashMap<String, usize>,
pub message_segment_length: usize, // The number of felts needed to store L1<>L2 messages.
#[pyo3(get)]
pub execution_resources: PyVmExecutionResources,
}

impl PyBouncerInfo {
pub fn calculate(
tx_actual_resources: &ResourcesMapping,
tx_additional_os_resources: VmExecutionResources,
message_segment_length: usize,
state_diff_size: usize,
) -> TransactionExecutionResult<Self> {
let l1_gas_amount = *tx_actual_resources
.0
.get("l1_gas_usage")
.expect("Invalid Transaction Execution Info. Field l1_gas_usage was not found.");

// TODO(Ayelet, 04/02/2024): Consider defining a constant list.
let builtin_ordered_list = [
BuiltinName::output,
BuiltinName::pedersen,
BuiltinName::range_check,
BuiltinName::ecdsa,
BuiltinName::bitwise,
BuiltinName::ec_op,
BuiltinName::keccak,
BuiltinName::poseidon,
];
let builtin_instance_counter: HashMap<String, usize> = builtin_ordered_list
.iter()
.map(|name| {
(
name.name().to_string(),
tx_actual_resources.0.get(name.name()).copied().unwrap_or_default(),
)
})
.collect();
let tx_actual_resources = VmExecutionResources {
n_steps: tx_actual_resources
.0
.get(constants::N_STEPS_RESOURCE)
.copied()
.unwrap_or_default(),
n_memory_holes: tx_actual_resources
.0
.get("n_memory_holes")
.copied()
.unwrap_or_default(),
builtin_instance_counter,
};

let mut merged_resources = &tx_additional_os_resources + &tx_actual_resources;
// Memory holes are counted as steps.
merged_resources.n_steps += merged_resources.n_memory_holes;
merged_resources.n_memory_holes = 0;

Ok(Self {
state_diff_size,
l1_gas_amount,
message_segment_length,
execution_resources: PyVmExecutionResources::from(merged_resources),
})
}
}
21 changes: 9 additions & 12 deletions crates/native_blockifier/src/transaction_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ 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::transaction_utils::calculate_tx_weights;
use blockifier::transaction::transactions::{ExecutableTransaction, ValidatableTransaction};
use blockifier::versioned_constants::VersionedConstants;
use cairo_vm::vm::runners::builtin_runner::HASH_BUILTIN_NAME;
Expand Down Expand Up @@ -135,24 +134,22 @@ impl<S: StateReader> TransactionExecutor<S> {
let state_diff_size = 0;

// Finalize counting logic.
let actual_resources = tx_execution_info.actual_resources.0.clone();
let tx_weights = calculate_tx_weights(
additional_os_resources,
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 py_bouncer_info = PyBouncerInfo::calculate(
actual_resources,
additional_os_resources,
message_segment_length,
state_diff_size,
)?;
let py_bouncer_info =
PyBouncerInfo { message_segment_length, state_diff_size, tx_weights };

self.staged_for_commit_state = Some(
transactional_state.stage(tx_executed_class_hashes, tx_visited_storage_entries),
);

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))
}
Err(error) => {
Expand Down
Loading