From 7a8c9d8010ac36baecbbbb2199da48470c2a3db2 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Fri, 11 Oct 2024 18:08:35 +0300 Subject: [PATCH 1/2] Check protocol version for fast VM --- core/lib/multivm/src/lib.rs | 2 +- core/lib/multivm/src/versions/vm_fast/vm.rs | 7 +++++++ core/lib/multivm/src/vm_instance.rs | 10 +++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core/lib/multivm/src/lib.rs b/core/lib/multivm/src/lib.rs index e171a78e1794..520274c14ae0 100644 --- a/core/lib/multivm/src/lib.rs +++ b/core/lib/multivm/src/lib.rs @@ -16,7 +16,7 @@ pub use crate::{ vm_1_3_2, vm_1_4_1, vm_1_4_2, vm_boojum_integration, vm_fast, vm_latest, vm_m5, vm_m6, vm_refunds_enhancement, vm_virtual_blocks, }, - vm_instance::{FastVmInstance, LegacyVmInstance}, + vm_instance::{is_supported_by_fast_vm, FastVmInstance, LegacyVmInstance}, }; mod glue; diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index 0c20af57e033..39c9b3c56566 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -40,6 +40,7 @@ use crate::{ VmExecutionStatistics, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmRevertReason, VmTrackingContracts, }, + is_supported_by_fast_vm, utils::events::extract_l2tol1logs_from_l1_messenger, vm_fast::{ bootloader_state::utils::{apply_l2_block, apply_pubdata_to_memory}, @@ -104,6 +105,12 @@ pub struct Vm { impl Vm { pub fn custom(batch_env: L1BatchEnv, system_env: SystemEnv, storage: S) -> Self { + assert!( + is_supported_by_fast_vm(system_env.version), + "Protocol version {:?} is not supported by fast VM", + system_env.version + ); + let default_aa_code_hash = system_env .base_system_smart_contracts .default_aa diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index ac5693b61619..897070345232 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -1,6 +1,6 @@ use std::mem; -use zksync_types::{vm::VmVersion, Transaction}; +use zksync_types::{vm::VmVersion, ProtocolVersionId, Transaction}; use zksync_vm2::interface::Tracer; use crate::{ @@ -328,3 +328,11 @@ impl FastVmInstance { Self::Shadowed(ShadowedFastVm::new(l1_batch_env, system_env, storage_view)) } } + +/// Checks whether the protocol version is supported by the fast VM. +pub fn is_supported_by_fast_vm(protocol_version: ProtocolVersionId) -> bool { + matches!( + protocol_version.into(), + VmVersion::Vm1_5_0IncreasedBootloaderMemory + ) +} From 1540dd9a5b075d20aad56b2afd08aaf28e2a2f60 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Fri, 11 Oct 2024 18:08:55 +0300 Subject: [PATCH 2/2] Select legacy VM for old protocol versions --- Cargo.lock | 1 + core/lib/vm_executor/Cargo.toml | 3 ++ core/lib/vm_executor/src/batch/factory.rs | 52 +++++++++++++++++++++++ core/lib/vm_executor/src/lib.rs | 2 + core/lib/vm_executor/src/testonly.rs | 45 ++++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 core/lib/vm_executor/src/testonly.rs diff --git a/Cargo.lock b/Cargo.lock index 7b1a268afef5..1c5c9f37b7a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11331,6 +11331,7 @@ name = "zksync_vm_executor" version = "0.1.0" dependencies = [ "anyhow", + "assert_matches", "async-trait", "once_cell", "tokio", diff --git a/core/lib/vm_executor/Cargo.toml b/core/lib/vm_executor/Cargo.toml index 089c2a9bcca7..a967aaa969ad 100644 --- a/core/lib/vm_executor/Cargo.toml +++ b/core/lib/vm_executor/Cargo.toml @@ -23,3 +23,6 @@ tokio.workspace = true anyhow.workspace = true tracing.workspace = true vise.workspace = true + +[dev-dependencies] +assert_matches.workspace = true diff --git a/core/lib/vm_executor/src/batch/factory.rs b/core/lib/vm_executor/src/batch/factory.rs index 146f0bb4e5c8..bc19086c9692 100644 --- a/core/lib/vm_executor/src/batch/factory.rs +++ b/core/lib/vm_executor/src/batch/factory.rs @@ -12,6 +12,7 @@ use zksync_multivm::{ ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, SystemEnv, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, + is_supported_by_fast_vm, tracers::CallTracer, vm_fast, vm_latest::HistoryEnabled, @@ -159,6 +160,10 @@ impl BatchVm { storage_ptr: StoragePtr>, mode: FastVmMode, ) -> Self { + if !is_supported_by_fast_vm(system_env.version) { + return Self::Legacy(LegacyVmInstance::new(l1_batch_env, system_env, storage_ptr)); + } + match mode { FastVmMode::Old => { Self::Legacy(LegacyVmInstance::new(l1_batch_env, system_env, storage_ptr)) @@ -443,3 +448,50 @@ impl CommandReceiver { } } } + +#[cfg(test)] +mod tests { + use assert_matches::assert_matches; + use zksync_multivm::interface::{storage::InMemoryStorage, TxExecutionMode}; + use zksync_types::ProtocolVersionId; + + use super::*; + use crate::testonly::{default_l1_batch_env, default_system_env, FAST_VM_MODES}; + + #[test] + fn selecting_vm_for_execution() { + let l1_batch_env = default_l1_batch_env(1); + let mut system_env = SystemEnv { + version: ProtocolVersionId::Version22, + ..default_system_env(TxExecutionMode::VerifyExecute) + }; + let storage = StorageView::new(InMemoryStorage::default()).to_rc_ptr(); + for mode in FAST_VM_MODES { + let vm = BatchVm::<_, ()>::new( + l1_batch_env.clone(), + system_env.clone(), + storage.clone(), + mode, + ); + assert_matches!(vm, BatchVm::Legacy(_)); + } + + system_env.version = ProtocolVersionId::latest(); + let vm = BatchVm::<_, ()>::new( + l1_batch_env.clone(), + system_env.clone(), + storage.clone(), + FastVmMode::Old, + ); + assert_matches!(vm, BatchVm::Legacy(_)); + let vm = BatchVm::<_, ()>::new( + l1_batch_env.clone(), + system_env.clone(), + storage.clone(), + FastVmMode::New, + ); + assert_matches!(vm, BatchVm::Fast(FastVmInstance::Fast(_))); + let vm = BatchVm::<_, ()>::new(l1_batch_env, system_env, storage, FastVmMode::Shadow); + assert_matches!(vm, BatchVm::Fast(FastVmInstance::Shadowed(_))); + } +} diff --git a/core/lib/vm_executor/src/lib.rs b/core/lib/vm_executor/src/lib.rs index 1a0fbb002df9..83edb77fd629 100644 --- a/core/lib/vm_executor/src/lib.rs +++ b/core/lib/vm_executor/src/lib.rs @@ -9,3 +9,5 @@ pub mod batch; pub mod oneshot; mod shared; pub mod storage; +#[cfg(test)] +mod testonly; diff --git a/core/lib/vm_executor/src/testonly.rs b/core/lib/vm_executor/src/testonly.rs new file mode 100644 index 000000000000..5bcd604a4324 --- /dev/null +++ b/core/lib/vm_executor/src/testonly.rs @@ -0,0 +1,45 @@ +use once_cell::sync::Lazy; +use zksync_contracts::BaseSystemContracts; +use zksync_multivm::{ + interface::{L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode}, + vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, +}; +use zksync_types::{ + block::L2BlockHasher, fee_model::BatchFeeInput, vm::FastVmMode, Address, L1BatchNumber, + L2BlockNumber, L2ChainId, ProtocolVersionId, H256, ZKPORTER_IS_AVAILABLE, +}; + +static BASE_SYSTEM_CONTRACTS: Lazy = + Lazy::new(BaseSystemContracts::load_from_disk); + +pub(crate) const FAST_VM_MODES: [FastVmMode; 3] = + [FastVmMode::Old, FastVmMode::New, FastVmMode::Shadow]; + +pub(crate) fn default_system_env(execution_mode: TxExecutionMode) -> SystemEnv { + SystemEnv { + zk_porter_available: ZKPORTER_IS_AVAILABLE, + version: ProtocolVersionId::latest(), + base_system_smart_contracts: BASE_SYSTEM_CONTRACTS.clone(), + bootloader_gas_limit: BATCH_COMPUTATIONAL_GAS_LIMIT, + execution_mode, + default_validation_computational_gas_limit: BATCH_COMPUTATIONAL_GAS_LIMIT, + chain_id: L2ChainId::default(), + } +} + +pub(crate) fn default_l1_batch_env(number: u32) -> L1BatchEnv { + L1BatchEnv { + previous_batch_hash: Some(H256::zero()), + number: L1BatchNumber(number), + timestamp: number.into(), + fee_account: Address::repeat_byte(0x22), + enforced_base_fee: None, + first_l2_block: L2BlockEnv { + number, + timestamp: number.into(), + prev_block_hash: L2BlockHasher::legacy_hash(L2BlockNumber(number - 1)), + max_virtual_blocks_to_create: 1, + }, + fee_input: BatchFeeInput::sensible_l1_pegged_default(), + } +}