From e40c65f3fe1124cd32ba6bd4102e27a91bc3ad7c Mon Sep 17 00:00:00 2001 From: Dori Medini Date: Sat, 5 Oct 2024 01:32:37 +0300 Subject: [PATCH] refactor(blockifier,starknet_api): migrate GasVector from blockifier to starknet_api Signed-off-by: Dori Medini --- Cargo.lock | 1 + crates/blockifier/src/blockifier/block.rs | 16 +-- crates/blockifier/src/context.rs | 3 +- crates/blockifier/src/fee/fee_checks.rs | 3 +- crates/blockifier/src/fee/fee_test.rs | 4 +- crates/blockifier/src/fee/fee_utils.rs | 4 +- crates/blockifier/src/fee/gas_usage.rs | 4 +- crates/blockifier/src/fee/gas_usage_test.rs | 9 +- crates/blockifier/src/fee/receipt.rs | 2 +- crates/blockifier/src/fee/receipt_test.rs | 9 +- crates/blockifier/src/fee/resources.rs | 102 +----------------- crates/blockifier/src/test_utils.rs | 9 +- .../src/transaction/account_transaction.rs | 3 +- .../transaction/account_transactions_test.rs | 4 +- .../src/transaction/execution_flavors_test.rs | 4 +- crates/blockifier/src/transaction/objects.rs | 2 +- .../src/transaction/transactions_test.rs | 6 +- .../src/py_block_executor.rs | 2 +- crates/papyrus_execution/src/objects.rs | 2 +- crates/starknet_api/Cargo.toml | 1 + crates/starknet_api/src/block.rs | 7 ++ .../starknet_api/src/execution_resources.rs | 94 +++++++++++++++- 22 files changed, 137 insertions(+), 154 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d15875ab2..78bc58d1cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10061,6 +10061,7 @@ dependencies = [ "hex", "indexmap 2.2.6", "itertools 0.12.1", + "log", "num-bigint 0.4.5", "pretty_assertions", "primitive-types", diff --git a/crates/blockifier/src/blockifier/block.rs b/crates/blockifier/src/blockifier/block.rs index 43dec39eae..2fa55420ed 100644 --- a/crates/blockifier/src/blockifier/block.rs +++ b/crates/blockifier/src/blockifier/block.rs @@ -1,5 +1,12 @@ use log::warn; -use starknet_api::block::{BlockHash, BlockNumber, BlockTimestamp, GasPrice, NonzeroGasPrice}; +use starknet_api::block::{ + BlockHash, + BlockNumber, + BlockTimestamp, + GasPrice, + GasPricesForFeeType, + NonzeroGasPrice, +}; use starknet_api::core::ContractAddress; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; @@ -31,13 +38,6 @@ pub struct GasPrices { strk_gas_prices: GasPricesForFeeType, // In fri. } -#[derive(Clone, Debug)] -pub struct GasPricesForFeeType { - pub l1_gas_price: NonzeroGasPrice, - pub l1_data_gas_price: NonzeroGasPrice, - pub l2_gas_price: NonzeroGasPrice, -} - impl GasPrices { pub fn new( eth_l1_gas_price: NonzeroGasPrice, diff --git a/crates/blockifier/src/context.rs b/crates/blockifier/src/context.rs index 16d178e7b6..f10aa77863 100644 --- a/crates/blockifier/src/context.rs +++ b/crates/blockifier/src/context.rs @@ -3,10 +3,11 @@ use std::collections::BTreeMap; use papyrus_config::dumping::{append_sub_config_name, ser_param, SerializeConfig}; use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam}; use serde::{Deserialize, Serialize}; +use starknet_api::block::GasPricesForFeeType; use starknet_api::core::{ChainId, ContractAddress}; use starknet_api::transaction::ValidResourceBounds; -use crate::blockifier::block::{BlockInfo, GasPricesForFeeType}; +use crate::blockifier::block::BlockInfo; use crate::bouncer::BouncerConfig; use crate::fee::resources::GasVectorComputationMode; use crate::transaction::objects::{ diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index c0fe124e32..2cd1583520 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -1,4 +1,4 @@ -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::transaction::Resource::{self, L1DataGas, L1Gas, L2Gas}; use starknet_api::transaction::{AllResourceBounds, Fee, ResourceBounds, ValidResourceBounds}; use starknet_types_core::felt::Felt; @@ -7,7 +7,6 @@ use thiserror::Error; use crate::context::TransactionContext; use crate::fee::fee_utils::{get_balance_and_if_covers_fee, get_fee_by_gas_vector}; use crate::fee::receipt::TransactionReceipt; -use crate::fee::resources::GasVector; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::{FeeType, TransactionExecutionResult, TransactionInfo}; diff --git a/crates/blockifier/src/fee/fee_test.rs b/crates/blockifier/src/fee/fee_test.rs index f89ef0ba92..f19c731960 100644 --- a/crates/blockifier/src/fee/fee_test.rs +++ b/crates/blockifier/src/fee/fee_test.rs @@ -5,7 +5,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use rstest::rstest; use starknet_api::block::{GasPrice, NonzeroGasPrice}; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::invoke_tx_args; use starknet_api::transaction::{Fee, Resource, ValidResourceBounds}; @@ -14,7 +14,7 @@ use crate::context::BlockContext; use crate::fee::fee_checks::{FeeCheckError, FeeCheckReportFields, PostExecutionReport}; use crate::fee::fee_utils::get_vm_resources_cost; use crate::fee::receipt::TransactionReceipt; -use crate::fee::resources::{GasVector, GasVectorComputationMode}; +use crate::fee::resources::GasVectorComputationMode; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{ diff --git a/crates/blockifier/src/fee/fee_utils.rs b/crates/blockifier/src/fee/fee_utils.rs index 44db9c5014..77c5826405 100644 --- a/crates/blockifier/src/fee/fee_utils.rs +++ b/crates/blockifier/src/fee/fee_utils.rs @@ -4,7 +4,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use num_bigint::BigUint; use starknet_api::core::ContractAddress; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::state::StorageKey; use starknet_api::transaction::ValidResourceBounds::{AllResources, L1Gas}; use starknet_api::transaction::{AllResourceBounds, Fee, Resource}; @@ -14,7 +14,7 @@ use crate::abi::abi_utils::get_fee_token_var_address; use crate::abi::sierra_types::next_storage_key; use crate::blockifier::block::BlockInfo; use crate::context::{BlockContext, TransactionContext}; -use crate::fee::resources::{GasVector, GasVectorComputationMode, TransactionFeeResult}; +use crate::fee::resources::{GasVectorComputationMode, TransactionFeeResult}; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionFeeError; use crate::transaction::objects::{ExecutionResourcesTraits, FeeType, TransactionInfo}; diff --git a/crates/blockifier/src/fee/gas_usage.rs b/crates/blockifier/src/fee/gas_usage.rs index e04e56af76..0c58eb5521 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -1,11 +1,11 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use super::fee_utils::get_vm_resources_cost; use crate::abi::constants; use crate::context::BlockContext; use crate::fee::eth_gas_constants; -use crate::fee::resources::{GasVector, GasVectorComputationMode}; +use crate::fee::resources::GasVectorComputationMode; use crate::state::cached_state::StateChangesCount; use crate::transaction::account_transaction::AccountTransaction; use crate::utils::u64_from_usize; diff --git a/crates/blockifier/src/fee/gas_usage_test.rs b/crates/blockifier/src/fee/gas_usage_test.rs index 5b2a583568..406dc898ee 100644 --- a/crates/blockifier/src/fee/gas_usage_test.rs +++ b/crates/blockifier/src/fee/gas_usage_test.rs @@ -1,6 +1,6 @@ use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::invoke_tx_args; use starknet_api::transaction::{EventContent, EventData, EventKey}; use starknet_types_core::felt::Felt; @@ -11,12 +11,7 @@ use crate::execution::call_info::{CallExecution, CallInfo, OrderedEvent}; use crate::fee::eth_gas_constants; use crate::fee::fee_utils::get_fee_by_gas_vector; use crate::fee::gas_usage::{get_da_gas_cost, get_message_segment_length}; -use crate::fee::resources::{ - GasVector, - GasVectorComputationMode, - StarknetResources, - StateResources, -}; +use crate::fee::resources::{GasVectorComputationMode, StarknetResources, StateResources}; use crate::state::cached_state::StateChangesCount; use crate::test_utils::{DEFAULT_ETH_L1_DATA_GAS_PRICE, DEFAULT_ETH_L1_GAS_PRICE}; use crate::transaction::objects::FeeType; diff --git a/crates/blockifier/src/fee/receipt.rs b/crates/blockifier/src/fee/receipt.rs index b0b4707c4e..cb17af785c 100644 --- a/crates/blockifier/src/fee/receipt.rs +++ b/crates/blockifier/src/fee/receipt.rs @@ -1,12 +1,12 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::core::ContractAddress; +use starknet_api::execution_resources::GasVector; use starknet_api::transaction::Fee; use crate::context::TransactionContext; use crate::execution::call_info::ExecutionSummary; use crate::fee::resources::{ ComputationResources, - GasVector, StarknetResources, StateResources, TransactionResources, diff --git a/crates/blockifier/src/fee/receipt_test.rs b/crates/blockifier/src/fee/receipt_test.rs index dab0ee10d2..39d0b72084 100644 --- a/crates/blockifier/src/fee/receipt_test.rs +++ b/crates/blockifier/src/fee/receipt_test.rs @@ -1,5 +1,5 @@ use rstest::{fixture, rstest}; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::transaction::L2ToL1Payload; use starknet_api::{invoke_tx_args, nonce}; use starknet_types_core::felt::Felt; @@ -18,12 +18,7 @@ use crate::fee::gas_usage::{ get_log_message_to_l1_emissions_cost, get_message_segment_length, }; -use crate::fee::resources::{ - GasVector, - GasVectorComputationMode, - StarknetResources, - StateResources, -}; +use crate::fee::resources::{GasVectorComputationMode, StarknetResources, StateResources}; use crate::state::cached_state::StateChangesCount; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; diff --git a/crates/blockifier/src/fee/resources.rs b/crates/blockifier/src/fee/resources.rs index 34d71d1904..a7cc2ec9b5 100644 --- a/crates/blockifier/src/fee/resources.rs +++ b/crates/blockifier/src/fee/resources.rs @@ -1,11 +1,7 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; -use serde::Serialize; -use starknet_api::block::GasPrice; use starknet_api::core::ContractAddress; -use starknet_api::execution_resources::GasAmount; -use starknet_api::transaction::Fee; +use starknet_api::execution_resources::{GasAmount, GasVector}; -use crate::blockifier::block::GasPricesForFeeType; use crate::execution::call_info::{EventSummary, ExecutionSummary}; use crate::fee::eth_gas_constants; use crate::fee::fee_utils::get_vm_resources_cost; @@ -295,102 +291,6 @@ impl MessageResources { } } -#[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] -#[derive( - derive_more::Add, - derive_more::Sum, - derive_more::AddAssign, - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - Serialize, -)] -pub struct GasVector { - pub l1_gas: GasAmount, - pub l1_data_gas: GasAmount, - pub l2_gas: GasAmount, -} - -impl GasVector { - pub fn from_l1_gas(l1_gas: GasAmount) -> Self { - Self { l1_gas, ..Default::default() } - } - - pub fn from_l1_data_gas(l1_data_gas: GasAmount) -> Self { - Self { l1_data_gas, ..Default::default() } - } - - pub fn from_l2_gas(l2_gas: GasAmount) -> Self { - Self { l2_gas, ..Default::default() } - } - - /// Computes the cost (in fee token units) of the gas vector (saturating on overflow). - pub fn saturated_cost(&self, gas_price: GasPrice, blob_gas_price: GasPrice) -> Fee { - let l1_gas_cost = self - .l1_gas - .checked_mul(gas_price) - .unwrap_or_else(|| { - log::warn!( - "L1 gas cost overflowed: multiplication of {:?} by {:?} resulted in overflow.", - self.l1_gas, - gas_price - ); - Fee(u128::MAX) - }) - .0; - let l1_data_gas_cost = self - .l1_data_gas - .checked_mul(blob_gas_price) - .unwrap_or_else(|| { - log::warn!( - "L1 blob gas cost overflowed: multiplication of {:?} by {:?} resulted in \ - overflow.", - self.l1_data_gas, - blob_gas_price - ); - Fee(u128::MAX) - }) - .0; - let total = l1_gas_cost.checked_add(l1_data_gas_cost).unwrap_or_else(|| { - log::warn!( - "Total gas cost overflowed: addition of {} and {} resulted in overflow.", - l1_gas_cost, - l1_data_gas_cost - ); - u128::MAX - }); - Fee(total) - } - - /// Compute l1_gas estimation from gas_vector using the following formula: - /// One byte of data costs either 1 data gas (in blob mode) or 16 gas (in calldata - /// mode). For gas price GP and data gas price DGP, the discount for using blobs - /// would be DGP / (16 * GP). - /// X non-data-related gas consumption and Y bytes of data, in non-blob mode, would - /// cost (X + 16*Y) units of gas. Applying the discount ratio to the data-related - /// summand, we get total_gas = (X + Y * DGP / GP). - /// If this function is called with kzg_flag==false, then l1_data_gas==0, and this dicount - /// function does nothing. - pub fn to_discounted_l1_gas(&self, gas_prices: &GasPricesForFeeType) -> GasAmount { - self.l1_gas - + (self.l1_data_gas.nonzero_saturating_mul(gas_prices.l1_data_gas_price)) - .checked_div_ceil(gas_prices.l1_gas_price) - .unwrap_or_else(|| { - log::warn!( - "Discounted L1 gas cost overflowed: division of L1 data gas cost ({:?} * \ - {:?}) by regular L1 gas price ({:?}) resulted in overflow.", - self.l1_data_gas, - gas_prices.l1_data_gas_price, - gas_prices.l1_gas_price - ); - GasAmount::MAX - }) - } -} - #[derive(Debug, PartialEq)] pub enum GasVectorComputationMode { All, diff --git a/crates/blockifier/src/test_utils.rs b/crates/blockifier/src/test_utils.rs index b2216f5610..0623bae312 100644 --- a/crates/blockifier/src/test_utils.rs +++ b/crates/blockifier/src/test_utils.rs @@ -15,7 +15,7 @@ use std::path::PathBuf; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::block::{GasPrice, NonzeroGasPrice}; use starknet_api::core::{ClassHash, ContractAddress, PatriciaKey}; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::state::StorageKey; use starknet_api::transaction::{Calldata, ContractAddressSalt, Fee, TransactionVersion}; use starknet_api::{contract_address, felt, patricia_key}; @@ -26,12 +26,7 @@ use crate::execution::call_info::ExecutionSummary; use crate::execution::deprecated_syscalls::hint_processor::SyscallCounter; use crate::execution::entry_point::CallEntryPoint; use crate::execution::syscalls::SyscallSelector; -use crate::fee::resources::{ - GasVector, - GasVectorComputationMode, - StarknetResources, - StateResources, -}; +use crate::fee::resources::{GasVectorComputationMode, StarknetResources, StateResources}; use crate::test_utils::contracts::FeatureContract; use crate::transaction::transaction_types::TransactionType; use crate::utils::{const_max, u128_from_usize}; diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 3787357d70..ccf83a0d05 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; -use starknet_api::block::GasPrice; +use starknet_api::block::{GasPrice, GasPricesForFeeType}; use starknet_api::calldata; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; @@ -23,7 +23,6 @@ use starknet_api::transaction::{ use starknet_types_core::felt::Felt; use crate::abi::abi_utils::selector_from_name; -use crate::blockifier::block::GasPricesForFeeType; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::{CallInfo, Retdata}; use crate::execution::contract_class::ContractClass; diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 5514dd84a7..53343d99c8 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -6,7 +6,7 @@ use cairo_vm::vm::runners::cairo_runner::ResourceTracker; use pretty_assertions::assert_eq; use rstest::rstest; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, PatriciaKey}; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::hash::StarkHash; use starknet_api::state::StorageKey; use starknet_api::test_utils::invoke::InvokeTxArgs; @@ -49,7 +49,7 @@ use crate::execution::entry_point::EntryPointExecutionContext; use crate::execution::syscalls::SyscallSelector; use crate::fee::fee_utils::{get_fee_by_gas_vector, get_sequencer_balance_keys}; use crate::fee::gas_usage::estimate_minimal_gas_vector; -use crate::fee::resources::{GasVector, GasVectorComputationMode}; +use crate::fee::resources::GasVectorComputationMode; use crate::state::cached_state::{StateChangesCount, TransactionalState}; use crate::state::state_api::{State, StateReader}; use crate::test_utils::contracts::FeatureContract; diff --git a/crates/blockifier/src/transaction/execution_flavors_test.rs b/crates/blockifier/src/transaction/execution_flavors_test.rs index a95c636f78..c0e41dd11b 100644 --- a/crates/blockifier/src/transaction/execution_flavors_test.rs +++ b/crates/blockifier/src/transaction/execution_flavors_test.rs @@ -3,7 +3,7 @@ use pretty_assertions::assert_eq; use rstest::rstest; use starknet_api::block::GasPrice; use starknet_api::core::ContractAddress; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::test_utils::invoke::InvokeTxArgs; use starknet_api::test_utils::NonceManager; use starknet_api::transaction::{ @@ -20,7 +20,7 @@ use starknet_types_core::felt::Felt; use crate::context::{BlockContext, ChainInfo}; use crate::execution::syscalls::SyscallSelector; use crate::fee::fee_utils::get_fee_by_gas_vector; -use crate::fee::resources::{GasVector, GasVectorComputationMode}; +use crate::fee::resources::GasVectorComputationMode; use crate::state::cached_state::CachedState; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; diff --git a/crates/blockifier/src/transaction/objects.rs b/crates/blockifier/src/transaction/objects.rs index 339593bebe..404762e77d 100644 --- a/crates/blockifier/src/transaction/objects.rs +++ b/crates/blockifier/src/transaction/objects.rs @@ -4,6 +4,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; +use starknet_api::execution_resources::GasVector; use starknet_api::transaction::{ signed_tx_version, AccountDeploymentData, @@ -25,7 +26,6 @@ use crate::blockifier::block::BlockInfo; use crate::execution::call_info::{CallInfo, ExecutionSummary}; use crate::fee::fee_utils::get_fee_by_gas_vector; use crate::fee::receipt::TransactionReceipt; -use crate::fee::resources::GasVector; use crate::transaction::errors::{TransactionExecutionError, TransactionPreValidationError}; #[cfg(test)] diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index c54db61ba5..55b86324af 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -8,10 +8,10 @@ use num_bigint::BigUint; use num_traits::Pow; use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; -use starknet_api::block::GasPrice; +use starknet_api::block::{GasPrice, GasPricesForFeeType}; use starknet_api::core::{ChainId, ClassHash, ContractAddress, EthAddress, Nonce, PatriciaKey}; use starknet_api::deprecated_contract_class::EntryPointType; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::state::StorageKey; use starknet_api::test_utils::invoke::InvokeTxArgs; use starknet_api::test_utils::NonceManager; @@ -51,7 +51,6 @@ use crate::abi::abi_utils::{ }; use crate::abi::constants as abi_constants; use crate::abi::sierra_types::next_storage_key; -use crate::blockifier::block::GasPricesForFeeType; use crate::context::{BlockContext, ChainInfo, FeeTokenAddresses, TransactionContext}; use crate::execution::call_info::{ CallExecution, @@ -76,7 +75,6 @@ use crate::fee::gas_usage::{ use crate::fee::receipt::TransactionReceipt; use crate::fee::resources::{ ComputationResources, - GasVector, GasVectorComputationMode, StarknetResources, StateResources, diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index 59538aae36..c7f2ac42d7 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -7,7 +7,6 @@ use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses}; use blockifier::execution::call_info::CallInfo; use blockifier::fee::receipt::TransactionReceipt; -use blockifier::fee::resources::GasVector; use blockifier::state::global_cache::GlobalContractCache; use blockifier::transaction::objects::{ExecutionResourcesTraits, TransactionExecutionInfo}; use blockifier::transaction::transaction_execution::Transaction; @@ -19,6 +18,7 @@ use pyo3::{FromPyObject, PyAny, Python}; use serde::Serialize; use starknet_api::block::BlockNumber; use starknet_api::core::{ChainId, ContractAddress}; +use starknet_api::execution_resources::GasVector; use starknet_api::transaction::Fee; use starknet_types_core::felt::Felt; diff --git a/crates/papyrus_execution/src/objects.rs b/crates/papyrus_execution/src/objects.rs index 9a4029ce2b..b1ca5b8385 100644 --- a/crates/papyrus_execution/src/objects.rs +++ b/crates/papyrus_execution/src/objects.rs @@ -9,7 +9,6 @@ use blockifier::execution::call_info::{ Retdata as BlockifierRetdata, }; use blockifier::execution::entry_point::CallType as BlockifierCallType; -use blockifier::fee::resources::GasVector; use blockifier::transaction::objects::{FeeType, TransactionExecutionInfo}; use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ExecutionResources as VmExecutionResources; @@ -36,6 +35,7 @@ use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::execution_resources::{ Builtin, ExecutionResources, + GasVector, GasVector as StarknetApiGasVector, }; use starknet_api::state::ThinStateDiff; diff --git a/crates/starknet_api/Cargo.toml b/crates/starknet_api/Cargo.toml index 4672191a41..e6fa5200bb 100644 --- a/crates/starknet_api/Cargo.toml +++ b/crates/starknet_api/Cargo.toml @@ -16,6 +16,7 @@ derive_more.workspace = true hex.workspace = true indexmap = { workspace = true, features = ["serde"] } itertools.workspace = true +log.workspace = true num-bigint.workspace = true pretty_assertions.workspace = true primitive-types = { workspace = true, features = ["serde"] } diff --git a/crates/starknet_api/src/block.rs b/crates/starknet_api/src/block.rs index 194ebbb9dd..761e7fe24a 100644 --- a/crates/starknet_api/src/block.rs +++ b/crates/starknet_api/src/block.rs @@ -281,6 +281,13 @@ impl TryFrom for NonzeroGasPrice { } } +#[derive(Clone, Debug)] +pub struct GasPricesForFeeType { + pub l1_gas_price: NonzeroGasPrice, + pub l1_data_gas_price: NonzeroGasPrice, + pub l2_gas_price: NonzeroGasPrice, +} + /// The timestamp of a [Block](`crate::block::Block`). #[derive( Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord, diff --git a/crates/starknet_api/src/execution_resources.rs b/crates/starknet_api/src/execution_resources.rs index 48e3ab45a7..87bf5e9086 100644 --- a/crates/starknet_api/src/execution_resources.rs +++ b/crates/starknet_api/src/execution_resources.rs @@ -4,6 +4,9 @@ use serde::{Deserialize, Serialize}; use starknet_types_core::felt::Felt; use strum_macros::EnumIter; +use crate::block::{GasPrice, GasPricesForFeeType}; +use crate::transaction::Fee; + #[derive( derive_more::Add, derive_more::AddAssign, @@ -32,7 +35,19 @@ impl From for Felt { } } -#[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] +#[derive( + derive_more::Add, + derive_more::Sum, + derive_more::AddAssign, + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + Deserialize, + Serialize, +)] pub struct GasVector { pub l1_gas: GasAmount, pub l1_data_gas: GasAmount, @@ -40,6 +55,83 @@ pub struct GasVector { pub l2_gas: GasAmount, } +impl GasVector { + pub fn from_l1_gas(l1_gas: GasAmount) -> Self { + Self { l1_gas, ..Default::default() } + } + + pub fn from_l1_data_gas(l1_data_gas: GasAmount) -> Self { + Self { l1_data_gas, ..Default::default() } + } + + pub fn from_l2_gas(l2_gas: GasAmount) -> Self { + Self { l2_gas, ..Default::default() } + } + + /// Computes the cost (in fee token units) of the gas vector (saturating on overflow). + pub fn saturated_cost(&self, gas_price: GasPrice, blob_gas_price: GasPrice) -> Fee { + let l1_gas_cost = self + .l1_gas + .checked_mul(gas_price) + .unwrap_or_else(|| { + log::warn!( + "L1 gas cost overflowed: multiplication of {:?} by {:?} resulted in overflow.", + self.l1_gas, + gas_price + ); + Fee(u128::MAX) + }) + .0; + let l1_data_gas_cost = self + .l1_data_gas + .checked_mul(blob_gas_price) + .unwrap_or_else(|| { + log::warn!( + "L1 blob gas cost overflowed: multiplication of {:?} by {:?} resulted in \ + overflow.", + self.l1_data_gas, + blob_gas_price + ); + Fee(u128::MAX) + }) + .0; + let total = l1_gas_cost.checked_add(l1_data_gas_cost).unwrap_or_else(|| { + log::warn!( + "Total gas cost overflowed: addition of {} and {} resulted in overflow.", + l1_gas_cost, + l1_data_gas_cost + ); + u128::MAX + }); + Fee(total) + } + + /// Compute l1_gas estimation from gas_vector using the following formula: + /// One byte of data costs either 1 data gas (in blob mode) or 16 gas (in calldata + /// mode). For gas price GP and data gas price DGP, the discount for using blobs + /// would be DGP / (16 * GP). + /// X non-data-related gas consumption and Y bytes of data, in non-blob mode, would + /// cost (X + 16*Y) units of gas. Applying the discount ratio to the data-related + /// summand, we get total_gas = (X + Y * DGP / GP). + /// If this function is called with kzg_flag==false, then l1_data_gas==0, and this dicount + /// function does nothing. + pub fn to_discounted_l1_gas(&self, gas_prices: &GasPricesForFeeType) -> GasAmount { + self.l1_gas + + (self.l1_data_gas.nonzero_saturating_mul(gas_prices.l1_data_gas_price)) + .checked_div_ceil(gas_prices.l1_gas_price) + .unwrap_or_else(|| { + log::warn!( + "Discounted L1 gas cost overflowed: division of L1 data gas cost ({:?} * \ + {:?}) by regular L1 gas price ({:?}) resulted in overflow.", + self.l1_data_gas, + gas_prices.l1_data_gas_price, + gas_prices.l1_gas_price + ); + GasAmount::MAX + }) + } +} + /// The execution resources used by a transaction. #[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)] pub struct ExecutionResources {