diff --git a/crates/blockifier/src/blockifier/block.rs b/crates/blockifier/src/blockifier/block.rs index 060e17666e3..5d3869a5d80 100644 --- a/crates/blockifier/src/blockifier/block.rs +++ b/crates/blockifier/src/blockifier/block.rs @@ -9,14 +9,16 @@ use crate::abi::constants; use crate::state::errors::StateError; use crate::state::state_api::{State, StateResult}; use crate::transaction::objects::FeeType; -use crate::versioned_constants::ResourceCost; +use crate::versioned_constants::VersionedConstants; #[cfg(test)] #[path = "block_test.rs"] pub mod block_test; -pub const L2_GAS_FOR_CAIRO_STEP: u128 = 100; +// TODO(Aner, 13/08/24): remove these +// pub const L2_GAS_FOR_CAIRO_STEP: u128 = +// VersionedConstants::latest_constants().os_constants.gas_costs; pub const CAIRO_STEPS_PER_L1_GAS: u128 = 400; -pub const L2_TO_L1_GAS_PRICE_RATIO: u128 = L2_GAS_FOR_CAIRO_STEP * CAIRO_STEPS_PER_L1_GAS; +// pub const L2_TO_L1_GAS_PRICE_RATIO: u128 = L2_GAS_FOR_CAIRO_STEP * CAIRO_STEPS_PER_L1_GAS; #[derive(Clone, Debug)] pub struct BlockInfo { @@ -35,8 +37,8 @@ pub struct GasPrices { strk_l1_gas_price: NonZeroU128, // In fri. eth_l1_data_gas_price: NonZeroU128, // In wei. strk_l1_data_gas_price: NonZeroU128, // In fri. - eth_l2_gas_price: ResourceCost, // In wei. - strk_l2_gas_price: ResourceCost, // In fri. + eth_l2_gas_price: NonZeroU128, // In wei. + strk_l2_gas_price: NonZeroU128, // In fri. } impl GasPrices { @@ -45,10 +47,22 @@ impl GasPrices { strk_l1_gas_price: NonZeroU128, eth_l1_data_gas_price: NonZeroU128, strk_l1_data_gas_price: NonZeroU128, + eth_l2_gas_price: NonZeroU128, + strk_l2_gas_price: NonZeroU128, ) -> Self { - let eth_l2_gas_price = ResourceCost::new(eth_l1_gas_price.into(), L2_TO_L1_GAS_PRICE_RATIO); - let strk_l2_gas_price = - ResourceCost::new(strk_l1_gas_price.into(), L2_TO_L1_GAS_PRICE_RATIO); + // TODO(Aner, 13/08/24): remove these asserts + assert_eq!( + eth_l2_gas_price, + VersionedConstants::l1_to_l2_gas_price_conversion(eth_l1_gas_price.into()) + .try_into() + .unwrap() + ); + assert_eq!( + strk_l2_gas_price, + VersionedConstants::l1_to_l2_gas_price_conversion(strk_l1_gas_price.into()) + .try_into() + .unwrap() + ); GasPrices { eth_l1_gas_price, strk_l1_gas_price, @@ -73,7 +87,7 @@ impl GasPrices { } } - pub fn get_l2_gas_price_by_fee_type(&self, fee_type: &FeeType) -> ResourceCost { + pub fn get_l2_gas_price_by_fee_type(&self, fee_type: &FeeType) -> NonZeroU128 { match fee_type { FeeType::Strk => self.strk_l2_gas_price, FeeType::Eth => self.eth_l2_gas_price, diff --git a/crates/blockifier/src/fee/fee_test.rs b/crates/blockifier/src/fee/fee_test.rs index 00cf10cd725..8b96c8d4cfe 100644 --- a/crates/blockifier/src/fee/fee_test.rs +++ b/crates/blockifier/src/fee/fee_test.rs @@ -133,6 +133,10 @@ fn test_discounted_gas_overdraft( gas_price.try_into().unwrap(), DEFAULT_ETH_L1_DATA_GAS_PRICE.try_into().unwrap(), data_gas_price.try_into().unwrap(), + VersionedConstants::l1_to_l2_gas_price_conversion(DEFAULT_ETH_L1_GAS_PRICE) + .try_into() + .unwrap(), + VersionedConstants::l1_to_l2_gas_price_conversion(gas_price).try_into().unwrap(), ); let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index 6b6e83b8593..4f4236efbfb 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -163,6 +163,12 @@ impl BlockInfo { DEFAULT_STRK_L1_GAS_PRICE.try_into().unwrap(), DEFAULT_ETH_L1_DATA_GAS_PRICE.try_into().unwrap(), DEFAULT_STRK_L1_DATA_GAS_PRICE.try_into().unwrap(), + VersionedConstants::l1_to_l2_gas_price_conversion(DEFAULT_ETH_L1_GAS_PRICE) + .try_into() + .unwrap(), + VersionedConstants::l1_to_l2_gas_price_conversion(DEFAULT_STRK_L1_GAS_PRICE) + .try_into() + .unwrap(), ), use_kzg_da: false, } diff --git a/crates/blockifier/src/versioned_constants.rs b/crates/blockifier/src/versioned_constants.rs index a975ab0e98c..3e2c3a988ee 100644 --- a/crates/blockifier/src/versioned_constants.rs +++ b/crates/blockifier/src/versioned_constants.rs @@ -124,6 +124,20 @@ impl VersionedConstants { Self::get(StarknetVersion::Latest) } + /// Converts from l1 gas cost to l2 gas cost with **upward rounding** + pub fn l1_to_l2_gas_price_conversion(l1_gas_price: u128) -> u128 { + let versioned_constants = VersionedConstants::latest_constants(); + let l1_to_l2_gas_price_ratio: Ratio = Ratio::new( + 1, + std::convert::Into::::into( + versioned_constants.os_constants.gas_costs.step_gas_cost, + ), + ) * versioned_constants.vm_resource_fee_cost() + ["n_steps"]; + (l1_gas_price * l1_to_l2_gas_price_ratio.numer()) + .div_ceil(*l1_to_l2_gas_price_ratio.denom()) + } + /// Returns the initial gas of any transaction to run with. pub fn tx_initial_gas(&self) -> u64 { let os_consts = &self.os_constants; diff --git a/crates/gateway/src/rpc_objects.rs b/crates/gateway/src/rpc_objects.rs index d6898d024f8..565ca0e8b85 100644 --- a/crates/gateway/src/rpc_objects.rs +++ b/crates/gateway/src/rpc_objects.rs @@ -74,6 +74,7 @@ pub struct BlockHeader { pub timestamp: BlockTimestamp, pub l1_gas_price: ResourcePrice, pub l1_data_gas_price: ResourcePrice, + pub l2_gas_price: ResourcePrice, pub l1_da_mode: L1DataAvailabilityMode, pub starknet_version: String, } @@ -90,6 +91,8 @@ impl TryInto for BlockHeader { parse_gas_price(self.l1_gas_price.price_in_fri)?, parse_gas_price(self.l1_data_gas_price.price_in_wei)?, parse_gas_price(self.l1_data_gas_price.price_in_fri)?, + parse_gas_price(self.l2_gas_price.price_in_wei)?, + parse_gas_price(self.l2_gas_price.price_in_fri)?, ), use_kzg_da: matches!(self.l1_da_mode, L1DataAvailabilityMode::Blob), }) diff --git a/crates/native_blockifier/src/py_state_diff.rs b/crates/native_blockifier/src/py_state_diff.rs index 634f6baac0b..83df63412d6 100644 --- a/crates/native_blockifier/src/py_state_diff.rs +++ b/crates/native_blockifier/src/py_state_diff.rs @@ -9,6 +9,7 @@ use blockifier::test_utils::{ DEFAULT_STRK_L1_DATA_GAS_PRICE, DEFAULT_STRK_L1_GAS_PRICE, }; +use blockifier::versioned_constants::VersionedConstants; use indexmap::IndexMap; use pyo3::prelude::*; use pyo3::FromPyObject; @@ -140,6 +141,7 @@ pub struct PyBlockInfo { pub block_timestamp: u64, pub l1_gas_price: PyResourcePrice, pub l1_data_gas_price: PyResourcePrice, + pub l2_gas_price: PyResourcePrice, pub sequencer_address: PyFelt, pub use_kzg_da: bool, } @@ -158,6 +160,14 @@ impl Default for PyBlockInfo { price_in_wei: DEFAULT_ETH_L1_DATA_GAS_PRICE, price_in_fri: DEFAULT_STRK_L1_DATA_GAS_PRICE, }, + l2_gas_price: PyResourcePrice { + price_in_wei: VersionedConstants::l1_to_l2_gas_price_conversion( + DEFAULT_ETH_L1_GAS_PRICE, + ), + price_in_fri: VersionedConstants::l1_to_l2_gas_price_conversion( + DEFAULT_STRK_L1_GAS_PRICE, + ), + }, sequencer_address: PyFelt::default(), use_kzg_da: bool::default(), } @@ -201,6 +211,20 @@ impl TryFrom for BlockInfo { ), ) })?, + block_info.l2_gas_price.price_in_wei.try_into().map_err(|_| { + NativeBlockifierInputError::InvalidNativeBlockifierInputError( + InvalidNativeBlockifierInputError::InvalidGasPriceWei( + block_info.l2_gas_price.price_in_wei, + ), + ) + })?, + block_info.l2_gas_price.price_in_fri.try_into().map_err(|_| { + NativeBlockifierInputError::InvalidNativeBlockifierInputError( + InvalidNativeBlockifierInputError::InvalidGasPriceFri( + block_info.l2_gas_price.price_in_fri, + ), + ) + })?, ), use_kzg_da: block_info.use_kzg_da, }) diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index 3094f818206..ff5c2b3a279 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -311,6 +311,7 @@ fn create_block_context( block_timestamp, l1_gas_price, l1_data_gas_price, + l2_gas_price, sequencer_address, l1_da_mode, ) = match maybe_pending_data { @@ -319,6 +320,7 @@ fn create_block_context( pending_data.timestamp, pending_data.l1_gas_price, pending_data.l1_data_gas_price, + pending_data.l2_gas_price, pending_data.sequencer, pending_data.l1_da_mode, ), @@ -332,6 +334,7 @@ fn create_block_context( header.timestamp, header.l1_gas_price, header.l1_data_gas_price, + header.l2_gas_price, header.sequencer, header.l1_da_mode, ) @@ -359,6 +362,8 @@ fn create_block_context( NonZeroU128::new(l1_gas_price.price_in_fri.0).unwrap_or(NonZeroU128::MIN), NonZeroU128::new(l1_data_gas_price.price_in_wei.0).unwrap_or(NonZeroU128::MIN), NonZeroU128::new(l1_data_gas_price.price_in_fri.0).unwrap_or(NonZeroU128::MIN), + NonZeroU128::new(l2_gas_price.price_in_wei.0).unwrap_or(NonZeroU128::MIN), + NonZeroU128::new(l2_gas_price.price_in_fri.0).unwrap_or(NonZeroU128::MIN), ), }; let chain_info = ChainInfo { diff --git a/crates/papyrus_execution/src/objects.rs b/crates/papyrus_execution/src/objects.rs index 8ded97a7d5e..a9b969cfb36 100644 --- a/crates/papyrus_execution/src/objects.rs +++ b/crates/papyrus_execution/src/objects.rs @@ -506,10 +506,12 @@ pub struct PendingData { pub replaced_classes: Vec, /// The timestamp of the pending block. pub timestamp: BlockTimestamp, - /// The gas price of the pending block. + /// The l1 gas price of the pending block. pub l1_gas_price: GasPricePerToken, /// The data price of the pending block. pub l1_data_gas_price: GasPricePerToken, + /// The l2 gas price of the pending block. + pub l2_gas_price: GasPricePerToken, /// The data availability mode of the pending block. pub l1_da_mode: L1DataAvailabilityMode, /// The sequencer address of the pending block. diff --git a/crates/papyrus_protobuf/src/converters/header.rs b/crates/papyrus_protobuf/src/converters/header.rs index d5175c7df14..9a4c65d18ea 100644 --- a/crates/papyrus_protobuf/src/converters/header.rs +++ b/crates/papyrus_protobuf/src/converters/header.rs @@ -176,6 +176,25 @@ impl TryFrom for SignedBlockHeader { ), }; + let l2_gas_price = GasPricePerToken { + price_in_fri: GasPrice( + value + .l2_gas_price_fri + .ok_or(ProtobufConversionError::MissingField { + field_description: "SignedBlockHeader::gas_price_fri", + })? + .into(), + ), + price_in_wei: GasPrice( + value + .l2_gas_price_wei + .ok_or(ProtobufConversionError::MissingField { + field_description: "SignedBlockHeader::gas_price_wei", + })? + .into(), + ), + }; + let receipt_commitment = value .receipts .map(|receipts| receipts.try_into().map(ReceiptCommitment)) @@ -198,6 +217,7 @@ impl TryFrom for SignedBlockHeader { block_number: BlockNumber(value.number), l1_gas_price, l1_data_gas_price, + l2_gas_price, state_root, sequencer, timestamp, @@ -264,6 +284,8 @@ impl From<(BlockHeader, Vec)> for protobuf::SignedBlockHeader { gas_price_fri: Some(header.l1_gas_price.price_in_fri.0.into()), data_gas_price_wei: Some(header.l1_data_gas_price.price_in_wei.0.into()), data_gas_price_fri: Some(header.l1_data_gas_price.price_in_fri.0.into()), + l2_gas_price_wei: Some(header.l2_gas_price.price_in_wei.0.into()), + l2_gas_price_fri: Some(header.l2_gas_price.price_in_fri.0.into()), l1_data_availability_mode: l1_data_availability_mode_to_enum_int(header.l1_da_mode), signatures: signatures.iter().map(|signature| (*signature).into()).collect(), } diff --git a/crates/papyrus_rpc/src/pending.rs b/crates/papyrus_rpc/src/pending.rs index 38118b84533..34b3e228362 100644 --- a/crates/papyrus_rpc/src/pending.rs +++ b/crates/papyrus_rpc/src/pending.rs @@ -17,6 +17,7 @@ pub(crate) fn client_pending_data_to_execution_pending_data( timestamp: client_pending_data.block.timestamp(), l1_gas_price: client_pending_data.block.l1_gas_price(), l1_data_gas_price: client_pending_data.block.l1_data_gas_price(), + l2_gas_price: client_pending_data.block.l2_gas_price(), l1_da_mode: client_pending_data.block.l1_da_mode(), sequencer: client_pending_data.block.sequencer_address(), } diff --git a/crates/papyrus_rpc/src/v0_6/api/api_impl.rs b/crates/papyrus_rpc/src/v0_6/api/api_impl.rs index 8a91b6aad83..f271362432d 100644 --- a/crates/papyrus_rpc/src/v0_6/api/api_impl.rs +++ b/crates/papyrus_rpc/src/v0_6/api/api_impl.rs @@ -1158,6 +1158,7 @@ impl JsonRpcServer for JsonRpcServerImpl { timestamp: pending_block.timestamp(), l1_gas_price: pending_block.l1_gas_price(), l1_data_gas_price: pending_block.l1_data_gas_price(), + l2_gas_price: pending_block.l2_gas_price(), sequencer: pending_block.sequencer_address(), // The pending state diff should be empty since we look at the state in the // start of the pending block. @@ -1276,6 +1277,7 @@ impl JsonRpcServer for JsonRpcServerImpl { timestamp: client_pending_data.block.timestamp(), l1_gas_price: client_pending_data.block.l1_gas_price(), l1_data_gas_price: client_pending_data.block.l1_data_gas_price(), + l2_gas_price: client_pending_data.block.l2_gas_price(), sequencer: client_pending_data.block.sequencer_address(), // The pending state diff should be empty since we look at the state in the // start of the pending block. diff --git a/crates/papyrus_rpc/src/v0_7/api/api_impl.rs b/crates/papyrus_rpc/src/v0_7/api/api_impl.rs index fc503f168c4..7a4b9012567 100644 --- a/crates/papyrus_rpc/src/v0_7/api/api_impl.rs +++ b/crates/papyrus_rpc/src/v0_7/api/api_impl.rs @@ -1143,6 +1143,7 @@ impl JsonRpcServer for JsonRpcServerImpl { timestamp: pending_block.timestamp(), l1_gas_price: pending_block.l1_gas_price(), l1_data_gas_price: pending_block.l1_data_gas_price(), + l2_gas_price: pending_block.l2_gas_price(), l1_da_mode: pending_block.l1_da_mode(), sequencer: pending_block.sequencer_address(), // The pending state diff should be empty since we look at the state in the @@ -1259,6 +1260,7 @@ impl JsonRpcServer for JsonRpcServerImpl { timestamp: client_pending_data.block.timestamp(), l1_gas_price: client_pending_data.block.l1_gas_price(), l1_data_gas_price: client_pending_data.block.l1_data_gas_price(), + l2_gas_price: client_pending_data.block.l2_gas_price(), l1_da_mode: client_pending_data.block.l1_da_mode(), sequencer: client_pending_data.block.sequencer_address(), // The pending state diff should be empty since we look at the state in the diff --git a/crates/papyrus_storage/src/header.rs b/crates/papyrus_storage/src/header.rs index 6944c333426..675874d30f0 100644 --- a/crates/papyrus_storage/src/header.rs +++ b/crates/papyrus_storage/src/header.rs @@ -71,6 +71,7 @@ pub(crate) struct StorageBlockHeader { pub block_number: BlockNumber, pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub state_root: GlobalRoot, pub sequencer: SequencerContractAddress, pub timestamp: BlockTimestamp, @@ -169,6 +170,7 @@ impl<'env, Mode: TransactionKind> HeaderStorageReader for StorageTxn<'env, Mode> block_number: block_header.block_number, l1_gas_price: block_header.l1_gas_price, l1_data_gas_price: block_header.l1_data_gas_price, + l2_gas_price: block_header.l2_gas_price, state_root: block_header.state_root, sequencer: block_header.sequencer, timestamp: block_header.timestamp, @@ -247,6 +249,7 @@ impl<'env> HeaderStorageWriter for StorageTxn<'env, RW> { block_number: block_header.block_number, l1_gas_price: block_header.l1_gas_price, l1_data_gas_price: block_header.l1_data_gas_price, + l2_gas_price: block_header.l2_gas_price, state_root: block_header.state_root, sequencer: block_header.sequencer, timestamp: block_header.timestamp, @@ -353,6 +356,7 @@ impl<'env> HeaderStorageWriter for StorageTxn<'env, RW> { block_number: reverted_header.block_number, l1_gas_price: reverted_header.l1_gas_price, l1_data_gas_price: reverted_header.l1_data_gas_price, + l2_gas_price: reverted_header.l2_gas_price, state_root: reverted_header.state_root, sequencer: reverted_header.sequencer, timestamp: reverted_header.timestamp, diff --git a/crates/papyrus_storage/src/serialization/serializers.rs b/crates/papyrus_storage/src/serialization/serializers.rs index c259ee3426c..9cd12b0df40 100644 --- a/crates/papyrus_storage/src/serialization/serializers.rs +++ b/crates/papyrus_storage/src/serialization/serializers.rs @@ -156,6 +156,7 @@ auto_storage_serde! { pub block_number: BlockNumber, pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub state_root: GlobalRoot, pub sequencer: SequencerContractAddress, pub timestamp: BlockTimestamp, diff --git a/crates/papyrus_storage/src/test_instances.rs b/crates/papyrus_storage/src/test_instances.rs index 70edfec51e1..583ce74f92d 100644 --- a/crates/papyrus_storage/src/test_instances.rs +++ b/crates/papyrus_storage/src/test_instances.rs @@ -30,6 +30,7 @@ auto_impl_get_test_instance! { pub block_number: BlockNumber, pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub state_root: GlobalRoot, pub sequencer: SequencerContractAddress, pub timestamp: BlockTimestamp, diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index 513dafac6a7..f6014f805a1 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -429,6 +429,7 @@ auto_impl_get_test_instance! { pub block_number: BlockNumber, pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub state_root: GlobalRoot, pub sequencer: SequencerContractAddress, pub timestamp: BlockTimestamp, diff --git a/crates/starknet_api/src/block.rs b/crates/starknet_api/src/block.rs index 26729420fc4..7101f8f977a 100644 --- a/crates/starknet_api/src/block.rs +++ b/crates/starknet_api/src/block.rs @@ -58,6 +58,7 @@ pub struct BlockHeader { pub block_number: BlockNumber, pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub state_root: GlobalRoot, pub sequencer: SequencerContractAddress, pub timestamp: BlockTimestamp, diff --git a/crates/starknet_client/src/reader/objects/block.rs b/crates/starknet_client/src/reader/objects/block.rs index fdda5eceaa6..b2c86dfb6a0 100644 --- a/crates/starknet_client/src/reader/objects/block.rs +++ b/crates/starknet_client/src/reader/objects/block.rs @@ -58,6 +58,7 @@ pub struct BlockPostV0_13_1 { // Replacing the eth_l1_gas_price & strk_l1_gas_price fields with a single field. pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub transaction_commitment: TransactionCommitment, pub event_commitment: EventCommitment, // Additions to the block structure in V0.13.2. These additions do not appear in older blocks @@ -195,6 +196,12 @@ impl Block { } } + pub fn l2_gas_price(&self) -> GasPricePerToken { + match self { + Block::PostV0_13_1(block) => block.l2_gas_price, + } + } + pub fn state_root(&self) -> GlobalRoot { match self { Block::PostV0_13_1(block) => block.state_root, @@ -297,6 +304,7 @@ impl Block { sequencer: self.sequencer_address(), timestamp: self.timestamp(), l1_data_gas_price: self.l1_data_gas_price(), + l2_gas_price: self.l2_gas_price(), l1_da_mode: self.l1_da_mode(), state_diff_commitment: self.state_diff_commitment(), transaction_commitment, diff --git a/crates/starknet_client/src/reader/objects/pending_data.rs b/crates/starknet_client/src/reader/objects/pending_data.rs index f611da26615..f2c0fd14c85 100644 --- a/crates/starknet_client/src/reader/objects/pending_data.rs +++ b/crates/starknet_client/src/reader/objects/pending_data.rs @@ -159,6 +159,13 @@ impl PendingBlockOrDeprecated { PendingBlockOrDeprecated::Current(block) => block.l1_data_gas_price, } } + pub fn l2_gas_price(&self) -> GasPricePerToken { + match self { + // In older versions, data gas price was 0. + PendingBlockOrDeprecated::Deprecated(_) => GasPricePerToken::default(), + PendingBlockOrDeprecated::Current(block) => block.l2_gas_price, + } + } pub fn l1_da_mode(&self) -> L1DataAvailabilityMode { match self { // In older versions, all blocks were using calldata. @@ -196,6 +203,7 @@ pub struct PendingBlock { pub status: BlockStatus, pub l1_gas_price: GasPricePerToken, pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, pub transactions: Vec, pub timestamp: BlockTimestamp, pub sequencer_address: SequencerContractAddress,