Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): add ExecutionSummary::to_gas_vector() #4048

Merged
merged 1 commit into from
Feb 10, 2025
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
1 change: 1 addition & 0 deletions crates/blockifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ workspace = true
cairo_native = ["dep:cairo-native", "starknet_sierra_multicompile/cairo_native"]
jemalloc = ["dep:tikv-jemallocator"]
native_blockifier = []
node_api = []
reexecution = ["transaction_serde"]
testing = ["rand", "rstest", "rstest_reuse", "starknet_api/testing"]
transaction_serde = []
Expand Down
60 changes: 59 additions & 1 deletion crates/blockifier/src/execution/call_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use std::ops::{Add, AddAssign};
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use serde::Serialize;
use starknet_api::core::{ClassHash, ContractAddress, EthAddress};
use starknet_api::execution_resources::GasAmount;
use starknet_api::execution_resources::{GasAmount, GasVector};
use starknet_api::state::StorageKey;
use starknet_api::transaction::fields::GasVectorComputationMode;
use starknet_api::transaction::{EventContent, L2ToL1Payload};
use starknet_types_core::felt::Felt;

Expand Down Expand Up @@ -71,6 +72,25 @@ pub struct EventSummary {
pub total_event_data_size: u64,
}

impl EventSummary {
pub fn to_gas_vector(
&self,
versioned_constants: &VersionedConstants,
mode: &GasVectorComputationMode,
) -> GasVector {
let archival_gas_costs = versioned_constants.get_archival_data_gas_costs(mode);
let gas_amount: GasAmount = (archival_gas_costs.gas_per_data_felt
* (archival_gas_costs.event_key_factor * self.total_event_keys
+ self.total_event_data_size))
.to_integer()
.into();
match mode {
GasVectorComputationMode::All => GasVector::from_l2_gas(gas_amount),
GasVectorComputationMode::NoL2Gas => GasVector::from_l1_gas(gas_amount),
}
}
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExecutionSummary {
pub charged_resources: ChargedResources,
Expand Down Expand Up @@ -99,6 +119,44 @@ impl Sum for ExecutionSummary {
}
}

impl ExecutionSummary {
/// Returns the a gas cost _estimation_ for the execution summary.
///
/// In particular, this calculation ignores state changes, cost of declared classes, L1 handler
/// payload length, plus Starknet OS overhead. These costs are only accounted for on a
/// transaction level and cannot be computed based on a single execution summary.
#[cfg(feature = "node_api")]
pub fn to_partial_gas_vector(
self,
versioned_constants: &VersionedConstants,
mode: &GasVectorComputationMode,
) -> GasVector {
use crate::fee::resources::{ComputationResources, MessageResources};

let computation_resources = ComputationResources {
vm_resources: self.charged_resources.vm_resources,
n_reverted_steps: 0,
sierra_gas: self.charged_resources.gas_consumed,
reverted_sierra_gas: 0u64.into(),
};

[
computation_resources.to_gas_vector(versioned_constants, mode),
self.event_summary.to_gas_vector(versioned_constants, mode),
MessageResources::new(self.l2_to_l1_payload_lengths, None).to_gas_vector(),
]
.iter()
.fold(GasVector::ZERO, |accumulator, cost| {
accumulator.checked_add(*cost).unwrap_or_else(|| {
panic!(
"Execution summary to gas vector overflowed: tried to add {cost:?} to \
{accumulator:?}"
);
})
})
}
}

/// L2 resources counted for fee charge.
/// When all execution will be using gas (no VM mode), this should be removed, and the gas_consumed
/// field should be used for fee collection.
Expand Down
74 changes: 37 additions & 37 deletions crates/blockifier/src/fee/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::fee::gas_usage::{
use crate::state::cached_state::{StateChanges, StateChangesCountForFee};
use crate::transaction::errors::TransactionFeeError;
use crate::utils::u64_from_usize;
use crate::versioned_constants::{AllocationCost, ArchivalDataGasCosts, VersionedConstants};
use crate::versioned_constants::{AllocationCost, VersionedConstants};

pub type TransactionFeeResult<T> = Result<T, TransactionFeeError>;

Expand Down Expand Up @@ -250,60 +250,60 @@ impl ArchivalDataResources {
versioned_constants: &VersionedConstants,
mode: &GasVectorComputationMode,
) -> GasVector {
let archival_gas_costs = match mode {
// Computation is in L2 gas units.
GasVectorComputationMode::All => &versioned_constants.archival_data_gas_costs,
// Computation is in L1 gas units.
GasVectorComputationMode::NoL2Gas => {
&versioned_constants.deprecated_l2_resource_gas_costs
}
};
let gas_amount = [
self.get_calldata_and_signature_gas_cost(archival_gas_costs),
self.get_code_gas_cost(archival_gas_costs),
self.get_events_gas_cost(archival_gas_costs),
[
self.get_calldata_and_signature_gas_cost(versioned_constants, mode),
self.get_code_gas_cost(versioned_constants, mode),
self.event_summary.to_gas_vector(versioned_constants, mode),
]
.into_iter()
.fold(GasAmount::ZERO, |accumulator, cost| {
.fold(GasVector::ZERO, |accumulator, cost| {
accumulator.checked_add(cost).unwrap_or_else(|| {
panic!(
"Archival data resources to gas vector overflowed: tried to add \
{accumulator:?} gas to {cost:?} gas.",
{accumulator:?} gas vector to {cost:?} gas vector.",
)
})
});
match mode {
GasVectorComputationMode::All => GasVector::from_l2_gas(gas_amount),
GasVectorComputationMode::NoL2Gas => GasVector::from_l1_gas(gas_amount),
}
})
}

/// Returns the cost for transaction calldata and transaction signature. Each felt costs a
/// fixed and configurable amount of gas. This cost represents the cost of storing the
/// calldata and the signature on L2. The result is given in L1/L2 gas units, depending on the
/// mode.
/// calldata and the signature on L2.
fn get_calldata_and_signature_gas_cost(
&self,
archival_gas_costs: &ArchivalDataGasCosts,
) -> GasAmount {
versioned_constants: &VersionedConstants,
mode: &GasVectorComputationMode,
) -> GasVector {
let archival_gas_costs = versioned_constants.get_archival_data_gas_costs(mode);

// TODO(Avi, 20/2/2024): Calculate the number of bytes instead of the number of felts.
let total_data_size = u64_from_usize(self.calldata_length + self.signature_length);
(archival_gas_costs.gas_per_data_felt * total_data_size).to_integer().into()
}
let gas_amount =
(archival_gas_costs.gas_per_data_felt * total_data_size).to_integer().into();

/// Returns the cost of declared class codes in L1/L2 gas units, depending on the mode.
fn get_code_gas_cost(&self, archival_gas_costs: &ArchivalDataGasCosts) -> GasAmount {
(archival_gas_costs.gas_per_code_byte * u64_from_usize(self.code_size)).to_integer().into()
match mode {
GasVectorComputationMode::All => GasVector::from_l2_gas(gas_amount),
GasVectorComputationMode::NoL2Gas => GasVector::from_l1_gas(gas_amount),
}
}

/// Returns the cost of the transaction's emmited events in L1/L2 gas units, depending on the
/// mode.
fn get_events_gas_cost(&self, archival_gas_costs: &ArchivalDataGasCosts) -> GasAmount {
(archival_gas_costs.gas_per_data_felt
* (archival_gas_costs.event_key_factor * self.event_summary.total_event_keys
+ self.event_summary.total_event_data_size))
.to_integer()
.into()
/// Returns the cost of declared class codes.
fn get_code_gas_cost(
&self,
versioned_constants: &VersionedConstants,
mode: &GasVectorComputationMode,
) -> GasVector {
let archival_gas_costs = versioned_constants.get_archival_data_gas_costs(mode);

let gas_amount: GasAmount = (archival_gas_costs.gas_per_code_byte
* u64_from_usize(self.code_size))
.to_integer()
.into();

match mode {
GasVectorComputationMode::All => GasVector::from_l2_gas(gas_amount),
GasVectorComputationMode::NoL2Gas => GasVector::from_l1_gas(gas_amount),
}
}
}

Expand Down
Loading