Skip to content

Commit

Permalink
feat(vm): Make utils version-dependent (matter-labs#809)
Browse files Browse the repository at this point in the history
## What ❔

In the new 1.4.1 version, the fee formulas as well as max txs per batch
will change. We'll prepare the main branch for it first to reduce the
diff

## Why ❔

<!-- Why are these changes done? What goal do they contribute to? What
are the principles behind them? -->
<!-- Example: PR templates ensure PR reviewers, observers, and future
iterators are in context about the evolution of repos. -->

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.
- [ ] Spellcheck has been run via `cargo spellcheck
--cfg=./spellcheck/era.cfg --code 1`.
  • Loading branch information
StanislavBreadless authored Jan 5, 2024
1 parent 39f2d50 commit e5fbcb5
Show file tree
Hide file tree
Showing 40 changed files with 482 additions and 222 deletions.
7 changes: 4 additions & 3 deletions core/bin/system-constants-generator/src/intrinsic_costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//! as well as contracts/SystemConfig.json
//!
use multivm::vm_latest::constants::BOOTLOADER_TX_ENCODING_SPACE;
use zksync_types::{ethabi::Address, IntrinsicSystemGasConstants, U256};
use multivm::utils::get_bootloader_encoding_space;
use zksync_types::{ethabi::Address, IntrinsicSystemGasConstants, ProtocolVersionId, U256};

use crate::utils::{
execute_internal_transfer_test, execute_user_txs_in_test_gas_vm, get_l1_tx, get_l1_txs,
Expand Down Expand Up @@ -129,7 +129,8 @@ pub(crate) fn l2_gas_constants() -> IntrinsicSystemGasConstants {
tx_with_more_factory_deps_result.pubdata_published - empty_l1_tx_result.pubdata_published;

// The number of the bootloader memory that can be filled up with transactions.
let bootloader_tx_memory_size_slots = BOOTLOADER_TX_ENCODING_SPACE;
let bootloader_tx_memory_size_slots =
get_bootloader_encoding_space(ProtocolVersionId::latest().into());

IntrinsicSystemGasConstants {
l2_tx_intrinsic_gas,
Expand Down
25 changes: 17 additions & 8 deletions core/bin/system-constants-generator/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::fs;

use codegen::{Block, Scope};
use multivm::vm_latest::constants::{
BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_L1_GAS, BOOTLOADER_TX_ENCODING_SPACE, MAX_PUBDATA_PER_BLOCK,
use multivm::{
utils::{get_bootloader_encoding_space, get_bootloader_max_txs_in_batch},
vm_latest::constants::{BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_L1_GAS, MAX_PUBDATA_PER_BLOCK},
};
use serde::{Deserialize, Serialize};
use zksync_types::{
Expand All @@ -13,8 +14,8 @@ use zksync_types::{
},
system_params::MAX_TX_ERGS_LIMIT,
},
IntrinsicSystemGasConstants, GUARANTEED_PUBDATA_IN_TX, L1_GAS_PER_PUBDATA_BYTE,
MAX_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, MAX_TXS_IN_BLOCK,
IntrinsicSystemGasConstants, ProtocolVersionId, GUARANTEED_PUBDATA_IN_TX,
L1_GAS_PER_PUBDATA_BYTE, MAX_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS,
};

mod intrinsic_costs;
Expand Down Expand Up @@ -57,8 +58,12 @@ pub fn generate_l1_contracts_system_config(gas_constants: &IntrinsicSystemGasCon
l1_gas_per_pubdata_byte: L1_GAS_PER_PUBDATA_BYTE,
block_overhead_l2_gas: BLOCK_OVERHEAD_GAS,
block_overhead_l1_gas: BLOCK_OVERHEAD_L1_GAS,
max_transactions_in_block: MAX_TXS_IN_BLOCK as u32,
bootloader_tx_encoding_space: BOOTLOADER_TX_ENCODING_SPACE,
max_transactions_in_block: get_bootloader_max_txs_in_batch(
ProtocolVersionId::latest().into(),
) as u32,
bootloader_tx_encoding_space: get_bootloader_encoding_space(
ProtocolVersionId::latest().into(),
),

l1_tx_intrinsic_l2_gas: gas_constants.l1_tx_intrinsic_gas,
l1_tx_intrinsic_pubdata: gas_constants.l1_tx_intrinsic_pubdata,
Expand Down Expand Up @@ -98,15 +103,19 @@ pub fn generate_l2_contracts_system_config(gas_constants: &IntrinsicSystemGasCon
let l2_contracts_config = L2SystemConfig {
guaranteed_pubdata_bytes: GUARANTEED_PUBDATA_IN_TX,
max_pubdata_per_block: MAX_PUBDATA_PER_BLOCK,
max_transactions_in_block: MAX_TXS_IN_BLOCK as u32,
max_transactions_in_block: get_bootloader_max_txs_in_batch(
ProtocolVersionId::latest().into(),
) as u32,
block_overhead_l2_gas: BLOCK_OVERHEAD_GAS,
block_overhead_l1_gas: BLOCK_OVERHEAD_L1_GAS,
l2_tx_intrinsic_gas: gas_constants.l2_tx_intrinsic_gas,
l2_tx_intrinsic_pubdata: gas_constants.l2_tx_intrinsic_pubdata,
l1_tx_intrinsic_l2_gas: gas_constants.l1_tx_intrinsic_gas,
l1_tx_intrinsic_pubdata: gas_constants.l1_tx_intrinsic_pubdata,
max_gas_per_transaction: MAX_TX_ERGS_LIMIT,
bootloader_memory_for_txs: BOOTLOADER_TX_ENCODING_SPACE,
bootloader_memory_for_txs: get_bootloader_encoding_space(
ProtocolVersionId::latest().into(),
),
refund_gas: gas_constants.l2_tx_gas_for_refund_transfer,
keccak_round_cost_gas: KECCAK256_CIRCUIT_COST_IN_ERGS,
sha256_round_cost_gas: SHA256_CIRCUIT_COST_IN_ERGS,
Expand Down
2 changes: 0 additions & 2 deletions core/lib/constants/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ pub const MAX_BYTES_PER_PACKED_SLOT: u64 = 65;
pub static GAS_PER_SLOT: Lazy<BigUint> =
Lazy::new(|| BigUint::from(MAX_BYTES_PER_PACKED_SLOT) * BigUint::from(GAS_PER_PUBDATA_BYTE));

pub const MAX_TXS_IN_BLOCK: usize = 1024;

pub const MAX_NEW_FACTORY_DEPS: usize = 32;

pub const PAD_MSG_BEFORE_HASH_BITS_LEN: usize = 736;
Expand Down
1 change: 1 addition & 0 deletions core/lib/multivm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ pub use crate::{
mod glue;
pub mod interface;
pub mod tracers;
pub mod utils;
pub mod versions;
mod vm_instance;
164 changes: 164 additions & 0 deletions core/lib/multivm/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
use zksync_types::{VmVersion, U256};

/// Calculates the base fee and gas per pubdata for the given L1 gas price.
pub fn derive_base_fee_and_gas_per_pubdata(
l1_gas_price: u64,
fair_gas_price: u64,
vm_version: VmVersion,
) -> (u64, u64) {
match vm_version {
VmVersion::M5WithRefunds | VmVersion::M5WithoutRefunds => {
crate::vm_m5::vm_with_bootloader::derive_base_fee_and_gas_per_pubdata(
l1_gas_price,
fair_gas_price,
)
}
VmVersion::M6Initial | VmVersion::M6BugWithCompressionFixed => {
crate::vm_m6::vm_with_bootloader::derive_base_fee_and_gas_per_pubdata(
l1_gas_price,
fair_gas_price,
)
}
VmVersion::Vm1_3_2 => {
crate::vm_1_3_2::vm_with_bootloader::derive_base_fee_and_gas_per_pubdata(
l1_gas_price,
fair_gas_price,
)
}
VmVersion::VmVirtualBlocks => {
crate::vm_virtual_blocks::utils::fee::derive_base_fee_and_gas_per_pubdata(
l1_gas_price,
fair_gas_price,
)
}
VmVersion::VmVirtualBlocksRefundsEnhancement => {
crate::vm_refunds_enhancement::utils::fee::derive_base_fee_and_gas_per_pubdata(
l1_gas_price,
fair_gas_price,
)
}
VmVersion::VmBoojumIntegration => {
crate::vm_boojum_integration::utils::fee::derive_base_fee_and_gas_per_pubdata(
l1_gas_price,
fair_gas_price,
)
}
}
}

/// Changes the fee model output so that the expected gas per pubdata is smaller than or the `tx_gas_per_pubdata_limit`.
pub fn adjust_l1_gas_price_for_tx(
l1_gas_price: u64,
fair_l2_gas_price: u64,
tx_gas_per_pubdata_limit: U256,
vm_version: VmVersion,
) -> u64 {
if U256::from(
derive_base_fee_and_gas_per_pubdata(l1_gas_price, fair_l2_gas_price, vm_version).1,
) <= tx_gas_per_pubdata_limit
{
return l1_gas_price;
}

// The latest VM supports adjusting the pubdata price for all the types of the fee models.
crate::vm_latest::utils::fee::adjust_l1_gas_price_for_tx(
fair_l2_gas_price,
tx_gas_per_pubdata_limit,
)
}

pub fn derive_overhead(
gas_limit: u32,
gas_price_per_pubdata: u32,
encoded_len: usize,
tx_type: u8,
vm_version: VmVersion,
) -> u32 {
match vm_version {
VmVersion::M5WithRefunds | VmVersion::M5WithoutRefunds => {
crate::vm_m5::transaction_data::derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
)
}
VmVersion::M6Initial | VmVersion::M6BugWithCompressionFixed => {
crate::vm_m6::transaction_data::derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
crate::vm_m6::transaction_data::OverheadCoefficients::from_tx_type(tx_type),
)
}
VmVersion::Vm1_3_2 => crate::vm_1_3_2::transaction_data::derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
crate::vm_1_3_2::transaction_data::OverheadCoefficients::from_tx_type(tx_type),
),
VmVersion::VmVirtualBlocks => crate::vm_virtual_blocks::utils::overhead::derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
crate::vm_virtual_blocks::utils::overhead::OverheadCoefficients::from_tx_type(tx_type),
),
VmVersion::VmVirtualBlocksRefundsEnhancement => {
crate::vm_refunds_enhancement::utils::overhead::derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
crate::vm_refunds_enhancement::utils::overhead::OverheadCoefficients::from_tx_type(
tx_type,
),
)
}
VmVersion::VmBoojumIntegration => {
crate::vm_boojum_integration::utils::overhead::derive_overhead(
gas_limit,
gas_price_per_pubdata,
encoded_len,
crate::vm_boojum_integration::utils::overhead::OverheadCoefficients::from_tx_type(
tx_type,
),
)
}
}
}

pub fn get_bootloader_encoding_space(version: VmVersion) -> u32 {
match version {
VmVersion::M5WithRefunds | VmVersion::M5WithoutRefunds => {
crate::vm_m5::vm_with_bootloader::BOOTLOADER_TX_ENCODING_SPACE
}
VmVersion::M6Initial | VmVersion::M6BugWithCompressionFixed => {
crate::vm_m6::vm_with_bootloader::BOOTLOADER_TX_ENCODING_SPACE
}
VmVersion::Vm1_3_2 => crate::vm_1_3_2::vm_with_bootloader::BOOTLOADER_TX_ENCODING_SPACE,
VmVersion::VmVirtualBlocks => {
crate::vm_virtual_blocks::constants::BOOTLOADER_TX_ENCODING_SPACE
}
VmVersion::VmVirtualBlocksRefundsEnhancement => {
crate::vm_refunds_enhancement::constants::BOOTLOADER_TX_ENCODING_SPACE
}
VmVersion::VmBoojumIntegration => {
crate::vm_boojum_integration::constants::BOOTLOADER_TX_ENCODING_SPACE
}
}
}

pub fn get_bootloader_max_txs_in_batch(version: VmVersion) -> usize {
match version {
VmVersion::M5WithRefunds | VmVersion::M5WithoutRefunds => {
crate::vm_m5::vm_with_bootloader::MAX_TXS_IN_BLOCK
}
VmVersion::M6Initial | VmVersion::M6BugWithCompressionFixed => {
crate::vm_m6::vm_with_bootloader::MAX_TXS_IN_BLOCK
}
VmVersion::Vm1_3_2 => crate::vm_1_3_2::vm_with_bootloader::MAX_TXS_IN_BLOCK,
VmVersion::VmVirtualBlocks => crate::vm_virtual_blocks::constants::MAX_TXS_IN_BLOCK,
VmVersion::VmVirtualBlocksRefundsEnhancement => {
crate::vm_refunds_enhancement::constants::MAX_TXS_IN_BLOCK
}
VmVersion::VmBoojumIntegration => crate::vm_boojum_integration::constants::MAX_TXS_IN_BLOCK,
}
}
6 changes: 3 additions & 3 deletions core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use zksync_types::{
fee::encoding_len,
l1::is_l1_tx_type,
l2::TransactionType,
ExecuteTransactionCommon, Transaction, MAX_L2_TX_GAS_LIMIT, MAX_TXS_IN_BLOCK, U256,
ExecuteTransactionCommon, Transaction, MAX_L2_TX_GAS_LIMIT, U256,
};
use zksync_utils::{
address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, ceil_div_u256, h256_to_u256,
};

use crate::vm_1_3_2::vm_with_bootloader::{
BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE,
BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK,
};

// This structure represents the data that is used by
Expand Down Expand Up @@ -229,7 +229,7 @@ impl TransactionData {
}
}

pub fn derive_overhead(
pub(crate) fn derive_overhead(
gas_limit: u32,
gas_price_per_pubdata: u32,
encoded_len: usize,
Expand Down
2 changes: 1 addition & 1 deletion core/lib/multivm/src/versions/vm_1_3_2/vm_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use zk_evm_1_3_3::{
},
};
use zksync_state::WriteStorage;
use zksync_system_constants::MAX_TXS_IN_BLOCK;
use zksync_types::{
l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log},
tx::tx_execution_info::TxExecutionStatus,
Expand Down Expand Up @@ -162,6 +161,7 @@ pub enum VmExecutionStopReason {
TracerRequestedStop,
}

use super::vm_with_bootloader::MAX_TXS_IN_BLOCK;
use crate::vm_1_3_2::utils::VmExecutionResult as NewVmExecutionResult;

fn vm_may_have_ended_inner<S: WriteStorage, H: HistoryMode>(
Expand Down
11 changes: 8 additions & 3 deletions core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use zk_evm_1_3_3::{
};
use zksync_contracts::BaseSystemContracts;
use zksync_state::WriteStorage;
use zksync_system_constants::MAX_TXS_IN_BLOCK;
use zksync_types::{
l1::is_l1_tx_type, zkevm_test_harness::INITIAL_MONOTONIC_CYCLE_COUNTER, Address, Transaction,
BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS,
Expand Down Expand Up @@ -84,7 +83,10 @@ pub fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 {
ceil_div(eth_price_per_pubdata_byte, base_fee)
}

pub fn derive_base_fee_and_gas_per_pubdata(l1_gas_price: u64, fair_gas_price: u64) -> (u64, u64) {
pub(crate) fn derive_base_fee_and_gas_per_pubdata(
l1_gas_price: u64,
fair_gas_price: u64,
) -> (u64, u64) {
let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price);

// The baseFee is set in such a way that it is always possible for a transaction to
Expand All @@ -109,6 +111,9 @@ impl From<BlockContext> for DerivedBlockContext {
}
}

// The maximal number of transactions in a single batch
pub(crate) const MAX_TXS_IN_BLOCK: usize = 1024;

// The first 32 slots are reserved for debugging purposes
pub const DEBUG_SLOTS_OFFSET: usize = 8;
pub const DEBUG_FIRST_SLOTS: usize = 32;
Expand Down Expand Up @@ -151,7 +156,7 @@ pub const BOOTLOADER_TX_DESCRIPTION_OFFSET: usize =
COMPRESSED_BYTECODES_OFFSET + COMPRESSED_BYTECODES_SLOTS;

// The size of the bootloader memory dedicated to the encodings of transactions
pub const BOOTLOADER_TX_ENCODING_SPACE: u32 =
pub(crate) const BOOTLOADER_TX_ENCODING_SPACE: u32 =
(USED_BOOTLOADER_MEMORY_WORDS - TX_DESCRIPTION_OFFSET - MAX_TXS_IN_BLOCK) as u32;

// Size of the bootloader tx description in words
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ pub use zk_evm_1_4_0::zkevm_opcode_defs::system_params::{
ERGS_PER_CIRCUIT, INITIAL_STORAGE_WRITE_PUBDATA_BYTES, MAX_PUBDATA_PER_BLOCK,
};
use zksync_system_constants::{
L1_GAS_PER_PUBDATA_BYTE, MAX_L2_TX_GAS_LIMIT, MAX_NEW_FACTORY_DEPS, MAX_TXS_IN_BLOCK,
L1_GAS_PER_PUBDATA_BYTE, MAX_L2_TX_GAS_LIMIT, MAX_NEW_FACTORY_DEPS,
USED_BOOTLOADER_MEMORY_WORDS,
};

use crate::vm_boojum_integration::old_vm::utils::heap_page_from_base;

// The maximal number of transactions in a single batch
pub(crate) const MAX_TXS_IN_BLOCK: usize = 1024;

/// Max cycles for a single transaction.
pub const MAX_CYCLES_FOR_TX: u32 = u32::MAX;

Expand Down Expand Up @@ -69,7 +72,7 @@ pub(crate) const BOOTLOADER_TX_DESCRIPTION_OFFSET: usize =
OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS;

/// The size of the bootloader memory dedicated to the encodings of transactions
pub const BOOTLOADER_TX_ENCODING_SPACE: u32 =
pub(crate) const BOOTLOADER_TX_ENCODING_SPACE: u32 =
(USED_BOOTLOADER_MEMORY_WORDS - TX_DESCRIPTION_OFFSET - MAX_TXS_IN_BLOCK) as u32;

// Size of the bootloader tx description in words
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ pub fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 {
}

/// Calculates the base fee and gas per pubdata for the given L1 gas price.
pub fn derive_base_fee_and_gas_per_pubdata(l1_gas_price: u64, fair_gas_price: u64) -> (u64, u64) {
pub(crate) fn derive_base_fee_and_gas_per_pubdata(
l1_gas_price: u64,
fair_gas_price: u64,
) -> (u64, u64) {
let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price);

// The baseFee is set in such a way that it is always possible for a transaction to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use zk_evm_1_4_0::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT;
use zksync_system_constants::{MAX_L2_TX_GAS_LIMIT, MAX_TXS_IN_BLOCK};
use zksync_system_constants::MAX_L2_TX_GAS_LIMIT;
use zksync_types::{l1::is_l1_tx_type, U256};
use zksync_utils::ceil_div_u256;

use crate::vm_boojum_integration::constants::{
BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE,
BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK,
};

/// Derives the overhead for processing transactions in a block.
pub fn derive_overhead(
pub(crate) fn derive_overhead(
gas_limit: u32,
gas_price_per_pubdata: u32,
encoded_len: usize,
Expand Down
Loading

0 comments on commit e5fbcb5

Please sign in to comment.