diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index a0ce9786279..e189fdb7d43 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -35,6 +35,7 @@ impl ETHSenderConfig { l1_batch_min_age_before_execute_seconds: None, max_acceptable_priority_fee_in_gwei: 100000000000, proof_loading_mode: ProofLoadingMode::OldProofFromDb, + pubdata_sending_mode: PubdataSendingMode::Calldata, }, gas_adjuster: GasAdjusterConfig { default_priority_fee_per_gas: 1000000000, @@ -63,6 +64,13 @@ pub enum ProofLoadingMode { FriProofFromGcs, } +#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Default)] +pub enum PubdataSendingMode { + #[default] + Calldata, + Blobs, +} + #[derive(Debug, Deserialize, Clone, PartialEq)] pub struct SenderConfig { pub aggregated_proof_sizes: Vec, @@ -96,6 +104,9 @@ pub struct SenderConfig { /// The mode in which proofs are loaded, either from DB/GCS for FRI/Old proof. pub proof_loading_mode: ProofLoadingMode, + + /// The mode in which we send pubdata, either Calldata or Blobs + pub pubdata_sending_mode: PubdataSendingMode, } impl SenderConfig { diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index ab2ef1da0f8..b3788b51942 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -5,7 +5,7 @@ use zksync_basic_types::{ basic_fri_types::CircuitIdRoundTuple, network::Network, Address, L2ChainId, H256, }; -use crate::configs; +use crate::configs::{self, eth_sender::PubdataSendingMode}; /// Generator of random configs. pub struct Gen<'a, R: Rng> { @@ -461,6 +461,15 @@ impl RandomConfig for configs::eth_sender::ProofLoadingMode { } } +impl RandomConfig for configs::eth_sender::PubdataSendingMode { + fn sample(g: &mut Gen) -> Self { + match g.rng.gen_range(0..2) { + 0 => Self::Calldata, + _ => Self::Blobs, + } + } +} + impl RandomConfig for configs::eth_sender::SenderConfig { fn sample(g: &mut Gen) -> Self { Self { @@ -481,6 +490,7 @@ impl RandomConfig for configs::eth_sender::SenderConfig { l1_batch_min_age_before_execute_seconds: g.gen(), max_acceptable_priority_fee_in_gwei: g.gen(), proof_loading_mode: g.gen(), + pubdata_sending_mode: PubdataSendingMode::Calldata, } } } diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index f0ee6030b02..d72abcffeb3 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -26,7 +26,9 @@ impl FromEnv for GasAdjusterConfig { #[cfg(test)] mod tests { - use zksync_config::configs::eth_sender::{ProofLoadingMode, ProofSendingMode}; + use zksync_config::configs::eth_sender::{ + ProofLoadingMode, ProofSendingMode, PubdataSendingMode, + }; use super::*; use crate::test_utils::{hash, EnvMutex}; @@ -54,6 +56,7 @@ mod tests { l1_batch_min_age_before_execute_seconds: Some(1000), max_acceptable_priority_fee_in_gwei: 100_000_000_000, proof_loading_mode: ProofLoadingMode::OldProofFromDb, + pubdata_sending_mode: PubdataSendingMode::Calldata, }, gas_adjuster: GasAdjusterConfig { default_priority_fee_per_gas: 20000000000, @@ -98,6 +101,7 @@ mod tests { ETH_SENDER_SENDER_L1_BATCH_MIN_AGE_BEFORE_EXECUTE_SECONDS="1000" ETH_SENDER_SENDER_MAX_ACCEPTABLE_PRIORITY_FEE_IN_GWEI="100000000000" ETH_SENDER_SENDER_PROOF_LOADING_MODE="OldProofFromDb" + ETH_SENDER_SENDER_PUBDATA_SENDING_MODE="Calldata" "#; lock.set_env(config); diff --git a/core/lib/protobuf_config/src/eth_sender.rs b/core/lib/protobuf_config/src/eth_sender.rs index 6d6f430b2c7..1f6c59e2e86 100644 --- a/core/lib/protobuf_config/src/eth_sender.rs +++ b/core/lib/protobuf_config/src/eth_sender.rs @@ -1,5 +1,5 @@ use anyhow::Context as _; -use zksync_config::configs; +use zksync_config::configs::{self}; use zksync_protobuf::required; use crate::{ @@ -45,6 +45,24 @@ impl proto::ProofLoadingMode { } } +impl proto::PubdataSendingMode { + fn new(x: &configs::eth_sender::PubdataSendingMode) -> Self { + use configs::eth_sender::PubdataSendingMode as From; + match x { + From::Calldata => Self::Calldata, + From::Blobs => Self::Blobs, + } + } + + fn parse(&self) -> configs::eth_sender::PubdataSendingMode { + use configs::eth_sender::PubdataSendingMode as To; + match self { + Self::Calldata => To::Calldata, + Self::Blobs => To::Blobs, + } + } +} + impl ProtoRepr for proto::EthSender { type Type = configs::eth_sender::ETHSenderConfig; fn read(&self) -> anyhow::Result { @@ -109,6 +127,10 @@ impl ProtoRepr for proto::Sender { .and_then(|x| Ok(proto::ProofLoadingMode::try_from(*x)?)) .context("proof_loading_mode")? .parse(), + pubdata_sending_mode: required(&self.pubdata_sending_mode) + .and_then(|x| Ok(proto::PubdataSendingMode::try_from(*x)?)) + .context("pubdata_sending_mode")? + .parse(), }) } @@ -137,6 +159,9 @@ impl ProtoRepr for proto::Sender { l1_batch_min_age_before_execute_seconds: this.l1_batch_min_age_before_execute_seconds, max_acceptable_priority_fee_in_gwei: Some(this.max_acceptable_priority_fee_in_gwei), proof_loading_mode: Some(proto::ProofLoadingMode::new(&this.proof_loading_mode).into()), + pubdata_sending_mode: Some( + proto::PubdataSendingMode::new(&this.pubdata_sending_mode).into(), + ), } } } diff --git a/core/lib/protobuf_config/src/proto/eth_sender.proto b/core/lib/protobuf_config/src/proto/eth_sender.proto index b5e866d0412..3a2e033c91a 100644 --- a/core/lib/protobuf_config/src/proto/eth_sender.proto +++ b/core/lib/protobuf_config/src/proto/eth_sender.proto @@ -18,6 +18,11 @@ enum ProofLoadingMode { FRI_PROOF_FROM_GCS = 1; } +enum PubdataSendingMode { + CALLDATA = 0; + BLOBS = 1; +} + message Sender { repeated uint64 aggregated_proof_sizes = 1; // ? optional uint64 wait_confirmations = 2; // optional @@ -37,6 +42,7 @@ message Sender { optional uint64 max_acceptable_priority_fee_in_gwei = 16; // required; gwei optional ProofLoadingMode proof_loading_mode = 17; // required // operator_private_key? + optional PubdataSendingMode pubdata_sending_mode = 18; // required } message GasAdjuster { diff --git a/core/lib/zksync_core/src/state_keeper/seal_criteria/conditional_sealer.rs b/core/lib/zksync_core/src/state_keeper/seal_criteria/conditional_sealer.rs index 4effb257f02..cc383ae16cb 100644 --- a/core/lib/zksync_core/src/state_keeper/seal_criteria/conditional_sealer.rs +++ b/core/lib/zksync_core/src/state_keeper/seal_criteria/conditional_sealer.rs @@ -116,7 +116,7 @@ impl ConditionalSealer for SequencerSealer { impl SequencerSealer { pub fn new(config: StateKeeperConfig) -> Self { - let sealers = Self::default_sealers(); + let sealers = Self::default_sealers(&config); Self { config, sealers } } @@ -128,11 +128,13 @@ impl SequencerSealer { Self { config, sealers } } - fn default_sealers() -> Vec> { + fn default_sealers(config: &StateKeeperConfig) -> Vec> { vec![ Box::new(criteria::SlotsCriterion), Box::new(criteria::GasCriterion), - Box::new(criteria::PubDataBytesCriterion), + Box::new(criteria::PubDataBytesCriterion { + max_pubdata_per_batch: config.max_pubdata_per_batch, + }), Box::new(criteria::CircuitsCriterion), Box::new(criteria::TxEncodingSizeCriterion), Box::new(criteria::GasForBatchTipCriterion), diff --git a/core/lib/zksync_core/src/state_keeper/seal_criteria/criteria/pubdata_bytes.rs b/core/lib/zksync_core/src/state_keeper/seal_criteria/criteria/pubdata_bytes.rs index ec778cdf083..593bb1aec2e 100644 --- a/core/lib/zksync_core/src/state_keeper/seal_criteria/criteria/pubdata_bytes.rs +++ b/core/lib/zksync_core/src/state_keeper/seal_criteria/criteria/pubdata_bytes.rs @@ -1,11 +1,17 @@ -use zksync_types::{ProtocolVersionId, MAX_PUBDATA_PER_L1_BATCH}; +use zksync_types::ProtocolVersionId; use crate::state_keeper::seal_criteria::{ SealCriterion, SealData, SealResolution, StateKeeperConfig, }; #[derive(Debug)] -pub struct PubDataBytesCriterion; +pub struct PubDataBytesCriterion { + /// This value changes based on the DA solution. + /// If we use calldata, the limit is `128kb` + /// If we use blobs then the value can be up to `252kb`, up to `126kb` will fill 1 blob, + /// more than that will switch over to 2 blobs. + pub max_pubdata_per_batch: u64, +} impl SealCriterion for PubDataBytesCriterion { fn should_seal( @@ -17,7 +23,7 @@ impl SealCriterion for PubDataBytesCriterion { tx_data: &SealData, protocol_version: ProtocolVersionId, ) -> SealResolution { - let max_pubdata_per_l1_batch = MAX_PUBDATA_PER_L1_BATCH as usize; + let max_pubdata_per_l1_batch = self.max_pubdata_per_batch as usize; let reject_bound = (max_pubdata_per_l1_batch as f64 * config.reject_tx_at_eth_params_percentage).round(); let include_and_seal_bound = @@ -62,13 +68,16 @@ mod tests { let config = StateKeeperConfig { reject_tx_at_eth_params_percentage: 0.95, close_block_at_eth_params_percentage: 0.95, + max_pubdata_per_batch: 100000, ..Default::default() }; - let criterion = PubDataBytesCriterion; + let criterion = PubDataBytesCriterion { + max_pubdata_per_batch: 100000, + }; let block_execution_metrics = ExecutionMetrics { - l2_l1_long_messages: (MAX_PUBDATA_PER_L1_BATCH as f64 + l2_l1_long_messages: (config.max_pubdata_per_batch as f64 * config.close_block_at_eth_params_percentage - 1.0) .round() as usize, @@ -89,7 +98,7 @@ mod tests { assert_eq!(empty_block_resolution, SealResolution::NoSeal); let block_execution_metrics = ExecutionMetrics { - l2_l1_long_messages: (MAX_PUBDATA_PER_L1_BATCH as f64 + l2_l1_long_messages: (config.max_pubdata_per_batch as f64 * config.close_block_at_eth_params_percentage + 1f64) .round() as usize, @@ -110,7 +119,7 @@ mod tests { assert_eq!(full_block_resolution, SealResolution::IncludeAndSeal); let block_execution_metrics = ExecutionMetrics { - l2_l1_long_messages: MAX_PUBDATA_PER_L1_BATCH as usize + 1, + l2_l1_long_messages: config.max_pubdata_per_batch as usize + 1, ..ExecutionMetrics::default() }; let full_block_resolution = criterion.should_seal( diff --git a/etc/env/base/chain.toml b/etc/env/base/chain.toml index 181c7cc8632..b6c7b5093ba 100644 --- a/etc/env/base/chain.toml +++ b/etc/env/base/chain.toml @@ -65,7 +65,10 @@ batch_overhead_l1_gas=800000 # The maximum amount of gas that can be used by the batch. This value is derived from the circuits limitation per batch. max_gas_per_batch=200000000 -# 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. +# This will also determine how many blobs are used, when enabled. +# If the value is less than 126 kb -> Calldata or 1 Blob +# If the value is > 126 kb and < 252 kb then 2 blobs are used. +# Note, the max at this moment is 252 kb max_pubdata_per_batch=100000 # The version of the fee model to use. diff --git a/etc/env/base/eth_sender.toml b/etc/env/base/eth_sender.toml index f95a70c5f96..8e9242f8d1f 100644 --- a/etc/env/base/eth_sender.toml +++ b/etc/env/base/eth_sender.toml @@ -46,6 +46,8 @@ max_acceptable_priority_fee_in_gwei=100000000000 proof_loading_mode="OldProofFromDb" +pubdata_sending_mode="Calldata" + [eth_sender.gas_adjuster] # Priority fee to be used by GasAdjuster (in wei). default_priority_fee_per_gas=1_000_000_000