From cfbcc11be0826e8c55fafa84ae01b2aead25d127 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 21 Oct 2024 13:04:29 +0300 Subject: [PATCH] refactor: Refactor fee-related types (#3121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - Moves basic logic for fee types close to the type declaration (i.e., to `zksync_types`). - Unifies `PubdataSendingMode` and `PubdataDA`. - Removes dependency of `zksync_types` on `zksync_config`. ## Why ❔ This allows external apps depending on fee types (e.g., the test node) to not have behemoths like `zksync_dal` in their dependency graph. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- Cargo.lock | 4 - core/bin/zksync_server/src/node_builder.rs | 10 +- core/lib/basic_types/src/lib.rs | 1 + .../{types => basic_types}/src/pubdata_da.rs | 23 +- core/lib/config/src/configs/eth_sender.rs | 11 +- core/lib/config/src/testonly.rs | 15 +- core/lib/env_config/src/eth_sender.rs | 3 +- .../src/i_executor/methods/commit_batches.rs | 4 +- .../structures/commit_batch_info.rs | 18 +- core/lib/protobuf_config/src/eth.rs | 23 +- core/lib/types/Cargo.toml | 3 +- core/lib/types/src/fee_model.rs | 463 +++++++++++++++++- core/lib/types/src/lib.rs | 1 - core/node/api_server/src/testonly.rs | 7 +- core/node/api_server/src/web3/tests/mod.rs | 7 +- core/node/consistency_checker/src/lib.rs | 14 +- .../node/consistency_checker/src/tests/mod.rs | 4 +- .../eth_sender/src/aggregated_operations.rs | 8 +- core/node/eth_sender/src/aggregator.rs | 9 +- core/node/eth_sender/src/eth_tx_aggregator.rs | 13 +- core/node/eth_sender/src/publish_criterion.rs | 4 +- core/node/eth_sender/src/tester.rs | 8 +- core/node/fee_model/Cargo.toml | 2 - .../src/l1_gas_price/gas_adjuster/mod.rs | 7 +- .../src/l1_gas_price/gas_adjuster/tests.rs | 6 +- core/node/fee_model/src/lib.rs | 459 +---------------- .../implementations/layers/gas_adjuster.rs | 3 +- .../src/implementations/layers/l1_gas.rs | 28 +- core/node/state_keeper/src/io/tests/tester.rs | 3 +- prover/Cargo.lock | 2 - zkstack_cli/Cargo.lock | 2 - 31 files changed, 564 insertions(+), 601 deletions(-) rename core/lib/{types => basic_types}/src/pubdata_da.rs (54%) diff --git a/Cargo.lock b/Cargo.lock index a5e51346bdf4..5da4cc8c1439 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10645,7 +10645,6 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "bigdecimal", "test-casing", "tokio", "tracing", @@ -10654,7 +10653,6 @@ dependencies = [ "zksync_dal", "zksync_eth_client", "zksync_types", - "zksync_utils", "zksync_web3_decl", ] @@ -11235,7 +11233,6 @@ dependencies = [ "once_cell", "prost 0.12.6", "rlp", - "secp256k1", "serde", "serde_json", "serde_with", @@ -11244,7 +11241,6 @@ dependencies = [ "tokio", "tracing", "zksync_basic_types", - "zksync_config", "zksync_contracts", "zksync_crypto_primitives", "zksync_mini_merkle_tree", diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index c87bf3ce2dda..234e22894240 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -4,8 +4,8 @@ use anyhow::Context; use zksync_config::{ configs::{ - da_client::DAClientConfig, eth_sender::PubdataSendingMode, - secrets::DataAvailabilitySecrets, wallets::Wallets, GeneralConfig, Secrets, + da_client::DAClientConfig, secrets::DataAvailabilitySecrets, wallets::Wallets, + GeneralConfig, Secrets, }, ContractsConfig, GenesisConfig, }; @@ -69,7 +69,9 @@ use zksync_node_framework::{ }, service::{ZkStackService, ZkStackServiceBuilder}, }; -use zksync_types::{settlement::SettlementMode, SHARED_BRIDGE_ETHER_TOKEN_ADDRESS}; +use zksync_types::{ + pubdata_da::PubdataSendingMode, settlement::SettlementMode, SHARED_BRIDGE_ETHER_TOKEN_ADDRESS, +}; use zksync_vlog::prometheus::PrometheusExporterConfig; /// Macro that looks into a path to fetch an optional config, @@ -189,7 +191,7 @@ impl MainNodeBuilder { .add_layer(BaseTokenRatioProviderLayer::new(base_token_adjuster_config)); } let state_keeper_config = try_load_config!(self.configs.state_keeper_config); - let l1_gas_layer = L1GasLayer::new(state_keeper_config); + let l1_gas_layer = L1GasLayer::new(&state_keeper_config); self.node.add_layer(l1_gas_layer); Ok(self) } diff --git a/core/lib/basic_types/src/lib.rs b/core/lib/basic_types/src/lib.rs index 197bd8eb7aa2..79c7b3924e34 100644 --- a/core/lib/basic_types/src/lib.rs +++ b/core/lib/basic_types/src/lib.rs @@ -29,6 +29,7 @@ pub mod commitment; pub mod network; pub mod protocol_version; pub mod prover_dal; +pub mod pubdata_da; pub mod seed_phrase; pub mod settlement; pub mod tee_types; diff --git a/core/lib/types/src/pubdata_da.rs b/core/lib/basic_types/src/pubdata_da.rs similarity index 54% rename from core/lib/types/src/pubdata_da.rs rename to core/lib/basic_types/src/pubdata_da.rs index bc7dc55e53de..3f042da98ac1 100644 --- a/core/lib/types/src/pubdata_da.rs +++ b/core/lib/basic_types/src/pubdata_da.rs @@ -1,15 +1,17 @@ +//! Types related to data availability. + use chrono::{DateTime, Utc}; use num_enum::TryFromPrimitive; use serde::{Deserialize, Serialize}; -use zksync_basic_types::L1BatchNumber; -use zksync_config::configs::eth_sender::PubdataSendingMode; + +use crate::L1BatchNumber; /// Enum holding the current values used for DA Layers. #[repr(u8)] -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[derive(TryFromPrimitive)] -pub enum PubdataDA { +#[derive(Debug, Clone, Copy, Default, PartialEq, Deserialize, Serialize, TryFromPrimitive)] +pub enum PubdataSendingMode { /// Pubdata is sent to the L1 as a tx calldata. + #[default] Calldata = 0, /// Pubdata is sent to L1 as EIP-4844 blobs. Blobs, @@ -19,17 +21,6 @@ pub enum PubdataDA { RelayedL2Calldata, } -impl From for PubdataDA { - fn from(value: PubdataSendingMode) -> Self { - match value { - PubdataSendingMode::Calldata => PubdataDA::Calldata, - PubdataSendingMode::Blobs => PubdataDA::Blobs, - PubdataSendingMode::Custom => PubdataDA::Custom, - PubdataSendingMode::RelayedL2Calldata => PubdataDA::RelayedL2Calldata, - } - } -} - /// Represents a blob in the data availability layer. #[derive(Debug, Clone)] pub struct DataAvailabilityBlob { diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 3a1a0505728c..7b67f015238d 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -2,7 +2,7 @@ use std::time::Duration; use anyhow::Context as _; use serde::Deserialize; -use zksync_basic_types::{settlement::SettlementMode, H256}; +use zksync_basic_types::{pubdata_da::PubdataSendingMode, settlement::SettlementMode, H256}; use zksync_crypto_primitives::K256PrivateKey; use crate::EthWatchConfig; @@ -80,15 +80,6 @@ pub enum ProofLoadingMode { FriProofFromGcs, } -#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Default)] -pub enum PubdataSendingMode { - #[default] - Calldata, - Blobs, - Custom, - RelayedL2Calldata, -} - #[derive(Debug, Deserialize, Clone, PartialEq)] pub struct SenderConfig { pub aggregated_proof_sizes: Vec, diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 0fdd927d19f0..9b1ec13e2d2e 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -7,6 +7,7 @@ use zksync_basic_types::{ commitment::L1BatchCommitmentMode, network::Network, protocol_version::{ProtocolSemanticVersion, ProtocolVersionId, VersionPatch}, + pubdata_da::PubdataSendingMode, seed_phrase::SeedPhrase, vm::FastVmMode, L1BatchNumber, L1ChainId, L2ChainId, @@ -16,8 +17,7 @@ use zksync_crypto_primitives::K256PrivateKey; use crate::{ configs::{ - self, da_client::DAClientConfig::Avail, eth_sender::PubdataSendingMode, - external_price_api_client::ForcedPriceClientConfig, + self, da_client::DAClientConfig::Avail, external_price_api_client::ForcedPriceClientConfig, }, AvailConfig, }; @@ -388,17 +388,6 @@ impl Distribution for EncodeDist { } } -impl Distribution for EncodeDist { - fn sample(&self, rng: &mut R) -> configs::eth_sender::PubdataSendingMode { - type T = configs::eth_sender::PubdataSendingMode; - match rng.gen_range(0..3) { - 0 => T::Calldata, - 1 => T::Blobs, - _ => T::Custom, - } - } -} - impl Distribution for EncodeDist { fn sample(&self, rng: &mut R) -> configs::eth_sender::SenderConfig { configs::eth_sender::SenderConfig { diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index e5132eb7d91f..0fd61fd173b6 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -41,7 +41,8 @@ impl FromEnv for GasAdjusterConfig { #[cfg(test)] mod tests { - use zksync_config::configs::eth_sender::{ProofSendingMode, PubdataSendingMode}; + use zksync_basic_types::pubdata_da::PubdataSendingMode; + use zksync_config::configs::eth_sender::ProofSendingMode; use super::*; use crate::test_utils::{hash, EnvMutex}; diff --git a/core/lib/l1_contract_interface/src/i_executor/methods/commit_batches.rs b/core/lib/l1_contract_interface/src/i_executor/methods/commit_batches.rs index 883804f0bd6f..67819f7d7ccd 100644 --- a/core/lib/l1_contract_interface/src/i_executor/methods/commit_batches.rs +++ b/core/lib/l1_contract_interface/src/i_executor/methods/commit_batches.rs @@ -1,7 +1,7 @@ use zksync_types::{ commitment::{L1BatchCommitmentMode, L1BatchWithMetadata}, ethabi::Token, - pubdata_da::PubdataDA, + pubdata_da::PubdataSendingMode, }; use crate::{ @@ -14,7 +14,7 @@ use crate::{ pub struct CommitBatches<'a> { pub last_committed_l1_batch: &'a L1BatchWithMetadata, pub l1_batches: &'a [L1BatchWithMetadata], - pub pubdata_da: PubdataDA, + pub pubdata_da: PubdataSendingMode, pub mode: L1BatchCommitmentMode, } diff --git a/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs b/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs index 179c04748d3b..6438aeb7f55c 100644 --- a/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs +++ b/core/lib/l1_contract_interface/src/i_executor/structures/commit_batch_info.rs @@ -4,7 +4,7 @@ use zksync_types::{ L1BatchWithMetadata, }, ethabi::Token, - pubdata_da::PubdataDA, + pubdata_da::PubdataSendingMode, web3::contract::Error as ContractError, ProtocolVersionId, U256, }; @@ -24,14 +24,14 @@ const PUBDATA_SOURCE_CUSTOM: u8 = 2; pub struct CommitBatchInfo<'a> { mode: L1BatchCommitmentMode, l1_batch_with_metadata: &'a L1BatchWithMetadata, - pubdata_da: PubdataDA, + pubdata_da: PubdataSendingMode, } impl<'a> CommitBatchInfo<'a> { pub fn new( mode: L1BatchCommitmentMode, l1_batch_with_metadata: &'a L1BatchWithMetadata, - pubdata_da: PubdataDA, + pubdata_da: PubdataSendingMode, ) -> Self { Self { mode, @@ -204,24 +204,24 @@ impl Tokenizable for CommitBatchInfo<'_> { // Here we're not pushing any pubdata on purpose; no pubdata is sent in Validium mode. ( L1BatchCommitmentMode::Validium, - PubdataDA::Calldata | PubdataDA::RelayedL2Calldata, + PubdataSendingMode::Calldata | PubdataSendingMode::RelayedL2Calldata, ) => { vec![PUBDATA_SOURCE_CALLDATA] } - (L1BatchCommitmentMode::Validium, PubdataDA::Blobs) => { + (L1BatchCommitmentMode::Validium, PubdataSendingMode::Blobs) => { vec![PUBDATA_SOURCE_BLOBS] } - (L1BatchCommitmentMode::Rollup, PubdataDA::Custom) => { + (L1BatchCommitmentMode::Rollup, PubdataSendingMode::Custom) => { panic!("Custom pubdata DA is incompatible with Rollup mode") } - (L1BatchCommitmentMode::Validium, PubdataDA::Custom) => { + (L1BatchCommitmentMode::Validium, PubdataSendingMode::Custom) => { vec![PUBDATA_SOURCE_CUSTOM] } ( L1BatchCommitmentMode::Rollup, - PubdataDA::Calldata | PubdataDA::RelayedL2Calldata, + PubdataSendingMode::Calldata | PubdataSendingMode::RelayedL2Calldata, ) => { // We compute and add the blob commitment to the pubdata payload so that we can verify the proof // even if we are not using blobs. @@ -232,7 +232,7 @@ impl Tokenizable for CommitBatchInfo<'_> { .chain(blob_commitment) .collect() } - (L1BatchCommitmentMode::Rollup, PubdataDA::Blobs) => { + (L1BatchCommitmentMode::Rollup, PubdataSendingMode::Blobs) => { let pubdata = self.pubdata_input(); let pubdata_commitments = pubdata.chunks(ZK_SYNC_BYTES_PER_BLOB).flat_map(|blob| { diff --git a/core/lib/protobuf_config/src/eth.rs b/core/lib/protobuf_config/src/eth.rs index c1d95bd30d2b..d4ea1d9f2697 100644 --- a/core/lib/protobuf_config/src/eth.rs +++ b/core/lib/protobuf_config/src/eth.rs @@ -1,6 +1,7 @@ use anyhow::Context as _; use zksync_config::configs::{self}; use zksync_protobuf::{required, ProtoRepr}; +use zksync_types::pubdata_da::PubdataSendingMode; use crate::{proto::eth as proto, read_optional_repr}; @@ -25,23 +26,21 @@ impl proto::ProofSendingMode { } impl proto::PubdataSendingMode { - fn new(x: &configs::eth_sender::PubdataSendingMode) -> Self { - use configs::eth_sender::PubdataSendingMode as From; + fn new(x: &PubdataSendingMode) -> Self { match x { - From::Calldata => Self::Calldata, - From::Blobs => Self::Blobs, - From::Custom => Self::Custom, - From::RelayedL2Calldata => Self::RelayedL2Calldata, + PubdataSendingMode::Calldata => Self::Calldata, + PubdataSendingMode::Blobs => Self::Blobs, + PubdataSendingMode::Custom => Self::Custom, + PubdataSendingMode::RelayedL2Calldata => Self::RelayedL2Calldata, } } - fn parse(&self) -> configs::eth_sender::PubdataSendingMode { - use configs::eth_sender::PubdataSendingMode as To; + fn parse(&self) -> PubdataSendingMode { match self { - Self::Calldata => To::Calldata, - Self::Blobs => To::Blobs, - Self::Custom => To::Custom, - Self::RelayedL2Calldata => To::RelayedL2Calldata, + Self::Calldata => PubdataSendingMode::Calldata, + Self::Blobs => PubdataSendingMode::Blobs, + Self::Custom => PubdataSendingMode::Custom, + Self::RelayedL2Calldata => PubdataSendingMode::RelayedL2Calldata, } } } diff --git a/core/lib/types/Cargo.toml b/core/lib/types/Cargo.toml index 54c38384a7ad..ffa9d219f084 100644 --- a/core/lib/types/Cargo.toml +++ b/core/lib/types/Cargo.toml @@ -11,12 +11,12 @@ keywords.workspace = true categories.workspace = true [dependencies] +# **IMPORTANT.** Please do not add dependency on `zksync_config` etc. This crate has a heavy dependency graph as is. zksync_system_constants.workspace = true zksync_utils.workspace = true zksync_basic_types.workspace = true zksync_contracts.workspace = true zksync_mini_merkle_tree.workspace = true -zksync_config.workspace = true zksync_protobuf.workspace = true zksync_crypto_primitives.workspace = true @@ -39,7 +39,6 @@ itertools.workspace = true tracing.workspace = true # Crypto stuff -secp256k1.workspace = true blake2.workspace = true [dev-dependencies] diff --git a/core/lib/types/src/fee_model.rs b/core/lib/types/src/fee_model.rs index b59aa65b04e0..ae346656ea6f 100644 --- a/core/lib/types/src/fee_model.rs +++ b/core/lib/types/src/fee_model.rs @@ -1,11 +1,13 @@ +// FIXME: separate crate together with node_fee_model interfaces? + use std::num::NonZeroU64; use bigdecimal::{BigDecimal, ToPrimitive}; use serde::{Deserialize, Serialize}; -use zksync_config::configs::chain::{FeeModelVersion, StateKeeperConfig}; use zksync_system_constants::L1_GAS_PER_PUBDATA_BYTE; +use zksync_utils::ceil_div_u256; -use crate::ProtocolVersionId; +use crate::{ProtocolVersionId, U256}; /// Fee input to be provided into the VM. It contains two options: /// - `L1Pegged`: L1 gas price is provided to the VM, and the pubdata price is derived from it. Using this option is required for the @@ -203,6 +205,7 @@ pub struct FeeModelConfigV2 { /// The maximum amount of pubdata that can be used by the batch. Note that if the calldata is used as pubdata, this variable should not exceed 128kb. pub max_pubdata_per_batch: u64, } + impl Default for FeeModelConfig { /// Config with all zeroes is not a valid config (since for instance having 0 max gas per batch may incur division by zero), /// so we implement a sensible default config here. @@ -213,24 +216,6 @@ impl Default for FeeModelConfig { } } -impl FeeModelConfig { - pub fn from_state_keeper_config(state_keeper_config: &StateKeeperConfig) -> Self { - match state_keeper_config.fee_model_version { - FeeModelVersion::V1 => Self::V1(FeeModelConfigV1 { - minimal_l2_gas_price: state_keeper_config.minimal_l2_gas_price, - }), - FeeModelVersion::V2 => Self::V2(FeeModelConfigV2 { - minimal_l2_gas_price: state_keeper_config.minimal_l2_gas_price, - compute_overhead_part: state_keeper_config.compute_overhead_part, - pubdata_overhead_part: state_keeper_config.pubdata_overhead_part, - batch_overhead_l1_gas: state_keeper_config.batch_overhead_l1_gas, - max_gas_per_batch: state_keeper_config.max_gas_per_batch, - max_pubdata_per_batch: state_keeper_config.max_pubdata_per_batch, - }), - } - } -} - #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct FeeParamsV1 { pub config: FeeModelConfigV1, @@ -337,4 +322,442 @@ impl FeeParams { l1_gas_price: 1_000_000_000, }) } + + /// Provides scaled [`BatchFeeInput`] based on these parameters. + pub fn scale( + self, + l1_gas_price_scale_factor: f64, + l1_pubdata_price_scale_factor: f64, + ) -> BatchFeeInput { + match self { + Self::V1(params) => BatchFeeInput::L1Pegged(compute_batch_fee_model_input_v1( + params, + l1_gas_price_scale_factor, + )), + Self::V2(params) => BatchFeeInput::PubdataIndependent(clip_batch_fee_model_input_v2( + compute_batch_fee_model_input_v2( + params, + l1_gas_price_scale_factor, + l1_pubdata_price_scale_factor, + ), + )), + } + } +} + +/// Calculates the batch fee input based on the main node parameters. +/// This function uses the `V1` fee model, i.e. where the pubdata price does not include the proving costs. +fn compute_batch_fee_model_input_v1( + params: FeeParamsV1, + l1_gas_price_scale_factor: f64, +) -> L1PeggedBatchFeeModelInput { + let l1_gas_price = (params.l1_gas_price as f64 * l1_gas_price_scale_factor) as u64; + + L1PeggedBatchFeeModelInput { + l1_gas_price, + fair_l2_gas_price: params.config.minimal_l2_gas_price, + } +} + +/// Calculates the batch fee input based on the main node parameters. +/// This function uses the `V2` fee model, i.e. where the pubdata price does not include the proving costs. +fn compute_batch_fee_model_input_v2( + params: FeeParamsV2, + l1_gas_price_scale_factor: f64, + l1_pubdata_price_scale_factor: f64, +) -> PubdataIndependentBatchFeeModelInput { + let config = params.config(); + let l1_gas_price = params.l1_gas_price(); + let l1_pubdata_price = params.l1_pubdata_price(); + + let FeeModelConfigV2 { + minimal_l2_gas_price, + compute_overhead_part, + pubdata_overhead_part, + batch_overhead_l1_gas, + max_gas_per_batch, + max_pubdata_per_batch, + } = config; + + // Firstly, we scale the gas price and pubdata price in case it is needed. + let l1_gas_price = (l1_gas_price as f64 * l1_gas_price_scale_factor) as u64; + let l1_pubdata_price = (l1_pubdata_price as f64 * l1_pubdata_price_scale_factor) as u64; + + // While the final results of the calculations are not expected to have any overflows, the intermediate computations + // might, so we use U256 for them. + let l1_batch_overhead_wei = U256::from(l1_gas_price) * U256::from(batch_overhead_l1_gas); + + let fair_l2_gas_price = { + // Firstly, we calculate which part of the overall overhead each unit of L2 gas should cover. + let l1_batch_overhead_per_gas = + ceil_div_u256(l1_batch_overhead_wei, U256::from(max_gas_per_batch)); + + // Then, we multiply by the `compute_overhead_part` to get the overhead for the computation for each gas. + // Also, this means that if we almost never close batches because of compute, the `compute_overhead_part` should be zero and so + // it is possible that the computation costs include for no overhead. + let gas_overhead_wei = + (l1_batch_overhead_per_gas.as_u64() as f64 * compute_overhead_part) as u64; + + // We sum up the minimal L2 gas price (i.e. the raw prover/compute cost of a single L2 gas) and the overhead for batch being closed. + minimal_l2_gas_price + gas_overhead_wei + }; + + let fair_pubdata_price = { + // Firstly, we calculate which part of the overall overhead each pubdata byte should cover. + let l1_batch_overhead_per_pubdata = + ceil_div_u256(l1_batch_overhead_wei, U256::from(max_pubdata_per_batch)); + + // Then, we multiply by the `pubdata_overhead_part` to get the overhead for each pubdata byte. + // Also, this means that if we almost never close batches because of pubdata, the `pubdata_overhead_part` should be zero and so + // it is possible that the pubdata costs include no overhead. + let pubdata_overhead_wei = + (l1_batch_overhead_per_pubdata.as_u64() as f64 * pubdata_overhead_part) as u64; + + // We sum up the raw L1 pubdata price (i.e. the expected price of publishing a single pubdata byte) and the overhead for batch being closed. + l1_pubdata_price + pubdata_overhead_wei + }; + + PubdataIndependentBatchFeeModelInput { + l1_gas_price, + fair_l2_gas_price, + fair_pubdata_price, + } +} + +/// Bootloader places limitations on fair_l2_gas_price and fair_pubdata_price. +/// (MAX_ALLOWED_FAIR_L2_GAS_PRICE and MAX_ALLOWED_FAIR_PUBDATA_PRICE in bootloader code respectively) +/// Server needs to clip this prices in order to allow chain continues operation at a loss. The alternative +/// would be to stop accepting the transactions until the conditions improve. +/// TODO (PE-153): to be removed when bootloader limitation is removed +fn clip_batch_fee_model_input_v2( + fee_model: PubdataIndependentBatchFeeModelInput, +) -> PubdataIndependentBatchFeeModelInput { + /// MAX_ALLOWED_FAIR_L2_GAS_PRICE + const MAXIMUM_L2_GAS_PRICE: u64 = 10_000_000_000_000; + /// MAX_ALLOWED_FAIR_PUBDATA_PRICE + const MAXIMUM_PUBDATA_PRICE: u64 = 1_000_000_000_000_000; + PubdataIndependentBatchFeeModelInput { + l1_gas_price: fee_model.l1_gas_price, + fair_l2_gas_price: if fee_model.fair_l2_gas_price < MAXIMUM_L2_GAS_PRICE { + fee_model.fair_l2_gas_price + } else { + tracing::warn!( + "Fair l2 gas price {} exceeds maximum. Limitting to {}", + fee_model.fair_l2_gas_price, + MAXIMUM_L2_GAS_PRICE + ); + MAXIMUM_L2_GAS_PRICE + }, + fair_pubdata_price: if fee_model.fair_pubdata_price < MAXIMUM_PUBDATA_PRICE { + fee_model.fair_pubdata_price + } else { + tracing::warn!( + "Fair pubdata price {} exceeds maximum. Limitting to {}", + fee_model.fair_pubdata_price, + MAXIMUM_PUBDATA_PRICE + ); + MAXIMUM_PUBDATA_PRICE + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // To test that overflow never happens, we'll use giant L1 gas price, i.e. + // almost realistic very large value of 100k gwei. Since it is so large, we'll also + // use it for the L1 pubdata price. + const GWEI: u64 = 1_000_000_000; + const GIANT_L1_GAS_PRICE: u64 = 100_000 * GWEI; + + // As a small L2 gas price we'll use the value of 1 wei. + const SMALL_L1_GAS_PRICE: u64 = 1; + + #[test] + fn test_compute_batch_fee_model_input_v2_giant_numbers() { + let config = FeeModelConfigV2 { + minimal_l2_gas_price: GIANT_L1_GAS_PRICE, + // We generally don't expect those values to be larger than 1. Still, in theory the operator + // may need to set higher values in extreme cases. + compute_overhead_part: 5.0, + pubdata_overhead_part: 5.0, + // The batch overhead would likely never grow beyond that + batch_overhead_l1_gas: 1_000_000, + // Let's imagine that for some reason the limit is relatively small + max_gas_per_batch: 50_000_000, + // The pubdata will likely never go below that + max_pubdata_per_batch: 100_000, + }; + + let params = FeeParamsV2::new( + config, + GIANT_L1_GAS_PRICE, + GIANT_L1_GAS_PRICE, + BaseTokenConversionRatio::default(), + ); + + // We'll use scale factor of 3.0 + let input = compute_batch_fee_model_input_v2(params, 3.0, 3.0); + + assert_eq!(input.l1_gas_price, GIANT_L1_GAS_PRICE * 3); + assert_eq!(input.fair_l2_gas_price, 130_000_000_000_000); + assert_eq!(input.fair_pubdata_price, 15_300_000_000_000_000); + } + + #[test] + fn test_compute_batch_fee_model_input_v2_small_numbers() { + // Here we assume that the operator wants to make the lives of users as cheap as possible. + let config = FeeModelConfigV2 { + minimal_l2_gas_price: SMALL_L1_GAS_PRICE, + compute_overhead_part: 0.0, + pubdata_overhead_part: 0.0, + batch_overhead_l1_gas: 0, + max_gas_per_batch: 50_000_000, + max_pubdata_per_batch: 100_000, + }; + + let params = FeeParamsV2::new( + config, + SMALL_L1_GAS_PRICE, + SMALL_L1_GAS_PRICE, + BaseTokenConversionRatio::default(), + ); + + let input = + clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); + + assert_eq!(input.l1_gas_price, SMALL_L1_GAS_PRICE); + assert_eq!(input.fair_l2_gas_price, SMALL_L1_GAS_PRICE); + assert_eq!(input.fair_pubdata_price, SMALL_L1_GAS_PRICE); + } + + #[test] + fn test_compute_batch_fee_model_input_v2_only_pubdata_overhead() { + // Here we use sensible config, but when only pubdata is used to close the batch + let config = FeeModelConfigV2 { + minimal_l2_gas_price: 100_000_000_000, + compute_overhead_part: 0.0, + pubdata_overhead_part: 1.0, + batch_overhead_l1_gas: 700_000, + max_gas_per_batch: 500_000_000, + max_pubdata_per_batch: 100_000, + }; + + let params = FeeParamsV2::new( + config, + GIANT_L1_GAS_PRICE, + GIANT_L1_GAS_PRICE, + BaseTokenConversionRatio::default(), + ); + + let input = + clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); + assert_eq!(input.l1_gas_price, GIANT_L1_GAS_PRICE); + // The fair L2 gas price is identical to the minimal one. + assert_eq!(input.fair_l2_gas_price, 100_000_000_000); + // The fair pubdata price is the minimal one plus the overhead. + assert_eq!(input.fair_pubdata_price, 800_000_000_000_000); + } + + #[test] + fn test_compute_baxtch_fee_model_input_v2_only_compute_overhead() { + // Here we use sensible config, but when only compute is used to close the batch + let config = FeeModelConfigV2 { + minimal_l2_gas_price: 100_000_000_000, + compute_overhead_part: 1.0, + pubdata_overhead_part: 0.0, + batch_overhead_l1_gas: 700_000, + max_gas_per_batch: 500_000_000, + max_pubdata_per_batch: 100_000, + }; + + let params = FeeParamsV2::new( + config, + GIANT_L1_GAS_PRICE, + GIANT_L1_GAS_PRICE, + BaseTokenConversionRatio::default(), + ); + + let input = compute_batch_fee_model_input_v2(params, 1.0, 1.0); + assert_eq!(input.l1_gas_price, GIANT_L1_GAS_PRICE); + // The fair L2 gas price is identical to the minimal one, plus the overhead + assert_eq!(input.fair_l2_gas_price, 240_000_000_000); + // The fair pubdata price is equal to the original one. + assert_eq!(input.fair_pubdata_price, GIANT_L1_GAS_PRICE); + } + + #[test] + fn test_compute_batch_fee_model_input_v2_param_tweaking() { + // In this test we generally checking that each param behaves as expected + let base_config = FeeModelConfigV2 { + minimal_l2_gas_price: 100_000_000_000, + compute_overhead_part: 0.5, + pubdata_overhead_part: 0.5, + batch_overhead_l1_gas: 700_000, + max_gas_per_batch: 500_000_000, + max_pubdata_per_batch: 100_000, + }; + + let base_params = FeeParamsV2::new( + base_config, + 1_000_000_000, + 1_000_000_000, + BaseTokenConversionRatio::default(), + ); + + let base_input = compute_batch_fee_model_input_v2(base_params, 1.0, 1.0); + + let base_input_larger_l1_gas_price = compute_batch_fee_model_input_v2( + FeeParamsV2::new( + base_config, + 2_000_000_000, // double the L1 gas price + 1_000_000_000, + BaseTokenConversionRatio::default(), + ), + 1.0, + 1.0, + ); + let base_input_scaled_l1_gas_price = + compute_batch_fee_model_input_v2(base_params, 2.0, 1.0); + assert_eq!( + base_input_larger_l1_gas_price, base_input_scaled_l1_gas_price, + "Scaling has the correct effect for the L1 gas price" + ); + assert!( + base_input.fair_l2_gas_price < base_input_larger_l1_gas_price.fair_l2_gas_price, + "L1 gas price increase raises L2 gas price" + ); + assert!( + base_input.fair_pubdata_price < base_input_larger_l1_gas_price.fair_pubdata_price, + "L1 gas price increase raises pubdata price" + ); + + let base_input_larger_pubdata_price = compute_batch_fee_model_input_v2( + FeeParamsV2::new( + base_config, + 1_000_000_000, + 2_000_000_000, // double the L1 pubdata price + BaseTokenConversionRatio::default(), + ), + 1.0, + 1.0, + ); + let base_input_scaled_pubdata_price = + compute_batch_fee_model_input_v2(base_params, 1.0, 2.0); + assert_eq!( + base_input_larger_pubdata_price, base_input_scaled_pubdata_price, + "Scaling has the correct effect for the pubdata price" + ); + assert_eq!( + base_input.fair_l2_gas_price, base_input_larger_pubdata_price.fair_l2_gas_price, + "L1 pubdata increase has no effect on L2 gas price" + ); + assert!( + base_input.fair_pubdata_price < base_input_larger_pubdata_price.fair_pubdata_price, + "Pubdata price increase raises pubdata price" + ); + + let base_input_larger_max_gas = compute_batch_fee_model_input_v2( + FeeParamsV2::new( + FeeModelConfigV2 { + max_gas_per_batch: base_config.max_gas_per_batch * 2, + ..base_config + }, + base_params.l1_gas_price(), + base_params.l1_pubdata_price(), + BaseTokenConversionRatio::default(), + ), + 1.0, + 1.0, + ); + assert!( + base_input.fair_l2_gas_price > base_input_larger_max_gas.fair_l2_gas_price, + "Max gas increase lowers L2 gas price" + ); + assert_eq!( + base_input.fair_pubdata_price, base_input_larger_max_gas.fair_pubdata_price, + "Max gas increase has no effect on pubdata price" + ); + + let base_input_larger_max_pubdata = compute_batch_fee_model_input_v2( + FeeParamsV2::new( + FeeModelConfigV2 { + max_pubdata_per_batch: base_config.max_pubdata_per_batch * 2, + ..base_config + }, + base_params.l1_gas_price(), + base_params.l1_pubdata_price(), + BaseTokenConversionRatio::default(), + ), + 1.0, + 1.0, + ); + assert_eq!( + base_input.fair_l2_gas_price, base_input_larger_max_pubdata.fair_l2_gas_price, + "Max pubdata increase has no effect on L2 gas price" + ); + assert!( + base_input.fair_pubdata_price > base_input_larger_max_pubdata.fair_pubdata_price, + "Max pubdata increase lowers pubdata price" + ); + } + + #[test] + fn test_compute_batch_fee_model_input_v2_gas_price_over_limit_due_to_l1_gas() { + // In this test we check the gas price limit works as expected + let config = FeeModelConfigV2 { + minimal_l2_gas_price: 100 * GWEI, + compute_overhead_part: 0.5, + pubdata_overhead_part: 0.5, + batch_overhead_l1_gas: 700_000, + max_gas_per_batch: 500_000_000, + max_pubdata_per_batch: 100_000, + }; + + let l1_gas_price = 1_000_000_000 * GWEI; + let params = FeeParamsV2::new( + config, + l1_gas_price, + GIANT_L1_GAS_PRICE, + BaseTokenConversionRatio::default(), + ); + + let input = + clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); + assert_eq!(input.l1_gas_price, l1_gas_price); + // The fair L2 gas price is identical to the maximum + assert_eq!(input.fair_l2_gas_price, 10_000 * GWEI); + assert_eq!(input.fair_pubdata_price, 1_000_000 * GWEI); + } + + #[test] + fn test_compute_batch_fee_model_input_v2_gas_price_over_limit_due_to_conversion_rate() { + // In this test we check the gas price limit works as expected + let config = FeeModelConfigV2 { + minimal_l2_gas_price: GWEI, + compute_overhead_part: 0.5, + pubdata_overhead_part: 0.5, + batch_overhead_l1_gas: 700_000, + max_gas_per_batch: 500_000_000, + max_pubdata_per_batch: 100_000, + }; + + let params = FeeParamsV2::new( + config, + GWEI, + 2 * GWEI, + BaseTokenConversionRatio { + numerator: NonZeroU64::new(3_000_000).unwrap(), + denominator: NonZeroU64::new(1).unwrap(), + }, + ); + + let input = + clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); + assert_eq!(input.l1_gas_price, 3_000_000 * GWEI); + // The fair L2 gas price is identical to the maximum + assert_eq!(input.fair_l2_gas_price, 10_000 * GWEI); + assert_eq!(input.fair_pubdata_price, 1_000_000 * GWEI); + } } diff --git a/core/lib/types/src/lib.rs b/core/lib/types/src/lib.rs index a50fc8a655b7..69e6e42fd51c 100644 --- a/core/lib/types/src/lib.rs +++ b/core/lib/types/src/lib.rs @@ -43,7 +43,6 @@ pub mod l2; pub mod l2_to_l1_log; pub mod priority_op_onchain_data; pub mod protocol_upgrade; -pub mod pubdata_da; pub mod snapshots; pub mod storage; pub mod system_contracts; diff --git a/core/node/api_server/src/testonly.rs b/core/node/api_server/src/testonly.rs index 13e5ecc08ead..6da8e333495f 100644 --- a/core/node/api_server/src/testonly.rs +++ b/core/node/api_server/src/testonly.rs @@ -10,7 +10,6 @@ use zksync_contracts::{ }; use zksync_dal::{Connection, Core, CoreDal}; use zksync_multivm::utils::derive_base_fee_and_gas_per_pubdata; -use zksync_node_fee_model::BatchFeeModelInputProvider; use zksync_system_constants::L2_BASE_TOKEN_ADDRESS; use zksync_types::{ api::state_override::{Bytecode, OverrideAccount, OverrideState, StateOverride}, @@ -72,11 +71,7 @@ fn inflate_bytecode(bytecode: &mut Vec, nop_count: usize) { } fn default_fee() -> Fee { - let fee_input = ::default_batch_fee_input_scaled( - FeeParams::sensible_v1_default(), - 1.0, - 1.0, - ); + let fee_input = FeeParams::sensible_v1_default().scale(1.0, 1.0); let (max_fee_per_gas, gas_per_pubdata_limit) = derive_base_fee_and_gas_per_pubdata(fee_input, ProtocolVersionId::default().into()); Fee { diff --git a/core/node/api_server/src/web3/tests/mod.rs b/core/node/api_server/src/web3/tests/mod.rs index c83279709a30..d8080f1dba59 100644 --- a/core/node/api_server/src/web3/tests/mod.rs +++ b/core/node/api_server/src/web3/tests/mod.rs @@ -22,7 +22,6 @@ use zksync_multivm::interface::{ TransactionExecutionMetrics, TransactionExecutionResult, TxExecutionStatus, VmEvent, VmExecutionMetrics, }; -use zksync_node_fee_model::BatchFeeModelInputProvider; use zksync_node_genesis::{insert_genesis_batch, mock_genesis_config, GenesisParams}; use zksync_node_test_utils::{ create_l1_batch, create_l1_batch_metadata, create_l2_block, create_l2_transaction, @@ -476,11 +475,7 @@ async fn store_events( } fn scaled_sensible_fee_input(scale: f64) -> BatchFeeInput { - ::default_batch_fee_input_scaled( - FeeParams::sensible_v1_default(), - scale, - scale, - ) + FeeParams::sensible_v1_default().scale(scale, scale) } #[derive(Debug)] diff --git a/core/node/consistency_checker/src/lib.rs b/core/node/consistency_checker/src/lib.rs index 20ba43a4166e..e13e479117cc 100644 --- a/core/node/consistency_checker/src/lib.rs +++ b/core/node/consistency_checker/src/lib.rs @@ -19,7 +19,7 @@ use zksync_types::{ commitment::{L1BatchCommitmentMode, L1BatchWithMetadata}, ethabi, ethabi::Token, - pubdata_da::PubdataDA, + pubdata_da::PubdataSendingMode, Address, L1BatchNumber, ProtocolVersionId, H256, U256, }; @@ -224,7 +224,7 @@ impl LocalL1BatchCommitData { .context("cannot detect DA source from reference commitment token")?; // For `PubdataDA::Calldata`, it's required that the pubdata fits into a single blob. - if matches!(da, PubdataDA::Calldata) { + if matches!(da, PubdataSendingMode::Calldata) { let pubdata_len = self .l1_batch .header @@ -258,7 +258,7 @@ impl LocalL1BatchCommitData { pub fn detect_da( protocol_version: ProtocolVersionId, reference: &Token, -) -> Result { +) -> Result { /// These are used by the L1 Contracts to indicate what DA layer is used for pubdata const PUBDATA_SOURCE_CALLDATA: u8 = 0; const PUBDATA_SOURCE_BLOBS: u8 = 1; @@ -269,7 +269,7 @@ pub fn detect_da( } if protocol_version.is_pre_1_4_2() { - return Ok(PubdataDA::Calldata); + return Ok(PubdataSendingMode::Calldata); } let reference = match reference { @@ -291,9 +291,9 @@ pub fn detect_da( ))), }; match last_reference_token.first() { - Some(&byte) if byte == PUBDATA_SOURCE_CALLDATA => Ok(PubdataDA::Calldata), - Some(&byte) if byte == PUBDATA_SOURCE_BLOBS => Ok(PubdataDA::Blobs), - Some(&byte) if byte == PUBDATA_SOURCE_CUSTOM => Ok(PubdataDA::Custom), + Some(&byte) if byte == PUBDATA_SOURCE_CALLDATA => Ok(PubdataSendingMode::Calldata), + Some(&byte) if byte == PUBDATA_SOURCE_BLOBS => Ok(PubdataSendingMode::Blobs), + Some(&byte) if byte == PUBDATA_SOURCE_CUSTOM => Ok(PubdataSendingMode::Custom), Some(&byte) => Err(parse_error(format!( "unexpected first byte of the last reference token; expected one of [{PUBDATA_SOURCE_CALLDATA}, {PUBDATA_SOURCE_BLOBS}], \ got {byte}" diff --git a/core/node/consistency_checker/src/tests/mod.rs b/core/node/consistency_checker/src/tests/mod.rs index 40c447071cf4..b09ef2b2272c 100644 --- a/core/node/consistency_checker/src/tests/mod.rs +++ b/core/node/consistency_checker/src/tests/mod.rs @@ -64,7 +64,7 @@ pub(crate) fn build_commit_tx_input_data( let tokens = CommitBatches { last_committed_l1_batch: &batches[0], l1_batches: batches, - pubdata_da: PubdataDA::Calldata, + pubdata_da: PubdataSendingMode::Calldata, mode, } .into_tokens(); @@ -167,7 +167,7 @@ fn build_commit_tx_input_data_is_correct(commitment_mode: L1BatchCommitmentMode) .unwrap(); assert_eq!( commit_data, - CommitBatchInfo::new(commitment_mode, batch, PubdataDA::Calldata).into_token(), + CommitBatchInfo::new(commitment_mode, batch, PubdataSendingMode::Calldata).into_token(), ); } } diff --git a/core/node/eth_sender/src/aggregated_operations.rs b/core/node/eth_sender/src/aggregated_operations.rs index 2dfaf5942659..5271d42d3b75 100644 --- a/core/node/eth_sender/src/aggregated_operations.rs +++ b/core/node/eth_sender/src/aggregated_operations.rs @@ -3,13 +3,17 @@ use std::ops; use zksync_l1_contract_interface::i_executor::methods::{ExecuteBatches, ProveBatches}; use zksync_types::{ aggregated_operations::AggregatedActionType, commitment::L1BatchWithMetadata, - pubdata_da::PubdataDA, L1BatchNumber, ProtocolVersionId, + pubdata_da::PubdataSendingMode, L1BatchNumber, ProtocolVersionId, }; #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone)] pub enum AggregatedOperation { - Commit(L1BatchWithMetadata, Vec, PubdataDA), + Commit( + L1BatchWithMetadata, + Vec, + PubdataSendingMode, + ), PublishProofOnchain(ProveBatches), Execute(ExecuteBatches), } diff --git a/core/node/eth_sender/src/aggregator.rs b/core/node/eth_sender/src/aggregator.rs index 4045e9ca3d80..432804a21b2e 100644 --- a/core/node/eth_sender/src/aggregator.rs +++ b/core/node/eth_sender/src/aggregator.rs @@ -11,7 +11,7 @@ use zksync_types::{ commitment::{L1BatchCommitmentMode, L1BatchWithMetadata}, helpers::unix_timestamp_ms, protocol_version::{L1VerifierConfig, ProtocolSemanticVersion}, - pubdata_da::PubdataDA, + pubdata_da::PubdataSendingMode, L1BatchNumber, ProtocolVersionId, }; @@ -36,7 +36,7 @@ pub struct Aggregator { /// means no wait is needed: nonces will still provide the correct ordering of /// transactions. operate_4844_mode: bool, - pubdata_da: PubdataDA, + pubdata_da: PubdataSendingMode, commitment_mode: L1BatchCommitmentMode, } @@ -47,8 +47,7 @@ impl Aggregator { operate_4844_mode: bool, commitment_mode: L1BatchCommitmentMode, ) -> Self { - let pubdata_da = config.pubdata_sending_mode.into(); - + let pubdata_da = config.pubdata_sending_mode; Self { commit_criteria: vec![ Box::from(NumberCriterion { @@ -476,7 +475,7 @@ impl Aggregator { } } - pub fn pubdata_da(&self) -> PubdataDA { + pub fn pubdata_da(&self) -> PubdataSendingMode { self.pubdata_da } diff --git a/core/node/eth_sender/src/eth_tx_aggregator.rs b/core/node/eth_sender/src/eth_tx_aggregator.rs index a08d16f456a9..ac9ed4aaaadb 100644 --- a/core/node/eth_sender/src/eth_tx_aggregator.rs +++ b/core/node/eth_sender/src/eth_tx_aggregator.rs @@ -19,7 +19,7 @@ use zksync_types::{ ethabi::{Function, Token}, l2_to_l1_log::UserL2ToL1Log, protocol_version::{L1VerifierConfig, PACKED_SEMVER_MINOR_MASK}, - pubdata_da::PubdataDA, + pubdata_da::PubdataSendingMode, settlement::SettlementMode, web3::{contract::Error as Web3ContractError, BlockNumber}, Address, L2ChainId, ProtocolVersionId, SLChainId, H256, U256, @@ -505,11 +505,12 @@ impl EthTxAggregator { ) }; - let l1_batch_for_sidecar = if PubdataDA::Blobs == self.aggregator.pubdata_da() { - Some(l1_batches[0].clone()) - } else { - None - }; + let l1_batch_for_sidecar = + if PubdataSendingMode::Blobs == self.aggregator.pubdata_da() { + Some(l1_batches[0].clone()) + } else { + None + }; Self::encode_commit_data(encoding_fn, &commit_data, l1_batch_for_sidecar) } diff --git a/core/node/eth_sender/src/publish_criterion.rs b/core/node/eth_sender/src/publish_criterion.rs index 52d861ce0af6..30f0820b148a 100644 --- a/core/node/eth_sender/src/publish_criterion.rs +++ b/core/node/eth_sender/src/publish_criterion.rs @@ -8,7 +8,7 @@ use zksync_types::{ aggregated_operations::AggregatedActionType, commitment::{L1BatchCommitmentMode, L1BatchWithMetadata}, ethabi, - pubdata_da::PubdataDA, + pubdata_da::PubdataSendingMode, L1BatchNumber, }; @@ -202,7 +202,7 @@ impl L1BatchPublishCriterion for GasCriterion { pub struct DataSizeCriterion { pub op: AggregatedActionType, pub data_limit: usize, - pub pubdata_da: PubdataDA, + pub pubdata_da: PubdataSendingMode, pub commitment_mode: L1BatchCommitmentMode, } diff --git a/core/node/eth_sender/src/tester.rs b/core/node/eth_sender/src/tester.rs index 86a8c477f9fe..646df1dc1a7b 100644 --- a/core/node/eth_sender/src/tester.rs +++ b/core/node/eth_sender/src/tester.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use zksync_config::{ - configs::eth_sender::{ProofSendingMode, PubdataSendingMode, SenderConfig}, + configs::eth_sender::{ProofSendingMode, SenderConfig}, ContractsConfig, EthConfig, GasAdjusterConfig, }; use zksync_dal::{Connection, ConnectionPool, Core, CoreDal}; @@ -12,7 +12,7 @@ use zksync_node_test_utils::{create_l1_batch, l1_batch_metadata_to_commitment_ar use zksync_object_store::MockObjectStore; use zksync_types::{ aggregated_operations::AggregatedActionType, block::L1BatchHeader, - commitment::L1BatchCommitmentMode, eth_sender::EthTx, pubdata_da::PubdataDA, + commitment::L1BatchCommitmentMode, eth_sender::EthTx, pubdata_da::PubdataSendingMode, settlement::SettlementMode, Address, L1BatchNumber, ProtocolVersion, H256, }; @@ -485,9 +485,9 @@ impl EthSenderTester { pub async fn save_commit_tx(&mut self, l1_batch_number: L1BatchNumber) -> EthTx { assert_eq!(l1_batch_number, self.next_l1_batch_number_to_commit); let pubdata_mode = if self.pubdata_sending_mode == PubdataSendingMode::Blobs { - PubdataDA::Blobs + PubdataSendingMode::Blobs } else { - PubdataDA::Calldata + PubdataSendingMode::Calldata }; let operation = AggregatedOperation::Commit( l1_batch_with_metadata( diff --git a/core/node/fee_model/Cargo.toml b/core/node/fee_model/Cargo.toml index 8760b97d9db3..a84a7c5c2173 100644 --- a/core/node/fee_model/Cargo.toml +++ b/core/node/fee_model/Cargo.toml @@ -16,9 +16,7 @@ zksync_types.workspace = true zksync_dal.workspace = true zksync_config.workspace = true zksync_eth_client.workspace = true -zksync_utils.workspace = true zksync_web3_decl.workspace = true -bigdecimal.workspace = true tokio = { workspace = true, features = ["time"] } anyhow.workspace = true diff --git a/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs b/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs index 27cdc7f5d5e0..459b8855b961 100644 --- a/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs +++ b/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs @@ -6,9 +6,12 @@ use std::{ }; use tokio::sync::watch; -use zksync_config::{configs::eth_sender::PubdataSendingMode, GasAdjusterConfig}; +use zksync_config::GasAdjusterConfig; use zksync_eth_client::EthFeeInterface; -use zksync_types::{commitment::L1BatchCommitmentMode, L1_GAS_PER_PUBDATA_BYTE, U256}; +use zksync_types::{ + commitment::L1BatchCommitmentMode, pubdata_da::PubdataSendingMode, L1_GAS_PER_PUBDATA_BYTE, + U256, +}; use zksync_web3_decl::client::{DynClient, L1, L2}; use self::metrics::METRICS; diff --git a/core/node/fee_model/src/l1_gas_price/gas_adjuster/tests.rs b/core/node/fee_model/src/l1_gas_price/gas_adjuster/tests.rs index 47023203de0e..ab649e2d7c90 100644 --- a/core/node/fee_model/src/l1_gas_price/gas_adjuster/tests.rs +++ b/core/node/fee_model/src/l1_gas_price/gas_adjuster/tests.rs @@ -1,9 +1,11 @@ use std::{collections::VecDeque, sync::RwLockReadGuard}; use test_casing::test_casing; -use zksync_config::{configs::eth_sender::PubdataSendingMode, GasAdjusterConfig}; +use zksync_config::GasAdjusterConfig; use zksync_eth_client::{clients::MockSettlementLayer, BaseFees}; -use zksync_types::{commitment::L1BatchCommitmentMode, settlement::SettlementMode}; +use zksync_types::{ + commitment::L1BatchCommitmentMode, pubdata_da::PubdataSendingMode, settlement::SettlementMode, +}; use zksync_web3_decl::client::L2; use super::{GasAdjuster, GasStatistics, GasStatisticsInner}; diff --git a/core/node/fee_model/src/lib.rs b/core/node/fee_model/src/lib.rs index fe4f6a27ce29..380a279cccc1 100644 --- a/core/node/fee_model/src/lib.rs +++ b/core/node/fee_model/src/lib.rs @@ -3,14 +3,9 @@ use std::{fmt, fmt::Debug, sync::Arc}; use anyhow::Context as _; use async_trait::async_trait; use zksync_dal::{ConnectionPool, Core, CoreDal}; -use zksync_types::{ - fee_model::{ - BaseTokenConversionRatio, BatchFeeInput, FeeModelConfig, FeeModelConfigV2, FeeParams, - FeeParamsV1, FeeParamsV2, L1PeggedBatchFeeModelInput, PubdataIndependentBatchFeeModelInput, - }, - U256, +use zksync_types::fee_model::{ + BaseTokenConversionRatio, BatchFeeInput, FeeModelConfig, FeeParams, FeeParamsV1, FeeParamsV2, }; -use zksync_utils::ceil_div_u256; use crate::l1_gas_price::GasAdjuster; @@ -34,13 +29,7 @@ pub trait BatchFeeModelInputProvider: fmt::Debug + 'static + Send + Sync { l1_pubdata_price_scale_factor: f64, ) -> anyhow::Result { let params = self.get_fee_model_params(); - Ok( - ::default_batch_fee_input_scaled( - params, - l1_gas_price_scale_factor, - l1_pubdata_price_scale_factor, - ), - ) + Ok(params.scale(l1_gas_price_scale_factor, l1_pubdata_price_scale_factor)) } /// Returns the fee model parameters using the denomination of the base token used (WEI for ETH). @@ -48,27 +37,6 @@ pub trait BatchFeeModelInputProvider: fmt::Debug + 'static + Send + Sync { } impl dyn BatchFeeModelInputProvider { - /// Provides the default implementation of `get_batch_fee_input_scaled()` given [`FeeParams`]. - pub fn default_batch_fee_input_scaled( - params: FeeParams, - l1_gas_price_scale_factor: f64, - l1_pubdata_price_scale_factor: f64, - ) -> BatchFeeInput { - match params { - FeeParams::V1(params) => BatchFeeInput::L1Pegged(compute_batch_fee_model_input_v1( - params, - l1_gas_price_scale_factor, - )), - FeeParams::V2(params) => BatchFeeInput::PubdataIndependent( - clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2( - params, - l1_gas_price_scale_factor, - l1_pubdata_price_scale_factor, - )), - ), - } - } - /// Returns the batch fee input as-is, i.e. without any scaling for the L1 gas and pubdata prices. pub async fn get_batch_fee_input(&self) -> anyhow::Result { self.get_batch_fee_input_scaled(1.0, 1.0).await @@ -168,122 +136,6 @@ impl BatchFeeModelInputProvider for ApiFeeInputProvider { } } -/// Calculates the batch fee input based on the main node parameters. -/// This function uses the `V1` fee model, i.e. where the pubdata price does not include the proving costs. -fn compute_batch_fee_model_input_v1( - params: FeeParamsV1, - l1_gas_price_scale_factor: f64, -) -> L1PeggedBatchFeeModelInput { - let l1_gas_price = (params.l1_gas_price as f64 * l1_gas_price_scale_factor) as u64; - - L1PeggedBatchFeeModelInput { - l1_gas_price, - fair_l2_gas_price: params.config.minimal_l2_gas_price, - } -} - -/// Calculates the batch fee input based on the main node parameters. -/// This function uses the `V2` fee model, i.e. where the pubdata price does not include the proving costs. -fn compute_batch_fee_model_input_v2( - params: FeeParamsV2, - l1_gas_price_scale_factor: f64, - l1_pubdata_price_scale_factor: f64, -) -> PubdataIndependentBatchFeeModelInput { - let config = params.config(); - let l1_gas_price = params.l1_gas_price(); - let l1_pubdata_price = params.l1_pubdata_price(); - - let FeeModelConfigV2 { - minimal_l2_gas_price, - compute_overhead_part, - pubdata_overhead_part, - batch_overhead_l1_gas, - max_gas_per_batch, - max_pubdata_per_batch, - } = config; - - // Firstly, we scale the gas price and pubdata price in case it is needed. - let l1_gas_price = (l1_gas_price as f64 * l1_gas_price_scale_factor) as u64; - let l1_pubdata_price = (l1_pubdata_price as f64 * l1_pubdata_price_scale_factor) as u64; - - // While the final results of the calculations are not expected to have any overflows, the intermediate computations - // might, so we use U256 for them. - let l1_batch_overhead_wei = U256::from(l1_gas_price) * U256::from(batch_overhead_l1_gas); - - let fair_l2_gas_price = { - // Firstly, we calculate which part of the overall overhead each unit of L2 gas should cover. - let l1_batch_overhead_per_gas = - ceil_div_u256(l1_batch_overhead_wei, U256::from(max_gas_per_batch)); - - // Then, we multiply by the `compute_overhead_part` to get the overhead for the computation for each gas. - // Also, this means that if we almost never close batches because of compute, the `compute_overhead_part` should be zero and so - // it is possible that the computation costs include for no overhead. - let gas_overhead_wei = - (l1_batch_overhead_per_gas.as_u64() as f64 * compute_overhead_part) as u64; - - // We sum up the minimal L2 gas price (i.e. the raw prover/compute cost of a single L2 gas) and the overhead for batch being closed. - minimal_l2_gas_price + gas_overhead_wei - }; - - let fair_pubdata_price = { - // Firstly, we calculate which part of the overall overhead each pubdata byte should cover. - let l1_batch_overhead_per_pubdata = - ceil_div_u256(l1_batch_overhead_wei, U256::from(max_pubdata_per_batch)); - - // Then, we multiply by the `pubdata_overhead_part` to get the overhead for each pubdata byte. - // Also, this means that if we almost never close batches because of pubdata, the `pubdata_overhead_part` should be zero and so - // it is possible that the pubdata costs include no overhead. - let pubdata_overhead_wei = - (l1_batch_overhead_per_pubdata.as_u64() as f64 * pubdata_overhead_part) as u64; - - // We sum up the raw L1 pubdata price (i.e. the expected price of publishing a single pubdata byte) and the overhead for batch being closed. - l1_pubdata_price + pubdata_overhead_wei - }; - - PubdataIndependentBatchFeeModelInput { - l1_gas_price, - fair_l2_gas_price, - fair_pubdata_price, - } -} - -/// Bootloader places limitations on fair_l2_gas_price and fair_pubdata_price. -/// (MAX_ALLOWED_FAIR_L2_GAS_PRICE and MAX_ALLOWED_FAIR_PUBDATA_PRICE in bootloader code respectively) -/// Server needs to clip this prices in order to allow chain continues operation at a loss. The alternative -/// would be to stop accepting the transactions until the conditions improve. -/// TODO (PE-153): to be removed when bootloader limitation is removed -fn clip_batch_fee_model_input_v2( - fee_model: PubdataIndependentBatchFeeModelInput, -) -> PubdataIndependentBatchFeeModelInput { - /// MAX_ALLOWED_FAIR_L2_GAS_PRICE - const MAXIMUM_L2_GAS_PRICE: u64 = 10_000_000_000_000; - /// MAX_ALLOWED_FAIR_PUBDATA_PRICE - const MAXIMUM_PUBDATA_PRICE: u64 = 1_000_000_000_000_000; - PubdataIndependentBatchFeeModelInput { - l1_gas_price: fee_model.l1_gas_price, - fair_l2_gas_price: if fee_model.fair_l2_gas_price < MAXIMUM_L2_GAS_PRICE { - fee_model.fair_l2_gas_price - } else { - tracing::warn!( - "Fair l2 gas price {} exceeds maximum. Limitting to {}", - fee_model.fair_l2_gas_price, - MAXIMUM_L2_GAS_PRICE - ); - MAXIMUM_L2_GAS_PRICE - }, - fair_pubdata_price: if fee_model.fair_pubdata_price < MAXIMUM_PUBDATA_PRICE { - fee_model.fair_pubdata_price - } else { - tracing::warn!( - "Fair pubdata price {} exceeds maximum. Limitting to {}", - fee_model.fair_pubdata_price, - MAXIMUM_PUBDATA_PRICE - ); - MAXIMUM_PUBDATA_PRICE - }, - } -} - /// Mock [`BatchFeeModelInputProvider`] implementation that returns a constant value. /// Intended to be used in tests only. #[derive(Debug)] @@ -307,308 +159,17 @@ mod tests { use std::num::NonZeroU64; use l1_gas_price::GasAdjusterClient; - use zksync_config::{configs::eth_sender::PubdataSendingMode, GasAdjusterConfig}; + use zksync_config::GasAdjusterConfig; use zksync_eth_client::{clients::MockSettlementLayer, BaseFees}; - use zksync_types::{commitment::L1BatchCommitmentMode, fee_model::BaseTokenConversionRatio}; + use zksync_types::{ + commitment::L1BatchCommitmentMode, + fee_model::{BaseTokenConversionRatio, FeeModelConfigV2}, + pubdata_da::PubdataSendingMode, + U256, + }; use super::*; - // To test that overflow never happens, we'll use giant L1 gas price, i.e. - // almost realistic very large value of 100k gwei. Since it is so large, we'll also - // use it for the L1 pubdata price. - const GWEI: u64 = 1_000_000_000; - const GIANT_L1_GAS_PRICE: u64 = 100_000 * GWEI; - - // As a small L2 gas price we'll use the value of 1 wei. - const SMALL_L1_GAS_PRICE: u64 = 1; - - #[test] - fn test_compute_batch_fee_model_input_v2_giant_numbers() { - let config = FeeModelConfigV2 { - minimal_l2_gas_price: GIANT_L1_GAS_PRICE, - // We generally don't expect those values to be larger than 1. Still, in theory the operator - // may need to set higher values in extreme cases. - compute_overhead_part: 5.0, - pubdata_overhead_part: 5.0, - // The batch overhead would likely never grow beyond that - batch_overhead_l1_gas: 1_000_000, - // Let's imagine that for some reason the limit is relatively small - max_gas_per_batch: 50_000_000, - // The pubdata will likely never go below that - max_pubdata_per_batch: 100_000, - }; - - let params = FeeParamsV2::new( - config, - GIANT_L1_GAS_PRICE, - GIANT_L1_GAS_PRICE, - BaseTokenConversionRatio::default(), - ); - - // We'll use scale factor of 3.0 - let input = compute_batch_fee_model_input_v2(params, 3.0, 3.0); - - assert_eq!(input.l1_gas_price, GIANT_L1_GAS_PRICE * 3); - assert_eq!(input.fair_l2_gas_price, 130_000_000_000_000); - assert_eq!(input.fair_pubdata_price, 15_300_000_000_000_000); - } - - #[test] - fn test_compute_batch_fee_model_input_v2_small_numbers() { - // Here we assume that the operator wants to make the lives of users as cheap as possible. - let config = FeeModelConfigV2 { - minimal_l2_gas_price: SMALL_L1_GAS_PRICE, - compute_overhead_part: 0.0, - pubdata_overhead_part: 0.0, - batch_overhead_l1_gas: 0, - max_gas_per_batch: 50_000_000, - max_pubdata_per_batch: 100_000, - }; - - let params = FeeParamsV2::new( - config, - SMALL_L1_GAS_PRICE, - SMALL_L1_GAS_PRICE, - BaseTokenConversionRatio::default(), - ); - - let input = - clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); - - assert_eq!(input.l1_gas_price, SMALL_L1_GAS_PRICE); - assert_eq!(input.fair_l2_gas_price, SMALL_L1_GAS_PRICE); - assert_eq!(input.fair_pubdata_price, SMALL_L1_GAS_PRICE); - } - - #[test] - fn test_compute_batch_fee_model_input_v2_only_pubdata_overhead() { - // Here we use sensible config, but when only pubdata is used to close the batch - let config = FeeModelConfigV2 { - minimal_l2_gas_price: 100_000_000_000, - compute_overhead_part: 0.0, - pubdata_overhead_part: 1.0, - batch_overhead_l1_gas: 700_000, - max_gas_per_batch: 500_000_000, - max_pubdata_per_batch: 100_000, - }; - - let params = FeeParamsV2::new( - config, - GIANT_L1_GAS_PRICE, - GIANT_L1_GAS_PRICE, - BaseTokenConversionRatio::default(), - ); - - let input = - clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); - assert_eq!(input.l1_gas_price, GIANT_L1_GAS_PRICE); - // The fair L2 gas price is identical to the minimal one. - assert_eq!(input.fair_l2_gas_price, 100_000_000_000); - // The fair pubdata price is the minimal one plus the overhead. - assert_eq!(input.fair_pubdata_price, 800_000_000_000_000); - } - - #[test] - fn test_compute_baxtch_fee_model_input_v2_only_compute_overhead() { - // Here we use sensible config, but when only compute is used to close the batch - let config = FeeModelConfigV2 { - minimal_l2_gas_price: 100_000_000_000, - compute_overhead_part: 1.0, - pubdata_overhead_part: 0.0, - batch_overhead_l1_gas: 700_000, - max_gas_per_batch: 500_000_000, - max_pubdata_per_batch: 100_000, - }; - - let params = FeeParamsV2::new( - config, - GIANT_L1_GAS_PRICE, - GIANT_L1_GAS_PRICE, - BaseTokenConversionRatio::default(), - ); - - let input = compute_batch_fee_model_input_v2(params, 1.0, 1.0); - assert_eq!(input.l1_gas_price, GIANT_L1_GAS_PRICE); - // The fair L2 gas price is identical to the minimal one, plus the overhead - assert_eq!(input.fair_l2_gas_price, 240_000_000_000); - // The fair pubdata price is equal to the original one. - assert_eq!(input.fair_pubdata_price, GIANT_L1_GAS_PRICE); - } - - #[test] - fn test_compute_batch_fee_model_input_v2_param_tweaking() { - // In this test we generally checking that each param behaves as expected - let base_config = FeeModelConfigV2 { - minimal_l2_gas_price: 100_000_000_000, - compute_overhead_part: 0.5, - pubdata_overhead_part: 0.5, - batch_overhead_l1_gas: 700_000, - max_gas_per_batch: 500_000_000, - max_pubdata_per_batch: 100_000, - }; - - let base_params = FeeParamsV2::new( - base_config, - 1_000_000_000, - 1_000_000_000, - BaseTokenConversionRatio::default(), - ); - - let base_input = compute_batch_fee_model_input_v2(base_params, 1.0, 1.0); - - let base_input_larger_l1_gas_price = compute_batch_fee_model_input_v2( - FeeParamsV2::new( - base_config, - 2_000_000_000, // double the L1 gas price - 1_000_000_000, - BaseTokenConversionRatio::default(), - ), - 1.0, - 1.0, - ); - let base_input_scaled_l1_gas_price = - compute_batch_fee_model_input_v2(base_params, 2.0, 1.0); - assert_eq!( - base_input_larger_l1_gas_price, base_input_scaled_l1_gas_price, - "Scaling has the correct effect for the L1 gas price" - ); - assert!( - base_input.fair_l2_gas_price < base_input_larger_l1_gas_price.fair_l2_gas_price, - "L1 gas price increase raises L2 gas price" - ); - assert!( - base_input.fair_pubdata_price < base_input_larger_l1_gas_price.fair_pubdata_price, - "L1 gas price increase raises pubdata price" - ); - - let base_input_larger_pubdata_price = compute_batch_fee_model_input_v2( - FeeParamsV2::new( - base_config, - 1_000_000_000, - 2_000_000_000, // double the L1 pubdata price - BaseTokenConversionRatio::default(), - ), - 1.0, - 1.0, - ); - let base_input_scaled_pubdata_price = - compute_batch_fee_model_input_v2(base_params, 1.0, 2.0); - assert_eq!( - base_input_larger_pubdata_price, base_input_scaled_pubdata_price, - "Scaling has the correct effect for the pubdata price" - ); - assert_eq!( - base_input.fair_l2_gas_price, base_input_larger_pubdata_price.fair_l2_gas_price, - "L1 pubdata increase has no effect on L2 gas price" - ); - assert!( - base_input.fair_pubdata_price < base_input_larger_pubdata_price.fair_pubdata_price, - "Pubdata price increase raises pubdata price" - ); - - let base_input_larger_max_gas = compute_batch_fee_model_input_v2( - FeeParamsV2::new( - FeeModelConfigV2 { - max_gas_per_batch: base_config.max_gas_per_batch * 2, - ..base_config - }, - base_params.l1_gas_price(), - base_params.l1_pubdata_price(), - BaseTokenConversionRatio::default(), - ), - 1.0, - 1.0, - ); - assert!( - base_input.fair_l2_gas_price > base_input_larger_max_gas.fair_l2_gas_price, - "Max gas increase lowers L2 gas price" - ); - assert_eq!( - base_input.fair_pubdata_price, base_input_larger_max_gas.fair_pubdata_price, - "Max gas increase has no effect on pubdata price" - ); - - let base_input_larger_max_pubdata = compute_batch_fee_model_input_v2( - FeeParamsV2::new( - FeeModelConfigV2 { - max_pubdata_per_batch: base_config.max_pubdata_per_batch * 2, - ..base_config - }, - base_params.l1_gas_price(), - base_params.l1_pubdata_price(), - BaseTokenConversionRatio::default(), - ), - 1.0, - 1.0, - ); - assert_eq!( - base_input.fair_l2_gas_price, base_input_larger_max_pubdata.fair_l2_gas_price, - "Max pubdata increase has no effect on L2 gas price" - ); - assert!( - base_input.fair_pubdata_price > base_input_larger_max_pubdata.fair_pubdata_price, - "Max pubdata increase lowers pubdata price" - ); - } - - #[test] - fn test_compute_batch_fee_model_input_v2_gas_price_over_limit_due_to_l1_gas() { - // In this test we check the gas price limit works as expected - let config = FeeModelConfigV2 { - minimal_l2_gas_price: 100 * GWEI, - compute_overhead_part: 0.5, - pubdata_overhead_part: 0.5, - batch_overhead_l1_gas: 700_000, - max_gas_per_batch: 500_000_000, - max_pubdata_per_batch: 100_000, - }; - - let l1_gas_price = 1_000_000_000 * GWEI; - let params = FeeParamsV2::new( - config, - l1_gas_price, - GIANT_L1_GAS_PRICE, - BaseTokenConversionRatio::default(), - ); - - let input = - clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); - assert_eq!(input.l1_gas_price, l1_gas_price); - // The fair L2 gas price is identical to the maximum - assert_eq!(input.fair_l2_gas_price, 10_000 * GWEI); - assert_eq!(input.fair_pubdata_price, 1_000_000 * GWEI); - } - - #[test] - fn test_compute_batch_fee_model_input_v2_gas_price_over_limit_due_to_conversion_rate() { - // In this test we check the gas price limit works as expected - let config = FeeModelConfigV2 { - minimal_l2_gas_price: GWEI, - compute_overhead_part: 0.5, - pubdata_overhead_part: 0.5, - batch_overhead_l1_gas: 700_000, - max_gas_per_batch: 500_000_000, - max_pubdata_per_batch: 100_000, - }; - - let params = FeeParamsV2::new( - config, - GWEI, - 2 * GWEI, - BaseTokenConversionRatio { - numerator: NonZeroU64::new(3_000_000).unwrap(), - denominator: NonZeroU64::new(1).unwrap(), - }, - ); - - let input = - clip_batch_fee_model_input_v2(compute_batch_fee_model_input_v2(params, 1.0, 1.0)); - assert_eq!(input.l1_gas_price, 3_000_000 * GWEI); - // The fair L2 gas price is identical to the maximum - assert_eq!(input.fair_l2_gas_price, 10_000 * GWEI); - assert_eq!(input.fair_pubdata_price, 1_000_000 * GWEI); - } - #[derive(Debug, Clone)] struct DummyTokenRatioProvider { ratio: BaseTokenConversionRatio, diff --git a/core/node/node_framework/src/implementations/layers/gas_adjuster.rs b/core/node/node_framework/src/implementations/layers/gas_adjuster.rs index 229700289a71..241c4d829beb 100644 --- a/core/node/node_framework/src/implementations/layers/gas_adjuster.rs +++ b/core/node/node_framework/src/implementations/layers/gas_adjuster.rs @@ -1,8 +1,9 @@ use std::sync::Arc; use anyhow::Context; -use zksync_config::{configs::eth_sender::PubdataSendingMode, GasAdjusterConfig, GenesisConfig}; +use zksync_config::{GasAdjusterConfig, GenesisConfig}; use zksync_node_fee_model::l1_gas_price::GasAdjuster; +use zksync_types::pubdata_da::PubdataSendingMode; use crate::{ implementations::resources::{ diff --git a/core/node/node_framework/src/implementations/layers/l1_gas.rs b/core/node/node_framework/src/implementations/layers/l1_gas.rs index 35c4bc3fc205..28f81bb45438 100644 --- a/core/node/node_framework/src/implementations/layers/l1_gas.rs +++ b/core/node/node_framework/src/implementations/layers/l1_gas.rs @@ -1,8 +1,8 @@ use std::sync::Arc; -use zksync_config::configs::chain::StateKeeperConfig; +use zksync_config::configs::chain::{FeeModelVersion, StateKeeperConfig}; use zksync_node_fee_model::{ApiFeeInputProvider, MainNodeFeeInputProvider}; -use zksync_types::fee_model::FeeModelConfig; +use zksync_types::fee_model::{FeeModelConfig, FeeModelConfigV1, FeeModelConfigV2}; use crate::{ implementations::resources::{ @@ -20,7 +20,7 @@ use crate::{ /// Adds several resources that depend on L1 gas price. #[derive(Debug)] pub struct L1GasLayer { - state_keeper_config: StateKeeperConfig, + fee_model_config: FeeModelConfig, } #[derive(Debug, FromContext)] @@ -42,9 +42,25 @@ pub struct Output { } impl L1GasLayer { - pub fn new(state_keeper_config: StateKeeperConfig) -> Self { + pub fn new(state_keeper_config: &StateKeeperConfig) -> Self { Self { - state_keeper_config, + fee_model_config: Self::map_config(state_keeper_config), + } + } + + fn map_config(state_keeper_config: &StateKeeperConfig) -> FeeModelConfig { + match state_keeper_config.fee_model_version { + FeeModelVersion::V1 => FeeModelConfig::V1(FeeModelConfigV1 { + minimal_l2_gas_price: state_keeper_config.minimal_l2_gas_price, + }), + FeeModelVersion::V2 => FeeModelConfig::V2(FeeModelConfigV2 { + minimal_l2_gas_price: state_keeper_config.minimal_l2_gas_price, + compute_overhead_part: state_keeper_config.compute_overhead_part, + pubdata_overhead_part: state_keeper_config.pubdata_overhead_part, + batch_overhead_l1_gas: state_keeper_config.batch_overhead_l1_gas, + max_gas_per_batch: state_keeper_config.max_gas_per_batch, + max_pubdata_per_batch: state_keeper_config.max_pubdata_per_batch, + }), } } } @@ -64,7 +80,7 @@ impl WiringLayer for L1GasLayer { let main_fee_input_provider = Arc::new(MainNodeFeeInputProvider::new( input.gas_adjuster.0.clone(), ratio_provider.0, - FeeModelConfig::from_state_keeper_config(&self.state_keeper_config), + self.fee_model_config, )); let replica_pool = input.replica_pool.get().await?; diff --git a/core/node/state_keeper/src/io/tests/tester.rs b/core/node/state_keeper/src/io/tests/tester.rs index 062fc426e8cc..ad189831bad7 100644 --- a/core/node/state_keeper/src/io/tests/tester.rs +++ b/core/node/state_keeper/src/io/tests/tester.rs @@ -4,7 +4,7 @@ use std::{slice, sync::Arc, time::Duration}; use zksync_base_token_adjuster::NoOpRatioProvider; use zksync_config::{ - configs::{chain::StateKeeperConfig, eth_sender::PubdataSendingMode, wallets::Wallets}, + configs::{chain::StateKeeperConfig, wallets::Wallets}, GasAdjusterConfig, }; use zksync_contracts::BaseSystemContracts; @@ -28,6 +28,7 @@ use zksync_types::{ fee_model::{BatchFeeInput, FeeModelConfig, FeeModelConfigV2}, l2::L2Tx, protocol_version::{L1VerifierConfig, ProtocolSemanticVersion}, + pubdata_da::PubdataSendingMode, system_contracts::get_system_smart_contracts, L2BlockNumber, L2ChainId, PriorityOpId, ProtocolVersionId, H256, }; diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 1408f2b23cd9..dd2df67902ff 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -8522,7 +8522,6 @@ dependencies = [ "once_cell", "prost 0.12.6", "rlp", - "secp256k1", "serde", "serde_json", "serde_with", @@ -8530,7 +8529,6 @@ dependencies = [ "thiserror", "tracing", "zksync_basic_types", - "zksync_config", "zksync_contracts", "zksync_crypto_primitives", "zksync_mini_merkle_tree", diff --git a/zkstack_cli/Cargo.lock b/zkstack_cli/Cargo.lock index 8750de36c753..63561c02b9d8 100644 --- a/zkstack_cli/Cargo.lock +++ b/zkstack_cli/Cargo.lock @@ -6977,7 +6977,6 @@ dependencies = [ "once_cell", "prost 0.12.6", "rlp", - "secp256k1", "serde", "serde_json", "serde_with", @@ -6985,7 +6984,6 @@ dependencies = [ "thiserror", "tracing", "zksync_basic_types", - "zksync_config", "zksync_contracts", "zksync_crypto_primitives", "zksync_mini_merkle_tree",