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

fix(executor): fix L2 gas computation and inner-call gas estimation #2511

Merged
merged 4 commits into from
Jan 30, 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
5 changes: 3 additions & 2 deletions crates/executor/src/estimate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use blockifier::transaction::transaction_execution::Transaction;
use blockifier::transaction::transactions::ExecutableTransaction;
use starknet_api::transaction::fields::GasVectorComputationMode;

use super::error::TransactionExecutionError;
use super::execution_state::ExecutionState;
Expand All @@ -19,12 +18,14 @@ pub fn estimate(
let _span = tracing::debug_span!("estimate", transaction_hash=%super::transaction::transaction_hash(&transaction), %block_number, %transaction_idx).entered();

let fee_type = super::transaction::fee_type(&transaction);
let gas_vector_computation_mode =
super::transaction::gas_vector_computation_mode(&transaction);
let minimal_l1_gas_amount_vector = match &transaction {
Transaction::Account(account_transaction) => {
Some(blockifier::fee::gas_usage::estimate_minimal_gas_vector(
&block_context,
account_transaction,
&GasVectorComputationMode::All,
&gas_vector_computation_mode,
))
}
Transaction::L1Handler(_) => None,
Expand Down
49 changes: 38 additions & 11 deletions crates/executor/src/simulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,15 @@ pub fn simulate(
let transaction_declared_deprecated_class_hash =
transaction_declared_deprecated_class(&transaction);
let fee_type = super::transaction::fee_type(&transaction);
let gas_vector_computation_mode =
super::transaction::gas_vector_computation_mode(&transaction);

let minimal_l1_gas_amount_vector = match &transaction {
Transaction::Account(account_transaction) => {
Some(blockifier::fee::gas_usage::estimate_minimal_gas_vector(
&block_context,
account_transaction,
&GasVectorComputationMode::All,
&gas_vector_computation_mode,
))
}
Transaction::L1Handler(_) => None,
Expand Down Expand Up @@ -131,6 +134,8 @@ pub fn simulate(
tx_info,
state_diff,
block_context.versioned_constants(),
&gas_vector_computation_mode,
block_context.block_info().use_kzg_da,
),
});
}
Expand Down Expand Up @@ -182,10 +187,11 @@ pub fn trace(
let mut traces = Vec::with_capacity(transactions.len());
for (transaction_idx, tx) in transactions.into_iter().enumerate() {
let hash = transaction_hash(&tx);
let _span = tracing::debug_span!("simulate", transaction_hash=%super::transaction::transaction_hash(&tx), %transaction_idx).entered();
let _span = tracing::debug_span!("trace", transaction_hash=%super::transaction::transaction_hash(&tx), %transaction_idx).entered();

let tx_type = transaction_type(&tx);
let tx_declared_deprecated_class_hash = transaction_declared_deprecated_class(&tx);
let gas_vector_computation_mode = super::transaction::gas_vector_computation_mode(&tx);

let mut tx_state = CachedState::<_>::create_transactional(&mut state);
let tx_info = tx.execute(&mut tx_state, &block_context).map_err(|e| {
Expand All @@ -209,11 +215,15 @@ pub fn trace(
})?;
tx_state.commit();

tracing::trace!("Transaction tracing finished");

let trace = to_trace(
tx_type,
tx_info,
state_diff,
block_context.versioned_constants(),
&gas_vector_computation_mode,
block_context.block_info().use_kzg_da,
);
traces.push((hash, trace));
}
Expand Down Expand Up @@ -362,16 +372,33 @@ fn to_trace(
execution_info: blockifier::transaction::objects::TransactionExecutionInfo,
state_diff: StateDiff,
versioned_constants: &VersionedConstants,
gas_vector_computation_mode: &GasVectorComputationMode,
use_kzg_da: bool,
) -> TransactionTrace {
let validate_invocation = execution_info
.validate_call_info
.map(|call_info| FunctionInvocation::from_call_info(call_info, versioned_constants));
let maybe_function_invocation = execution_info
.execute_call_info
.map(|call_info| FunctionInvocation::from_call_info(call_info, versioned_constants));
let fee_transfer_invocation = execution_info
.fee_transfer_call_info
.map(|call_info| FunctionInvocation::from_call_info(call_info, versioned_constants));
let validate_invocation = execution_info.validate_call_info.map(|call_info| {
FunctionInvocation::from_call_info(
call_info,
versioned_constants,
gas_vector_computation_mode,
use_kzg_da,
)
});
let maybe_function_invocation = execution_info.execute_call_info.map(|call_info| {
FunctionInvocation::from_call_info(
call_info,
versioned_constants,
gas_vector_computation_mode,
use_kzg_da,
)
});
let fee_transfer_invocation = execution_info.fee_transfer_call_info.map(|call_info| {
FunctionInvocation::from_call_info(
call_info,
versioned_constants,
gas_vector_computation_mode,
use_kzg_da,
)
});

let computation_resources = validate_invocation
.as_ref()
Expand Down
39 changes: 39 additions & 0 deletions crates/executor/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use blockifier::transaction::objects::HasRelatedFeeType;
use blockifier::transaction::transaction_execution::Transaction;
use pathfinder_common::TransactionHash;
use starknet_api::block::FeeType;
use starknet_api::transaction::fields::GasVectorComputationMode;

use super::felt::IntoFelt;

Expand Down Expand Up @@ -34,3 +35,41 @@ pub fn fee_type(transaction: &Transaction) -> FeeType {
Transaction::L1Handler(tx) => tx.fee_type(),
}
}

pub fn gas_vector_computation_mode(transaction: &Transaction) -> GasVectorComputationMode {
match &transaction {
Transaction::Account(account_transaction) => {
use starknet_api::executable_transaction::AccountTransaction;
match &account_transaction.tx {
AccountTransaction::Declare(tx) => {
use starknet_api::transaction::DeclareTransaction;
match &tx.tx {
DeclareTransaction::V3(tx) => {
tx.resource_bounds.get_gas_vector_computation_mode()
}
_ => GasVectorComputationMode::NoL2Gas,
}
}
AccountTransaction::DeployAccount(tx) => {
use starknet_api::transaction::DeployAccountTransaction;
match &tx.tx {
DeployAccountTransaction::V3(tx) => {
tx.resource_bounds.get_gas_vector_computation_mode()
}
_ => GasVectorComputationMode::NoL2Gas,
}
}
AccountTransaction::Invoke(tx) => {
use starknet_api::transaction::InvokeTransaction;
match &tx.tx {
InvokeTransaction::V3(tx) => {
tx.resource_bounds.get_gas_vector_computation_mode()
}
_ => GasVectorComputationMode::NoL2Gas,
}
}
}
}
Transaction::L1Handler(_) => GasVectorComputationMode::NoL2Gas,
}
}
77 changes: 57 additions & 20 deletions crates/executor/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::{BTreeMap, HashSet};

use blockifier::execution::call_info::OrderedL2ToL1Message;
use blockifier::fee::fee_utils::get_vm_resources_cost;
use blockifier::fee::resources::{StarknetResources, TransactionResources};
use blockifier::transaction::objects::TransactionExecutionInfo;
use pathfinder_common::{
CasmHash,
Expand Down Expand Up @@ -314,16 +314,69 @@ pub struct DataAvailabilityResources {
}

impl FunctionInvocation {
// This estimation purposefully ignores some of the gas costs since we don't
// have all the necessary defails to compute them and those will be taken
// into account only when computing the transaction receipt.
// Ignored costs include state change costs, code size related costs for
// DECLARE, L1 handler payload size and Starknet OS overhead.
fn estimate_gas_consumed(
call_info: &blockifier::execution::call_info::CallInfo,
versioned_constants: &blockifier::versioned_constants::VersionedConstants,
gas_vector_computation_mode: &starknet_api::transaction::fields::GasVectorComputationMode,
use_kzg_da: bool,
) -> GasVector {
let execution_summary = call_info.summarize(versioned_constants);
let sierra_gas = execution_summary.charged_resources.gas_consumed;
let vm_resources = execution_summary
.charged_resources
.vm_resources
.filter_unused_builtins();
let state_changes = blockifier::state::cached_state::StateChanges::default();
let state_resources = blockifier::fee::resources::StateResources::new(
&state_changes,
None,
Default::default(),
);
let starknet_resources =
StarknetResources::new(0, 0, 0, state_resources, None, execution_summary);
let tx_resources = TransactionResources {
starknet_resources,
computation: blockifier::fee::resources::ComputationResources {
vm_resources,
n_reverted_steps: 0,
sierra_gas,
reverted_sierra_gas: 0u64.into(),
},
};
tx_resources.to_gas_vector(versioned_constants, use_kzg_da, gas_vector_computation_mode)
}

pub fn from_call_info(
call_info: blockifier::execution::call_info::CallInfo,
versioned_constants: &blockifier::versioned_constants::VersionedConstants,
gas_vector_computation_mode: &starknet_api::transaction::fields::GasVectorComputationMode,
use_kzg_da: bool,
) -> Self {
let gas_consumed = Self::estimate_gas_consumed(
&call_info,
versioned_constants,
gas_vector_computation_mode,
use_kzg_da,
);

let messages = ordered_l2_to_l1_messages(&call_info);

let internal_calls = call_info
.inner_calls
.into_iter()
.map(|call_info| Self::from_call_info(call_info, versioned_constants))
.map(|call_info| {
Self::from_call_info(
call_info,
versioned_constants,
gas_vector_computation_mode,
use_kzg_da,
)
})
.collect();

let events = call_info
Expand All @@ -341,22 +394,6 @@ impl FunctionInvocation {
.map(IntoFelt::into_felt)
.collect();

let gas_vector = match call_info.tracked_resource {
blockifier::execution::contract_class::TrackedResource::CairoSteps => {
get_vm_resources_cost(
versioned_constants,
&call_info.resources,
0,
&starknet_api::transaction::fields::GasVectorComputationMode::NoL2Gas,
)
}
blockifier::execution::contract_class::TrackedResource::SierraGas => GasVector {
l1_gas: 0u64.into(),
l1_data_gas: 0u64.into(),
l2_gas: call_info.execution.gas_consumed.into(),
},
};

Self {
calldata: call_info
.call
Expand All @@ -382,8 +419,8 @@ impl FunctionInvocation {
result,
computation_resources: call_info.resources.into(),
execution_resources: InnerCallExecutionResources {
l1_gas: gas_vector.l1_gas.0.into(),
l2_gas: gas_vector.l2_gas.0.into(),
l1_gas: gas_consumed.l1_gas.0.into(),
l2_gas: gas_consumed.l2_gas.0.into(),
},
is_reverted: call_info.execution.failed,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rpc/src/method/simulate_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ pub(crate) mod tests {
pedersen_builtin_applications: 7,
..Default::default()
},
execution_resources: pathfinder_executor::types::InnerCallExecutionResources { l1_gas: 4, l2_gas: 0 },
execution_resources: pathfinder_executor::types::InnerCallExecutionResources { l1_gas: 5, l2_gas: 0 },
is_reverted: false,
}
],
Expand Down Expand Up @@ -1350,7 +1350,7 @@ pub(crate) mod tests {
],
computation_resources: universal_deployer_execute_computation_resources(),
execution_resources: pathfinder_executor::types::InnerCallExecutionResources {
l1_gas: 6,
l1_gas: 7,
l2_gas: 0,
},
is_reverted: false,
Expand Down
Loading