diff --git a/core/lib/multivm/src/utils.rs b/core/lib/multivm/src/utils.rs index 9f5ae5540c39..88cf3b341422 100644 --- a/core/lib/multivm/src/utils.rs +++ b/core/lib/multivm/src/utils.rs @@ -77,10 +77,19 @@ pub fn get_batch_base_fee(l1_batch_env: &L1BatchEnv, vm_version: VmVersion) -> u pub fn adjust_pubdata_price_for_tx( batch_fee_input: BatchFeeInput, tx_gas_per_pubdata_limit: U256, + max_base_fee: Option, vm_version: VmVersion, ) -> BatchFeeInput { - if U256::from(derive_base_fee_and_gas_per_pubdata(batch_fee_input, vm_version).1) - <= tx_gas_per_pubdata_limit + // If no max base fee was provided, we just use the maximal one for convenience. + let max_base_fee = max_base_fee.unwrap_or(U256::MAX); + let desired_gas_per_pubdata = + tx_gas_per_pubdata_limit.min(get_max_gas_per_pubdata_byte(vm_version).into()); + + let (current_base_fee, current_gas_per_pubdata) = + derive_base_fee_and_gas_per_pubdata(batch_fee_input, vm_version); + + if U256::from(current_gas_per_pubdata) <= desired_gas_per_pubdata + && U256::from(current_base_fee) <= max_base_fee { // gas per pubdata is already smaller than or equal to `tx_gas_per_pubdata_limit`. return batch_fee_input; @@ -88,27 +97,41 @@ pub fn adjust_pubdata_price_for_tx( match batch_fee_input { BatchFeeInput::L1Pegged(fee_input) => { + let current_l2_fair_gas_price = U256::from(fee_input.fair_l2_gas_price); + let fair_l2_gas_price = if max_base_fee < current_l2_fair_gas_price { + max_base_fee + } else { + current_l2_fair_gas_price + }; + // `gasPerPubdata = ceil(17 * l1gasprice / fair_l2_gas_price)` // `gasPerPubdata <= 17 * l1gasprice / fair_l2_gas_price + 1` // `fair_l2_gas_price(gasPerPubdata - 1) / 17 <= l1gasprice` - let new_l1_gas_price = U256::from(fee_input.fair_l2_gas_price) - * (tx_gas_per_pubdata_limit - U256::from(1u32)) - / U256::from(17); + let new_l1_gas_price = + fair_l2_gas_price * (desired_gas_per_pubdata - U256::from(1u32)) / U256::from(17); BatchFeeInput::L1Pegged(L1PeggedBatchFeeModelInput { l1_gas_price: new_l1_gas_price.as_u64(), - ..fee_input + fair_l2_gas_price: fair_l2_gas_price.as_u64(), }) } BatchFeeInput::PubdataIndependent(fee_input) => { + let current_l2_fair_gas_price = U256::from(fee_input.fair_l2_gas_price); + let fair_l2_gas_price = if max_base_fee < current_l2_fair_gas_price { + max_base_fee + } else { + current_l2_fair_gas_price + }; + // `gasPerPubdata = ceil(fair_pubdata_price / fair_l2_gas_price)` // `gasPerPubdata <= fair_pubdata_price / fair_l2_gas_price + 1` // `fair_l2_gas_price(gasPerPubdata - 1) <= fair_pubdata_price` - let new_fair_pubdata_price = U256::from(fee_input.fair_l2_gas_price) - * (tx_gas_per_pubdata_limit - U256::from(1u32)); + let new_fair_pubdata_price = + fair_l2_gas_price * (desired_gas_per_pubdata - U256::from(1u32)); BatchFeeInput::PubdataIndependent(PubdataIndependentBatchFeeModelInput { fair_pubdata_price: new_fair_pubdata_price.as_u64(), + fair_l2_gas_price: fair_l2_gas_price.as_u64(), ..fee_input }) } diff --git a/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs b/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs index 9eaa698aef95..147c8743bdb9 100644 --- a/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs +++ b/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs @@ -266,6 +266,7 @@ impl<'a> Sandbox<'a> { self.l1_batch_env.fee_input = adjust_pubdata_price_for_tx( self.l1_batch_env.fee_input, tx.gas_per_pubdata_byte_limit(), + self.l1_batch_env.enforced_base_fee.map(U256::from), protocol_version.into(), ); }; diff --git a/core/lib/zksync_core/src/api_server/tx_sender/mod.rs b/core/lib/zksync_core/src/api_server/tx_sender/mod.rs index cceea1fa16e2..1dfb63b6a01a 100644 --- a/core/lib/zksync_core/src/api_server/tx_sender/mod.rs +++ b/core/lib/zksync_core/src/api_server/tx_sender/mod.rs @@ -12,7 +12,6 @@ use zksync_config::configs::{api::Web3JsonRpcConfig, chain::StateKeeperConfig}; use zksync_contracts::BaseSystemContracts; use zksync_dal::{transactions_dal::L2TxSubmissionResult, ConnectionPool, StorageProcessor}; use zksync_state::PostgresStorageCaches; -use zksync_system_constants::DEFAULT_L2_TX_GAS_PER_PUBDATA_BYTE; use zksync_types::{ fee::{Fee, TransactionExecutionMetrics}, fee_model::BatchFeeInput, @@ -651,6 +650,9 @@ impl TxSender { adjust_pubdata_price_for_tx( fee_input, tx.gas_per_pubdata_byte_limit(), + // We do not have to adjust the params to the `gasPrice` of the transaction, since + // its gas price will be amended later on to suit the `fee_input` + None, protocol_version.into(), ) }; @@ -704,9 +706,6 @@ impl TxSender { if l2_common_data.signature.is_empty() { l2_common_data.signature = PackedEthSignature::default().serialize_packed().into(); } - - l2_common_data.fee.gas_per_pubdata_limit = - U256::from(DEFAULT_L2_TX_GAS_PER_PUBDATA_BYTE); } // Acquire the vm token for the whole duration of the binary search.