diff --git a/core/bin/system-constants-generator/src/utils.rs b/core/bin/system-constants-generator/src/utils.rs index 96de0537d538..3775b3c0e243 100644 --- a/core/bin/system-constants-generator/src/utils.rs +++ b/core/bin/system-constants-generator/src/utils.rs @@ -10,7 +10,7 @@ use zksync_multivm::{ storage::{InMemoryStorage, StorageView, WriteStorage}, tracer::VmExecutionStopReason, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmFactory, - VmInterface, + VmInterface, VmInterfaceExt, }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ diff --git a/core/lib/multivm/src/glue/types/vm/vm_partial_execution_result.rs b/core/lib/multivm/src/glue/types/vm/vm_partial_execution_result.rs index 320917d3f4f0..3cb61b461a42 100644 --- a/core/lib/multivm/src/glue/types/vm/vm_partial_execution_result.rs +++ b/core/lib/multivm/src/glue/types/vm/vm_partial_execution_result.rs @@ -11,9 +11,9 @@ impl GlueFrom contracts_used: value.contracts_used, cycles_used: value.cycles_used, total_log_queries: value.logs.total_log_queries_count, + gas_remaining: value.gas_remaining, // There are no such fields in `m5`. gas_used: 0, - gas_remaining: 0, computational_gas_used: 0, pubdata_published: 0, circuit_statistic: Default::default(), @@ -37,10 +37,10 @@ impl GlueFrom contracts_used: value.contracts_used, cycles_used: value.cycles_used, computational_gas_used: value.computational_gas_used, + gas_remaining: value.gas_remaining, total_log_queries: value.logs.total_log_queries_count, // There are no such fields in `m6`. gas_used: 0, - gas_remaining: 0, pubdata_published: 0, circuit_statistic: Default::default(), }, @@ -63,10 +63,10 @@ impl GlueFrom contracts_used: value.contracts_used, cycles_used: value.cycles_used, computational_gas_used: value.computational_gas_used, + gas_remaining: value.gas_remaining, total_log_queries: value.logs.total_log_queries_count, // There are no such fields in `1_3_2`. gas_used: 0, - gas_remaining: 0, pubdata_published: 0, circuit_statistic: Default::default(), }, diff --git a/core/lib/multivm/src/versions/shadow.rs b/core/lib/multivm/src/versions/shadow.rs index 6af546318af4..7394c4617509 100644 --- a/core/lib/multivm/src/versions/shadow.rs +++ b/core/lib/multivm/src/versions/shadow.rs @@ -9,10 +9,9 @@ use zksync_types::{StorageKey, StorageLog, StorageLogWithPreviousValue, Transact use crate::{ interface::{ storage::{ImmutableStorageView, ReadStorage, StoragePtr, StorageView}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, - FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, - VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, - VmMemoryMetrics, + BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, + SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, + VmInterfaceHistoryEnabled, VmMemoryMetrics, }, vm_fast, }; @@ -52,18 +51,6 @@ where self.main.push_transaction(tx); } - fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs { - let main_result = self.main.execute(execution_mode); - let shadow_result = self.shadow.execute(execution_mode); - let mut errors = DivergenceErrors::default(); - errors.check_results_match(&main_result, &shadow_result); - errors - .into_result() - .with_context(|| format!("executing VM with mode {execution_mode:?}")) - .unwrap(); - main_result - } - fn inspect( &mut self, dispatcher: Self::TracerDispatcher, @@ -80,73 +67,17 @@ where main_result } - fn get_bootloader_memory(&self) -> BootloaderMemory { - let main_memory = self.main.get_bootloader_memory(); - let shadow_memory = self.shadow.get_bootloader_memory(); - DivergenceErrors::single("get_bootloader_memory", &main_memory, &shadow_memory).unwrap(); - main_memory - } - - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - let main_bytecodes = self.main.get_last_tx_compressed_bytecodes(); - let shadow_bytecodes = self.shadow.get_last_tx_compressed_bytecodes(); - DivergenceErrors::single( - "get_last_tx_compressed_bytecodes", - &main_bytecodes, - &shadow_bytecodes, - ) - .unwrap(); - main_bytecodes - } - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { self.shadow.start_new_l2_block(l2_block_env); self.main.start_new_l2_block(l2_block_env); } - fn get_current_execution_state(&self) -> CurrentExecutionState { - let main_state = self.main.get_current_execution_state(); - let shadow_state = self.shadow.get_current_execution_state(); - DivergenceErrors::single("get_current_execution_state", &main_state, &shadow_state) - .unwrap(); - main_state - } - - fn execute_transaction_with_bytecode_compression( - &mut self, - tx: Transaction, - with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { - let tx_hash = tx.hash(); - let main_result = self - .main - .execute_transaction_with_bytecode_compression(tx.clone(), with_compression); - let shadow_result = self - .shadow - .execute_transaction_with_bytecode_compression(tx, with_compression); - let mut errors = DivergenceErrors::default(); - errors.check_results_match(&main_result.1, &shadow_result.1); - errors - .into_result() - .with_context(|| { - format!("executing transaction {tx_hash:?}, with_compression={with_compression:?}") - }) - .unwrap(); - main_result - } - fn inspect_transaction_with_bytecode_compression( &mut self, tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { let tx_hash = tx.hash(); let main_result = self.main.inspect_transaction_with_bytecode_compression( tracer, @@ -171,13 +102,6 @@ where self.main.record_vm_memory_metrics() } - fn gas_remaining(&self) -> u32 { - let main_gas = self.main.gas_remaining(); - let shadow_gas = self.shadow.gas_remaining(); - DivergenceErrors::single("gas_remaining", &main_gas, &shadow_gas).unwrap(); - main_gas - } - fn finish_batch(&mut self) -> FinishedL1Batch { let main_batch = self.main.finish_batch(); let shadow_batch = self.shadow.finish_batch(); @@ -216,16 +140,6 @@ where pub struct DivergenceErrors(Vec); impl DivergenceErrors { - fn single( - context: &str, - main: &T, - shadow: &T, - ) -> anyhow::Result<()> { - let mut this = Self::default(); - this.check_match(context, main, shadow); - this.into_result() - } - fn check_results_match( &mut self, main_result: &VmExecutionResultAndLogs, @@ -251,6 +165,11 @@ impl DivergenceErrors { let shadow_logs = UniqueStorageLogs::new(&shadow_result.logs.storage_logs); self.check_match("logs.storage_logs", &main_logs, &shadow_logs); self.check_match("refunds", &main_result.refunds, &shadow_result.refunds); + self.check_match( + "gas_remaining", + &main_result.statistics.gas_remaining, + &shadow_result.statistics.gas_remaining, + ); } fn check_match(&mut self, context: &str, main: &T, shadow: &T) { diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs index f86beb2d400d..eb1ae45542db 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs @@ -1,32 +1,25 @@ use std::collections::HashSet; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; -use zksync_types::{ - l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}, - Transaction, -}; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_types::Transaction; +use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; use crate::{ glue::{history_mode::HistoryMode, GlueInto}, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, - FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, - VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, - VmMemoryMetrics, + BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, + L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmExecutionResultAndLogs, + VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, }, tracers::old::TracerDispatcher, utils::bytecode, - vm_1_3_2::{events::merge_events, VmInstance}, + vm_1_3_2::VmInstance, }; #[derive(Debug)] pub struct Vm { pub(crate) vm: VmInstance, pub(crate) system_env: SystemEnv, - pub(crate) batch_env: L1BatchEnv, - pub(crate) last_tx_compressed_bytecodes: Vec, } impl VmInterface for Vm { @@ -81,83 +74,23 @@ impl VmInterface for Vm { } } - fn get_bootloader_memory(&self) -> BootloaderMemory { - vec![] - } - - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.last_tx_compressed_bytecodes.clone() - } - fn start_new_l2_block(&mut self, _l2_block_env: L2BlockEnv) { // Do nothing, because vm 1.3.2 doesn't support L2 blocks } - fn get_current_execution_state(&self) -> CurrentExecutionState { - let (raw_events, l1_messages) = self.vm.state.event_sink.flatten(); - let events = merge_events(raw_events) - .into_iter() - .map(|e| e.into_vm_event(self.batch_env.number)) - .collect(); - let l2_to_l1_logs = l1_messages - .into_iter() - .map(|m| { - UserL2ToL1Log(L2ToL1Log { - shard_id: m.shard_id, - is_service: m.is_first, - tx_number_in_block: m.tx_number_in_block, - sender: m.address, - key: u256_to_h256(m.key), - value: u256_to_h256(m.value), - }) - }) - .collect(); - - let used_contract_hashes = self - .vm - .state - .decommittment_processor - .known_bytecodes - .inner() - .keys() - .cloned() - .collect(); - - let storage_log_queries = self.vm.state.storage.get_final_log_queries(); - - let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; - - CurrentExecutionState { - events, - deduplicated_storage_logs: deduped_storage_log_queries - .into_iter() - .map(GlueInto::glue_into) - .collect(), - used_contract_hashes, - user_l2_to_l1_logs: l2_to_l1_logs, - system_logs: vec![], - // Fields below are not produced by VM 1.3.2 - storage_refunds: vec![], - pubdata_costs: Vec::new(), - } - } - fn inspect_transaction_with_bytecode_compression( &mut self, tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { if let Some(storage_invocations) = tracer.storage_invocations { self.vm .execution_mode .set_invocation_limit(storage_invocations); } - self.last_tx_compressed_bytecodes = vec![]; + + let compressed_bytecodes: Vec<_>; let bytecodes = if with_compression { let deps = &tx.execute.factory_deps; let mut deps_hashes = HashSet::with_capacity(deps.len()); @@ -174,18 +107,17 @@ impl VmInterface for Vm { bytecode::compress(bytecode.clone()).ok() } }); - let compressed_bytecodes: Vec<_> = filtered_deps.collect(); + compressed_bytecodes = filtered_deps.collect(); - self.last_tx_compressed_bytecodes - .clone_from(&compressed_bytecodes); crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory( &mut self.vm, &tx, self.system_env.execution_mode.glue_into(), - Some(compressed_bytecodes), + Some(compressed_bytecodes.clone()), ); bytecode_hashes } else { + compressed_bytecodes = vec![]; crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory( &mut self.vm, &tx, @@ -224,7 +156,7 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + (Ok(compressed_bytecodes), result) } } @@ -245,10 +177,6 @@ impl VmInterface for Vm { } } - fn gas_remaining(&self) -> u32 { - self.vm.gas_remaining() - } - fn finish_batch(&mut self) -> FinishedL1Batch { self.vm .execute_till_block_end( @@ -270,7 +198,7 @@ impl VmFactory for Vm { let inner_vm: VmInstance = crate::vm_1_3_2::vm_with_bootloader::init_vm_with_gas_limit( oracle_tools, - batch_env.clone().glue_into(), + batch_env.glue_into(), block_properties, system_env.execution_mode.glue_into(), &system_env.base_system_smart_contracts.clone().glue_into(), @@ -279,8 +207,6 @@ impl VmFactory for Vm { Self { vm: inner_vm, system_env, - batch_env, - last_tx_compressed_bytecodes: vec![], } } } diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm_instance.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm_instance.rs index b82282f0a567..de3bb2c22d77 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm_instance.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm_instance.rs @@ -142,6 +142,7 @@ pub struct VmPartialExecutionResult { pub contracts_used: usize, pub cycles_used: u32, pub computational_gas_used: u32, + pub gas_remaining: u32, } #[derive(Debug, Clone, PartialEq)] @@ -660,6 +661,7 @@ impl VmInstance { cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, computational_gas_used, + gas_remaining: self.gas_remaining(), }, call_traces: tx_tracer.call_traces(), }) @@ -762,6 +764,7 @@ impl VmInstance { .get_decommitted_bytecodes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, computational_gas_used, + gas_remaining: self.gas_remaining(), }; // Collecting `block_tip_result` needs logs with timestamp, so we drain events for the `full_result` @@ -810,6 +813,7 @@ impl VmInstance { contracts_used: 0, cycles_used: 0, computational_gas_used: 0, + gas_remaining: 0, }, } } else { @@ -863,6 +867,7 @@ impl VmInstance { .get_decommitted_bytecodes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, computational_gas_used, + gas_remaining: self.gas_remaining(), } } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs index 6e0e31d461de..5f24f2465a32 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs @@ -5,7 +5,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, - CompressedBytecodeInfo, VmInterface, + CompressedBytecodeInfo, }, utils::bytecode, vm_1_4_1::Vm, @@ -15,15 +15,18 @@ use crate::{ impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { - self.get_last_tx_compressed_bytecodes().iter().any(|info| { - !self - .state - .storage - .storage - .get_ptr() - .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) - }) + self.bootloader_state + .get_last_tx_compressed_bytecodes() + .iter() + .any(|info| { + !self + .state + .storage + .storage + .get_ptr() + .borrow_mut() + .is_bytecode_known(&hash_bytecode(&info.original)) + }) } } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/implementation/execution.rs b/core/lib/multivm/src/versions/vm_1_4_1/implementation/execution.rs index 01ee21f1836f..db5aaa783df5 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/implementation/execution.rs @@ -4,7 +4,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, VmExecutionStopReason}, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + VmExecutionMode, VmExecutionResultAndLogs, }, vm_1_4_1::{ old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, diff --git a/core/lib/multivm/src/versions/vm_1_4_1/implementation/gas.rs b/core/lib/multivm/src/versions/vm_1_4_1/implementation/gas.rs index bd30aa6218b1..908c9466e895 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/implementation/gas.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{storage::WriteStorage, VmInterface}, + interface::storage::WriteStorage, vm_1_4_1::{tracers::DefaultExecutionTracer, vm::Vm}, HistoryMode, }; diff --git a/core/lib/multivm/src/versions/vm_1_4_1/vm.rs b/core/lib/multivm/src/versions/vm_1_4_1/vm.rs index 8f20e8654d77..8e63afd8e1ca 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/vm.rs @@ -8,7 +8,7 @@ use crate::{ glue::GlueInto, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, + BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, @@ -38,40 +38,11 @@ pub struct Vm { _phantom: std::marker::PhantomData, } -impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; - - /// Push tx into memory for the future execution - fn push_transaction(&mut self, tx: Transaction) { - self.push_transaction_with_compression(tx, true); - } - - /// Execute VM with custom tracers. - fn inspect( - &mut self, - tracer: Self::TracerDispatcher, - execution_mode: VmExecutionMode, - ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode, None) - } - - /// Get current state of bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { - self.bootloader_state.start_new_l2_block(l2_block_env); +impl Vm { + pub(super) fn gas_remaining(&self) -> u32 { + self.state.local_state.callstack.current.ergs_remaining } - /// Get current state of virtual machine. - /// This method should be used only after the batch execution. - /// Otherwise it can panic. fn get_current_execution_state(&self) -> CurrentExecutionState { let (raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) @@ -106,19 +77,35 @@ impl VmInterface for Vm { pubdata_costs: Vec::new(), } } +} - /// Execute transaction with optional bytecode compression. +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + /// Push tx into memory for the future execution + fn push_transaction(&mut self, tx: Transaction) { + self.push_transaction_with_compression(tx, true); + } + + /// Execute VM with custom tracers. + fn inspect( + &mut self, + tracer: Self::TracerDispatcher, + execution_mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(tracer, execution_mode, None) + } + + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + self.bootloader_state.start_new_l2_block(l2_block_env); + } - /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( &mut self, tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx, None); if self.has_unpublished_bytecodes() { @@ -127,7 +114,10 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + ( + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + result, + ) } } @@ -135,14 +125,10 @@ impl VmInterface for Vm { self.record_vm_memory_metrics_inner() } - fn gas_remaining(&self) -> u32 { - self.state.local_state.callstack.current.ergs_remaining - } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.execute(VmExecutionMode::Batch); + let result = self.inspect(TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.get_bootloader_memory(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs index 54e69289521f..1033fff90e46 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs @@ -5,7 +5,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, - CompressedBytecodeInfo, VmInterface, + CompressedBytecodeInfo, }, utils::bytecode, vm_1_4_2::Vm, @@ -15,15 +15,18 @@ use crate::{ impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { - self.get_last_tx_compressed_bytecodes().iter().any(|info| { - !self - .state - .storage - .storage - .get_ptr() - .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) - }) + self.bootloader_state + .get_last_tx_compressed_bytecodes() + .iter() + .any(|info| { + !self + .state + .storage + .storage + .get_ptr() + .borrow_mut() + .is_bytecode_known(&hash_bytecode(&info.original)) + }) } } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/implementation/execution.rs b/core/lib/multivm/src/versions/vm_1_4_2/implementation/execution.rs index a04e071fe436..d42d18809331 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/implementation/execution.rs @@ -4,7 +4,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, VmExecutionStopReason}, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + VmExecutionMode, VmExecutionResultAndLogs, }, vm_1_4_2::{ old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/implementation/gas.rs b/core/lib/multivm/src/versions/vm_1_4_2/implementation/gas.rs index d5b74de94554..e560acc1cf7f 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/implementation/gas.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{storage::WriteStorage, VmInterface}, + interface::storage::WriteStorage, vm_1_4_2::{tracers::DefaultExecutionTracer, vm::Vm}, HistoryMode, }; diff --git a/core/lib/multivm/src/versions/vm_1_4_2/vm.rs b/core/lib/multivm/src/versions/vm_1_4_2/vm.rs index e612885086dc..e7a1f69fa424 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/vm.rs @@ -8,7 +8,7 @@ use crate::{ glue::GlueInto, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, + BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, @@ -38,40 +38,11 @@ pub struct Vm { _phantom: std::marker::PhantomData, } -impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; - - /// Push tx into memory for the future execution - fn push_transaction(&mut self, tx: Transaction) { - self.push_transaction_with_compression(tx, true); - } - - /// Execute VM with custom tracers. - fn inspect( - &mut self, - tracer: Self::TracerDispatcher, - execution_mode: VmExecutionMode, - ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode, None) - } - - /// Get current state of bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { - self.bootloader_state.start_new_l2_block(l2_block_env); +impl Vm { + pub(super) fn gas_remaining(&self) -> u32 { + self.state.local_state.callstack.current.ergs_remaining } - /// Get current state of virtual machine. - /// This method should be used only after the batch execution. - /// Otherwise it can panic. fn get_current_execution_state(&self) -> CurrentExecutionState { let (raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) @@ -106,19 +77,35 @@ impl VmInterface for Vm { pubdata_costs: Vec::new(), } } +} - /// Execute transaction with optional bytecode compression. +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + /// Push tx into memory for the future execution + fn push_transaction(&mut self, tx: Transaction) { + self.push_transaction_with_compression(tx, true); + } + + /// Execute VM with custom tracers. + fn inspect( + &mut self, + tracer: Self::TracerDispatcher, + execution_mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(tracer, execution_mode, None) + } + + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + self.bootloader_state.start_new_l2_block(l2_block_env); + } - /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( &mut self, tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx, None); if self.has_unpublished_bytecodes() { @@ -127,7 +114,10 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + ( + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + result, + ) } } @@ -135,14 +125,10 @@ impl VmInterface for Vm { self.record_vm_memory_metrics_inner() } - fn gas_remaining(&self) -> u32 { - self.state.local_state.callstack.current.ergs_remaining - } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.execute(VmExecutionMode::Batch); + let result = self.inspect(TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.get_bootloader_memory(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs index b7e702b7a957..2d6f081a1886 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs @@ -5,7 +5,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, - CompressedBytecodeInfo, VmInterface, + CompressedBytecodeInfo, }, utils::bytecode, vm_boojum_integration::Vm, @@ -15,15 +15,18 @@ use crate::{ impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { - self.get_last_tx_compressed_bytecodes().iter().any(|info| { - !self - .state - .storage - .storage - .get_ptr() - .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) - }) + self.bootloader_state + .get_last_tx_compressed_bytecodes() + .iter() + .any(|info| { + !self + .state + .storage + .storage + .get_ptr() + .borrow_mut() + .is_bytecode_known(&hash_bytecode(&info.original)) + }) } } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/execution.rs b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/execution.rs index 664cb90531e4..a7c790a4bc30 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/execution.rs @@ -4,7 +4,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, VmExecutionStopReason}, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + VmExecutionMode, VmExecutionResultAndLogs, }, vm_boojum_integration::{ old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/gas.rs b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/gas.rs index b31e4c3536bc..eb69f3552233 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/gas.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{storage::WriteStorage, VmInterface}, + interface::storage::WriteStorage, vm_boojum_integration::{tracers::DefaultExecutionTracer, vm::Vm}, HistoryMode, }; diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs index 0a9e12865078..4b6b6931dd22 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs @@ -8,7 +8,7 @@ use crate::{ glue::GlueInto, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, + BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, @@ -38,40 +38,11 @@ pub struct Vm { _phantom: std::marker::PhantomData, } -impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; - - /// Push tx into memory for the future execution - fn push_transaction(&mut self, tx: Transaction) { - self.push_transaction_with_compression(tx, true); - } - - /// Execute VM with custom tracers. - fn inspect( - &mut self, - tracer: Self::TracerDispatcher, - execution_mode: VmExecutionMode, - ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode) - } - - /// Get current state of bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { - self.bootloader_state.start_new_l2_block(l2_block_env); +impl Vm { + pub(super) fn gas_remaining(&self) -> u32 { + self.state.local_state.callstack.current.ergs_remaining } - /// Get current state of virtual machine. - /// This method should be used only after the batch execution. - /// Otherwise it can panic. fn get_current_execution_state(&self) -> CurrentExecutionState { let (raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) @@ -106,8 +77,28 @@ impl VmInterface for Vm { pubdata_costs: Vec::new(), } } +} - /// Execute transaction with optional bytecode compression. +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + /// Push tx into memory for the future execution + fn push_transaction(&mut self, tx: Transaction) { + self.push_transaction_with_compression(tx, true); + } + + /// Execute VM with custom tracers. + fn inspect( + &mut self, + tracer: Self::TracerDispatcher, + execution_mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(tracer, execution_mode) + } + + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + self.bootloader_state.start_new_l2_block(l2_block_env); + } /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( @@ -115,10 +106,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { @@ -127,7 +115,10 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + ( + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + result, + ) } } @@ -135,14 +126,10 @@ impl VmInterface for Vm { self.record_vm_memory_metrics_inner() } - fn gas_remaining(&self) -> u32 { - self.state.local_state.callstack.current.ergs_remaining - } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.execute(VmExecutionMode::Batch); + let result = self.inspect(TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.get_bootloader_memory(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/bootloader.rs b/core/lib/multivm/src/versions/vm_fast/tests/bootloader.rs index c698d36683ef..27643c146ee5 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/bootloader.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/bootloader.rs @@ -1,7 +1,7 @@ use zksync_types::U256; use crate::{ - interface::{ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterfaceExt}, versions::vm_fast::tests::{ tester::VmTesterBuilder, utils::{get_bootloader, verify_required_memory, BASE_SYSTEM_CONTRACTS}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/bytecode_publishing.rs b/core/lib/multivm/src/versions/vm_fast/tests/bytecode_publishing.rs index 56c20e785ee6..3070140c00b3 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/bytecode_publishing.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/bytecode_publishing.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{TxExecutionMode, VmEvent, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmEvent, VmExecutionMode, VmInterface, VmInterfaceExt}, utils::bytecode, vm_fast::tests::{ tester::{DeployContractsTx, TxType, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/code_oracle.rs b/core/lib/multivm/src/versions/vm_fast/tests/code_oracle.rs index 24fda3beed4b..946ad0c38b0c 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/code_oracle.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/code_oracle.rs @@ -5,7 +5,7 @@ use zksync_types::{ use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_fast::tests::{ tester::{get_empty_storage, VmTesterBuilder}, utils::{load_precompiles_contract, read_precompiles_contract, read_test_contract}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/default_aa.rs b/core/lib/multivm/src/versions/vm_fast/tests/default_aa.rs index 460c8251652b..f809af81b165 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/default_aa.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/default_aa.rs @@ -7,7 +7,7 @@ use zksync_types::{ use zksync_utils::u256_to_h256; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_fast::tests::{ tester::{DeployContractsTx, TxType, VmTesterBuilder}, utils::{get_balance, read_test_contract, verify_required_storage}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/get_used_contracts.rs b/core/lib/multivm/src/versions/vm_fast/tests/get_used_contracts.rs index 5524bd3edde9..85ff4bbf5e9b 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/get_used_contracts.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/get_used_contracts.rs @@ -12,7 +12,7 @@ use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; use crate::{ interface::{ storage::ReadStorage, ExecutionResult, TxExecutionMode, VmExecutionMode, - VmExecutionResultAndLogs, VmInterface, + VmExecutionResultAndLogs, VmInterface, VmInterfaceExt, }, vm_fast::{ tests::{ diff --git a/core/lib/multivm/src/versions/vm_fast/tests/is_write_initial.rs b/core/lib/multivm/src/versions/vm_fast/tests/is_write_initial.rs index ff97c0389aa9..df8d992f02fe 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/is_write_initial.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/is_write_initial.rs @@ -1,7 +1,9 @@ use zksync_types::get_nonce_key; use crate::{ - interface::{storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ + storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, + }, vm_fast::tests::{ tester::{Account, TxType, VmTesterBuilder}, utils::read_test_contract, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/l1_tx_execution.rs b/core/lib/multivm/src/versions/vm_fast/tests/l1_tx_execution.rs index f1411497c24c..f1399a1b4e68 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/l1_tx_execution.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/l1_tx_execution.rs @@ -9,7 +9,7 @@ use zksync_types::{ use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, utils::StorageWritesDeduplicator, vm_fast::{ tests::{ diff --git a/core/lib/multivm/src/versions/vm_fast/tests/l2_blocks.rs b/core/lib/multivm/src/versions/vm_fast/tests/l2_blocks.rs index 6ff5ed426cba..a374f63608bc 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/l2_blocks.rs @@ -16,7 +16,7 @@ use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::{ interface::{ storage::ReadStorage, ExecutionResult, Halt, L2BlockEnv, TxExecutionMode, VmExecutionMode, - VmInterface, + VmInterface, VmInterfaceExt, }, vm_fast::{ tests::tester::{default_l1_batch, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/nonce_holder.rs b/core/lib/multivm/src/versions/vm_fast/tests/nonce_holder.rs index b18676cf2ba6..122b38601175 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/nonce_holder.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/nonce_holder.rs @@ -2,7 +2,7 @@ use zksync_types::{Execute, ExecuteTransactionCommon, Nonce}; use crate::{ interface::{ - ExecutionResult, Halt, TxExecutionMode, TxRevertReason, VmExecutionMode, VmInterface, + ExecutionResult, Halt, TxExecutionMode, TxRevertReason, VmExecutionMode, VmInterfaceExt, VmRevertReason, }, vm_fast::tests::{ diff --git a/core/lib/multivm/src/versions/vm_fast/tests/refunds.rs b/core/lib/multivm/src/versions/vm_fast/tests/refunds.rs index 21a3129a3a61..5ad6e3fa4f3d 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/refunds.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/refunds.rs @@ -2,7 +2,7 @@ use ethabi::Token; use zksync_types::{Address, Execute, U256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_fast::tests::{ tester::{DeployContractsTx, TxType, VmTesterBuilder}, utils::{read_expensive_contract, read_test_contract}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/require_eip712.rs b/core/lib/multivm/src/versions/vm_fast/tests/require_eip712.rs index 352e709b7043..fe94189ed7cf 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/require_eip712.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/require_eip712.rs @@ -9,7 +9,9 @@ use zksync_types::{ use zksync_utils::h256_to_u256; use crate::{ - interface::{storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ + storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, + }, vm_fast::tests::{ tester::{Account, VmTester, VmTesterBuilder}, utils::read_many_owners_custom_account_contract, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/sekp256r1.rs b/core/lib/multivm/src/versions/vm_fast/tests/sekp256r1.rs index 76357d44cf38..a61a0a2bd91c 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/sekp256r1.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/sekp256r1.rs @@ -4,7 +4,7 @@ use zksync_types::{web3::keccak256, Execute, H256, U256}; use zksync_utils::h256_to_u256; use crate::{ - interface::{ExecutionResult, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ExecutionResult, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_fast::tests::tester::VmTesterBuilder, }; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/simple_execution.rs b/core/lib/multivm/src/versions/vm_fast/tests/simple_execution.rs index 7d866e1539b0..61f4113118ec 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/simple_execution.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/simple_execution.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{ExecutionResult, VmExecutionMode, VmInterface}, + interface::{ExecutionResult, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_fast::tests::tester::{TxType, VmTesterBuilder}, }; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/storage.rs b/core/lib/multivm/src/versions/vm_fast/tests/storage.rs index 733ce1f0618c..7fe15ca7bcd2 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/storage.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/storage.rs @@ -3,7 +3,9 @@ use zksync_contracts::{load_contract, read_bytecode}; use zksync_types::{Address, Execute, U256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceHistoryEnabled}, + interface::{ + TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, + }, vm_fast::tests::tester::VmTesterBuilder, }; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/tester/transaction_test_info.rs b/core/lib/multivm/src/versions/vm_fast/tests/tester/transaction_test_info.rs index 562a8a6a6bdd..0d8c6b20764a 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/tester/transaction_test_info.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/tester/transaction_test_info.rs @@ -4,8 +4,8 @@ use super::VmTester; use crate::{ interface::{ storage::ReadStorage, CurrentExecutionState, ExecutionResult, Halt, TxRevertReason, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, VmInterfaceHistoryEnabled, - VmRevertReason, + VmExecutionMode, VmExecutionResultAndLogs, VmInterface, VmInterfaceExt, + VmInterfaceHistoryEnabled, VmRevertReason, }, vm_fast::Vm, }; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/tester/vm_tester.rs b/core/lib/multivm/src/versions/vm_fast/tests/tester/vm_tester.rs index efab73aed1df..335ec752c7d4 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/tester/vm_tester.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/tester/vm_tester.rs @@ -18,6 +18,7 @@ use crate::{ interface::{ storage::{InMemoryStorage, StoragePtr}, L1BatchEnv, L2Block, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmInterface, + VmInterfaceExt, }, versions::vm_fast::{tests::utils::read_test_contract, vm::Vm}, vm_latest::{constants::BATCH_COMPUTATIONAL_GAS_LIMIT, utils::l2_blocks::load_last_l2_block}, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/transfer.rs b/core/lib/multivm/src/versions/vm_fast/tests/transfer.rs index 3b61b8ac7f1e..3327012801ce 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/transfer.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/transfer.rs @@ -5,7 +5,7 @@ use zksync_types::{utils::storage_key_for_eth_balance, AccountTreeId, Address, E use zksync_utils::u256_to_h256; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_fast::tests::{ tester::{get_empty_storage, VmTesterBuilder}, utils::get_balance, diff --git a/core/lib/multivm/src/versions/vm_fast/tests/upgrade.rs b/core/lib/multivm/src/versions/vm_fast/tests/upgrade.rs index 616436776090..f972b29cda8a 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/upgrade.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/upgrade.rs @@ -12,7 +12,7 @@ use zksync_utils::{bytecode::hash_bytecode, u256_to_h256}; use crate::{ interface::{ - ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterface, + ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, }, vm_fast::tests::{ diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index a9b2fcd605c9..3a01a10d1871 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -30,7 +30,7 @@ use super::{ use crate::{ glue::GlueInto, interface::{ - storage::ReadStorage, BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, + storage::ReadStorage, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, Refunds, SystemEnv, TxRevertReason, VmEvent, VmExecutionLogs, VmExecutionMode, VmExecutionResultAndLogs, VmExecutionStatistics, VmInterface, VmInterfaceHistoryEnabled, @@ -345,6 +345,10 @@ impl Vm { pub(crate) fn decommitted_hashes(&self) -> impl Iterator + '_ { self.inner.world_diff.decommitted_hashes() } + + fn gas_remaining(&self) -> u32 { + self.inner.state.current_frame.gas + } } // We don't implement `VmFactory` trait because, unlike old VMs, the new VM doesn't require storage to be writable; @@ -407,6 +411,39 @@ impl Vm { me } + // visible for testing + pub(super) fn get_current_execution_state(&self) -> CurrentExecutionState { + let world_diff = &self.inner.world_diff; + let events = merge_events(world_diff.events(), self.batch_env.number); + + let user_l2_to_l1_logs = extract_l2tol1logs_from_l1_messenger(&events) + .into_iter() + .map(Into::into) + .map(UserL2ToL1Log) + .collect(); + + CurrentExecutionState { + events, + deduplicated_storage_logs: world_diff + .get_storage_changes() + .map(|((address, key), (_, value))| StorageLog { + key: StorageKey::new(AccountTreeId::new(address), u256_to_h256(key)), + value: u256_to_h256(value), + kind: StorageLogKind::RepeatedWrite, // Initialness doesn't matter here + }) + .collect(), + used_contract_hashes: self.decommitted_hashes().collect(), + system_logs: world_diff + .l2_to_l1_logs() + .iter() + .map(|x| x.glue_into()) + .collect(), + user_l2_to_l1_logs, + storage_refunds: world_diff.storage_refunds().to_vec(), + pubdata_costs: world_diff.pubdata_costs().to_vec(), + } + } + fn delete_history_if_appropriate(&mut self) { if self.snapshot.is_none() && self.inner.state.previous_frames.is_empty() { self.inner.delete_history(); @@ -496,7 +533,7 @@ impl VmInterface for Vm { contracts_used: 0, cycles_used: 0, gas_used: 0, - gas_remaining: 0, + gas_remaining: self.gas_remaining(), computational_gas_used: 0, total_log_queries: 0, pubdata_published: (pubdata_after - pubdata_before).max(0) as u32, @@ -512,7 +549,7 @@ impl VmInterface for Vm { tx: zksync_types::Transaction, with_compression: bool, ) -> ( - Result<(), BytecodeCompressionError>, + Result, BytecodeCompressionError>, VmExecutionResultAndLogs, ) { self.push_transaction_inner(tx, 0, with_compression); @@ -521,67 +558,23 @@ impl VmInterface for Vm { let compression_result = if self.has_unpublished_bytecodes() { Err(BytecodeCompressionError::BytecodeCompressionFailed) } else { - Ok(()) + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()) }; (compression_result, result) } - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { self.bootloader_state.start_new_l2_block(l2_block_env) } - fn get_current_execution_state(&self) -> CurrentExecutionState { - let world_diff = &self.inner.world_diff; - let events = merge_events(world_diff.events(), self.batch_env.number); - - let user_l2_to_l1_logs = extract_l2tol1logs_from_l1_messenger(&events) - .into_iter() - .map(Into::into) - .map(UserL2ToL1Log) - .collect(); - - CurrentExecutionState { - events, - deduplicated_storage_logs: world_diff - .get_storage_changes() - .map(|((address, key), (_, value))| StorageLog { - key: StorageKey::new(AccountTreeId::new(address), u256_to_h256(key)), - value: u256_to_h256(value), - kind: StorageLogKind::RepeatedWrite, // Initialness doesn't matter here - }) - .collect(), - used_contract_hashes: self.decommitted_hashes().collect(), - system_logs: world_diff - .l2_to_l1_logs() - .iter() - .map(|x| x.glue_into()) - .collect(), - user_l2_to_l1_logs, - storage_refunds: world_diff.storage_refunds().to_vec(), - pubdata_costs: world_diff.pubdata_costs().to_vec(), - } - } - fn record_vm_memory_metrics(&self) -> VmMemoryMetrics { todo!("Unused during batch execution") } - fn gas_remaining(&self) -> u32 { - self.inner.state.current_frame.gas - } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.execute(VmExecutionMode::Batch); + let result = self.inspect((), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.get_bootloader_memory(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs index d0a41ce69f42..2cd98c8e58a3 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs @@ -5,7 +5,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, - CompressedBytecodeInfo, VmInterface, + CompressedBytecodeInfo, }, utils::bytecode, vm_latest::Vm, @@ -15,15 +15,18 @@ use crate::{ impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { - self.get_last_tx_compressed_bytecodes().iter().any(|info| { - !self - .state - .storage - .storage - .get_ptr() - .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) - }) + self.bootloader_state + .get_last_tx_compressed_bytecodes() + .iter() + .any(|info| { + !self + .state + .storage + .storage + .get_ptr() + .borrow_mut() + .is_bytecode_known(&hash_bytecode(&info.original)) + }) } } diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs b/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs index 4676fd82d5e2..66fc1a8bfd71 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs @@ -4,7 +4,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, VmExecutionStopReason}, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + VmExecutionMode, VmExecutionResultAndLogs, }, vm_latest::{ old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/gas.rs b/core/lib/multivm/src/versions/vm_latest/implementation/gas.rs index 1e33eecf6325..8d006a467795 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/gas.rs @@ -1,8 +1,4 @@ -use crate::{ - interface::{storage::WriteStorage, VmInterface}, - vm_latest::vm::Vm, - HistoryMode, -}; +use crate::{interface::storage::WriteStorage, vm_latest::vm::Vm, HistoryMode}; impl Vm { pub(crate) fn calculate_computational_gas_used(&self, gas_remaining_before: u32) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs b/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs index f1851eaae425..bed348afd2d9 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs @@ -15,7 +15,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, u25 use super::utils::{get_complex_upgrade_abi, read_complex_upgrade}; use crate::{ - interface::{L1BatchEnv, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{L1BatchEnv, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ constants::{ BOOTLOADER_BATCH_TIP_CIRCUIT_STATISTICS_OVERHEAD, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/bootloader.rs b/core/lib/multivm/src/versions/vm_latest/tests/bootloader.rs index 4b60c1992025..86e343b963f5 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/bootloader.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/bootloader.rs @@ -1,7 +1,7 @@ use zksync_types::U256; use crate::{ - interface::{ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterfaceExt}, vm_latest::{ constants::BOOTLOADER_HEAP_PAGE, tests::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/bytecode_publishing.rs b/core/lib/multivm/src/versions/vm_latest/tests/bytecode_publishing.rs index ef56aafe4cbe..2ed9948af819 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/bytecode_publishing.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/bytecode_publishing.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{TxExecutionMode, VmEvent, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmEvent, VmExecutionMode, VmInterface, VmInterfaceExt}, utils::bytecode, vm_latest::{ tests::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/code_oracle.rs b/core/lib/multivm/src/versions/vm_latest/tests/code_oracle.rs index 7174e9be67de..0708d67e27a3 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/code_oracle.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/code_oracle.rs @@ -9,7 +9,7 @@ use zksync_types::{ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, u256_to_h256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::{ tester::{get_empty_storage, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/default_aa.rs b/core/lib/multivm/src/versions/vm_latest/tests/default_aa.rs index 34297d991d10..aa3eb5e752ce 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/default_aa.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/default_aa.rs @@ -7,7 +7,7 @@ use zksync_types::{ use zksync_utils::u256_to_h256; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::{ tester::{DeployContractsTx, TxType, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/get_used_contracts.rs b/core/lib/multivm/src/versions/vm_latest/tests/get_used_contracts.rs index a77b8c97b425..a42037a7f5be 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/get_used_contracts.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/get_used_contracts.rs @@ -22,6 +22,7 @@ use zksync_vm_interface::VmExecutionResultAndLogs; use crate::{ interface::{ storage::WriteStorage, ExecutionResult, TxExecutionMode, VmExecutionMode, VmInterface, + VmInterfaceExt, }, vm_latest::{ tests::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/is_write_initial.rs b/core/lib/multivm/src/versions/vm_latest/tests/is_write_initial.rs index 900f322bc3f3..8206cfa9be6f 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/is_write_initial.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/is_write_initial.rs @@ -1,7 +1,9 @@ use zksync_types::get_nonce_key; use crate::{ - interface::{storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ + storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, + }, vm_latest::{ tests::{ tester::{Account, TxType, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/l1_tx_execution.rs b/core/lib/multivm/src/versions/vm_latest/tests/l1_tx_execution.rs index 4d42bb96cc96..dcb1bff06d09 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/l1_tx_execution.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/l1_tx_execution.rs @@ -10,7 +10,7 @@ use zksync_types::{ use zksync_utils::u256_to_h256; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, utils::StorageWritesDeduplicator, vm_latest::{ tests::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs b/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs index 1f4c36bb25b7..1b5c3db59f72 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs @@ -17,7 +17,7 @@ use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::{ interface::{ storage::WriteStorage, ExecutionResult, Halt, L2BlockEnv, TxExecutionMode, VmExecutionMode, - VmInterface, + VmInterface, VmInterfaceExt, }, vm_latest::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/migration.rs b/core/lib/multivm/src/versions/vm_latest/tests/migration.rs index 6bd0e87615ed..5b8da2551808 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/migration.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/migration.rs @@ -1,7 +1,7 @@ use zksync_types::{get_code_key, H256, SYSTEM_CONTEXT_ADDRESS}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::{ tester::{get_empty_storage, DeployContractsTx, TxType, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/nonce_holder.rs b/core/lib/multivm/src/versions/vm_latest/tests/nonce_holder.rs index 076ecb523618..661286ca9697 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/nonce_holder.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/nonce_holder.rs @@ -2,7 +2,7 @@ use zksync_types::{Execute, Nonce}; use crate::{ interface::{ - ExecutionResult, Halt, TxExecutionMode, TxRevertReason, VmExecutionMode, VmInterface, + ExecutionResult, Halt, TxExecutionMode, TxRevertReason, VmExecutionMode, VmInterfaceExt, VmRevertReason, }, vm_latest::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs index 893ca57bc4d1..eb3104fd637a 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs @@ -5,7 +5,7 @@ use zksync_test_account::TxType; use zksync_types::{utils::deployed_address_create, Execute, U256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, tracers::PrestateTracer, vm_latest::{ constants::BATCH_COMPUTATIONAL_GAS_LIMIT, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/refunds.rs b/core/lib/multivm/src/versions/vm_latest/tests/refunds.rs index 52dbd6efb339..ca058d672d2e 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/refunds.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/refunds.rs @@ -2,7 +2,7 @@ use ethabi::Token; use zksync_types::{Address, Execute, U256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::{ tester::{DeployContractsTx, TxType, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/require_eip712.rs b/core/lib/multivm/src/versions/vm_latest/tests/require_eip712.rs index 5178c5dc29cf..779e9b5c629d 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/require_eip712.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/require_eip712.rs @@ -8,7 +8,7 @@ use zksync_types::{ }; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::{ tester::{Account, VmTester, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs index 489c762aac4e..43e7baae3b2d 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs @@ -6,7 +6,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, TracerExecutionStopReason}, - TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceHistoryEnabled, + TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/sekp256r1.rs b/core/lib/multivm/src/versions/vm_latest/tests/sekp256r1.rs index 3cd50e0eb917..6cc731a1387c 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/sekp256r1.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/sekp256r1.rs @@ -4,7 +4,7 @@ use zksync_types::{web3::keccak256, Execute, H256, U256}; use zksync_utils::h256_to_u256; use crate::{ - interface::{ExecutionResult, TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{ExecutionResult, TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{tests::tester::VmTesterBuilder, HistoryEnabled}, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tests/simple_execution.rs b/core/lib/multivm/src/versions/vm_latest/tests/simple_execution.rs index a864538524a2..1c82e77a5037 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/simple_execution.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/simple_execution.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{ExecutionResult, VmExecutionMode, VmInterface}, + interface::{ExecutionResult, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::tester::{TxType, VmTesterBuilder}, HistoryDisabled, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/storage.rs b/core/lib/multivm/src/versions/vm_latest/tests/storage.rs index b7c14c54f6df..0fe0b0220fae 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/storage.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/storage.rs @@ -4,7 +4,9 @@ use zksync_test_account::Account; use zksync_types::{fee::Fee, Address, Execute, U256}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceHistoryEnabled}, + interface::{ + TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, + }, vm_latest::{tests::tester::VmTesterBuilder, HistoryEnabled}, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tests/tester/transaction_test_info.rs b/core/lib/multivm/src/versions/vm_latest/tests/tester/transaction_test_info.rs index 114f80d1a217..08667ccc625f 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/tester/transaction_test_info.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/tester/transaction_test_info.rs @@ -3,7 +3,8 @@ use zksync_types::{ExecuteTransactionCommon, Transaction}; use crate::{ interface::{ CurrentExecutionState, ExecutionResult, Halt, TxRevertReason, VmExecutionMode, - VmExecutionResultAndLogs, VmInterface, VmInterfaceHistoryEnabled, VmRevertReason, + VmExecutionResultAndLogs, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, + VmRevertReason, }, vm_latest::{tests::tester::vm_tester::VmTester, HistoryEnabled}, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs b/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs index 9aba2539e001..1fe4232c7780 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs @@ -15,7 +15,7 @@ use crate::{ interface::{ storage::{InMemoryStorage, StoragePtr, StorageView, WriteStorage}, L1BatchEnv, L2Block, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmFactory, - VmInterface, + VmInterface, VmInterfaceExt, }, vm_latest::{ constants::BATCH_COMPUTATIONAL_GAS_LIMIT, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/transfer.rs b/core/lib/multivm/src/versions/vm_latest/tests/transfer.rs index f4198d541f73..31f6c3291ef6 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/transfer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/transfer.rs @@ -5,7 +5,7 @@ use zksync_types::{utils::storage_key_for_eth_balance, AccountTreeId, Address, E use zksync_utils::u256_to_h256; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, vm_latest::{ tests::{ tester::{get_empty_storage, VmTesterBuilder}, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/upgrade.rs b/core/lib/multivm/src/versions/vm_latest/tests/upgrade.rs index 020b12a7a6e9..7c3ebff4a77d 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/upgrade.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/upgrade.rs @@ -15,7 +15,7 @@ use super::utils::{get_complex_upgrade_abi, read_test_contract}; use crate::{ interface::{ storage::WriteStorage, ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, - VmInterface, VmInterfaceHistoryEnabled, + VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, }, vm_latest::{ tests::{ diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index 1c85133e1178..c0c13669c2ef 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -9,7 +9,7 @@ use crate::{ glue::GlueInto, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, + BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, @@ -73,41 +73,13 @@ pub struct Vm { _phantom: std::marker::PhantomData, } -impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; - - /// Push tx into memory for the future execution - fn push_transaction(&mut self, tx: Transaction) { - self.push_transaction_with_compression(tx, true); - } - - /// Execute VM with custom tracers. - fn inspect( - &mut self, - tracer: Self::TracerDispatcher, - execution_mode: VmExecutionMode, - ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode, None) - } - - /// Get current state of bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { - self.bootloader_state.start_new_l2_block(l2_block_env); +impl Vm { + pub(super) fn gas_remaining(&self) -> u32 { + self.state.local_state.callstack.current.ergs_remaining } - /// Get current state of virtual machine. - /// This method should be used only after the batch execution. - /// Otherwise it can panic. - fn get_current_execution_state(&self) -> CurrentExecutionState { + // visible for testing + pub(super) fn get_current_execution_state(&self) -> CurrentExecutionState { let (raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) .into_iter() @@ -140,8 +112,28 @@ impl VmInterface for Vm { pubdata_costs: self.state.storage.returned_pubdata_costs.inner().clone(), } } +} + +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + /// Push tx into memory for the future execution + fn push_transaction(&mut self, tx: Transaction) { + self.push_transaction_with_compression(tx, true); + } + + /// Execute VM with custom tracers. + fn inspect( + &mut self, + tracer: Self::TracerDispatcher, + execution_mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(tracer, execution_mode, None) + } - /// Execute transaction with optional bytecode compression. + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + self.bootloader_state.start_new_l2_block(l2_block_env); + } /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( @@ -149,10 +141,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx, None); if self.has_unpublished_bytecodes() { @@ -161,7 +150,10 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + ( + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + result, + ) } } @@ -169,14 +161,10 @@ impl VmInterface for Vm { self.record_vm_memory_metrics_inner() } - fn gas_remaining(&self) -> u32 { - self.state.local_state.callstack.current.ergs_remaining - } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.execute(VmExecutionMode::Batch); + let result = self.inspect(TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.get_bootloader_memory(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, diff --git a/core/lib/multivm/src/versions/vm_m5/vm.rs b/core/lib/multivm/src/versions/vm_m5/vm.rs index 8f232c95b38e..4282f3f0cf4a 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm.rs @@ -1,23 +1,14 @@ -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; -use itertools::Itertools; -use zk_evm_1_3_1::aux_structures::LogQuery; -use zksync_types::{ - l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}, - vm::VmVersion, - Transaction, -}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{vm::VmVersion, Transaction}; +use zksync_utils::h256_to_u256; use crate::{ glue::{history_mode::HistoryMode, GlueInto}, interface::{ - storage::StoragePtr, BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, - CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, - VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, - VmInterfaceHistoryEnabled, VmMemoryMetrics, + storage::StoragePtr, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, + SystemEnv, TxExecutionMode, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, + VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, }, vm_m5::{ - events::merge_events, storage::Storage, vm_instance::{MultiVMSubversion, VmInstance}, }, @@ -27,8 +18,6 @@ use crate::{ pub struct Vm { pub(crate) vm: VmInstance, pub(crate) system_env: SystemEnv, - pub(crate) batch_env: L1BatchEnv, - pub(crate) last_tx_compressed_bytecodes: Vec, _phantom: std::marker::PhantomData, } @@ -49,7 +38,7 @@ impl Vm { let inner_vm = crate::vm_m5::vm_with_bootloader::init_vm_with_gas_limit( vm_sub_version, oracle_tools, - batch_env.clone().glue_into(), + batch_env.glue_into(), block_properties, system_env.execution_mode.glue_into(), &system_env.base_system_smart_contracts.clone().glue_into(), @@ -58,8 +47,6 @@ impl Vm { Self { vm: inner_vm, system_env, - batch_env, - last_tx_compressed_bytecodes: vec![], _phantom: Default::default(), } } @@ -97,95 +84,23 @@ impl VmInterface for Vm { } } - fn get_bootloader_memory(&self) -> BootloaderMemory { - vec![] - } - - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.last_tx_compressed_bytecodes.clone() - } - fn start_new_l2_block(&mut self, _l2_block_env: L2BlockEnv) { // Do nothing, because vm 1.3.2 doesn't support L2 blocks } - fn get_current_execution_state(&self) -> CurrentExecutionState { - let (raw_events, l1_messages) = self.vm.state.event_sink.flatten(); - let events = merge_events(raw_events) - .into_iter() - .map(|e| e.into_vm_event(self.batch_env.number)) - .collect(); - let l2_to_l1_logs = l1_messages - .into_iter() - .map(|m| { - UserL2ToL1Log(L2ToL1Log { - shard_id: m.shard_id, - is_service: m.is_first, - tx_number_in_block: m.tx_number_in_block, - sender: m.address, - key: u256_to_h256(m.key), - value: u256_to_h256(m.value), - }) - }) - .collect(); - - let used_contract_hashes = self - .vm - .state - .decommittment_processor - .known_bytecodes - .inner() - .keys() - .cloned() - .collect(); - - let storage_log_queries = self.vm.get_final_log_queries(); - - // To allow calling the `vm-1.3.3`s. method, the `v1.3.1`'s `LogQuery` has to be converted - // to the `vm-1.3.3`'s `LogQuery`. Then, we need to convert it back. - let deduplicated_logs: Vec = sort_storage_access_queries( - &storage_log_queries - .iter() - .map(|log| { - GlueInto::::glue_into(log.log_query) - }) - .collect_vec(), - ) - .1 - .into_iter() - .map(GlueInto::::glue_into) - .collect(); - - CurrentExecutionState { - events, - deduplicated_storage_logs: deduplicated_logs - .into_iter() - .map(GlueInto::glue_into) - .collect(), - used_contract_hashes, - system_logs: vec![], - user_l2_to_l1_logs: l2_to_l1_logs, - // Fields below are not produced by `vm5` - storage_refunds: vec![], - pubdata_costs: vec![], - } - } - fn inspect_transaction_with_bytecode_compression( &mut self, _tracer: Self::TracerDispatcher, tx: Transaction, _with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { crate::vm_m5::vm_with_bootloader::push_transaction_to_bootloader_memory( &mut self.vm, &tx, self.system_env.execution_mode.glue_into(), ); - (Ok(()), self.execute(VmExecutionMode::OneTx)) + // Bytecode compression isn't supported + (Ok(vec![]), self.inspect((), VmExecutionMode::OneTx)) } fn record_vm_memory_metrics(&self) -> VmMemoryMetrics { @@ -201,10 +116,6 @@ impl VmInterface for Vm { } } - fn gas_remaining(&self) -> u32 { - self.vm.gas_remaining() - } - fn finish_batch(&mut self) -> FinishedL1Batch { self.vm .execute_till_block_end( diff --git a/core/lib/multivm/src/versions/vm_m5/vm_instance.rs b/core/lib/multivm/src/versions/vm_m5/vm_instance.rs index f0a94d0c3b6e..4a96c4a750cc 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm_instance.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm_instance.rs @@ -157,6 +157,7 @@ pub struct VmPartialExecutionResult { pub revert_reason: Option, pub contracts_used: usize, pub cycles_used: u32, + pub gas_remaining: u32, } #[derive(Debug, Clone, PartialEq)] @@ -682,6 +683,7 @@ impl VmInstance { .get_decommitted_bytes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, + gas_remaining: self.gas_remaining(), }, }) } else { @@ -743,6 +745,7 @@ impl VmInstance { .decommittment_processor .get_decommitted_bytes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, + gas_remaining: self.gas_remaining(), }; // Collecting `block_tip_result` needs logs with timestamp, so we drain events for the `full_result` @@ -799,6 +802,7 @@ impl VmInstance { .decommittment_processor .get_decommitted_bytes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, + gas_remaining: self.gas_remaining(), } } diff --git a/core/lib/multivm/src/versions/vm_m6/vm.rs b/core/lib/multivm/src/versions/vm_m6/vm.rs index b59561319f56..520abd930555 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm.rs @@ -1,34 +1,25 @@ use std::collections::HashSet; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; -use itertools::Itertools; -use zk_evm_1_3_1::aux_structures::LogQuery; -use zksync_types::{ - l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}, - vm::VmVersion, - Transaction, -}; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_types::{vm::VmVersion, Transaction}; +use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; use crate::{ glue::{history_mode::HistoryMode, GlueInto}, interface::{ - storage::StoragePtr, BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, - CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, - VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, - VmInterfaceHistoryEnabled, VmMemoryMetrics, + storage::StoragePtr, BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch, + L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, + VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, + VmMemoryMetrics, }, tracers::old::TracerDispatcher, utils::bytecode, - vm_m6::{events::merge_events, storage::Storage, vm_instance::MultiVMSubversion, VmInstance}, + vm_m6::{storage::Storage, vm_instance::MultiVMSubversion, VmInstance}, }; #[derive(Debug)] pub struct Vm { pub(crate) vm: VmInstance, pub(crate) system_env: SystemEnv, - pub(crate) batch_env: L1BatchEnv, - pub(crate) last_tx_compressed_bytecodes: Vec, } impl Vm { @@ -48,7 +39,7 @@ impl Vm { let inner_vm = crate::vm_m6::vm_with_bootloader::init_vm_with_gas_limit( vm_sub_version, oracle_tools, - batch_env.clone().glue_into(), + batch_env.glue_into(), block_properties, system_env.execution_mode.glue_into(), &system_env.base_system_smart_contracts.clone().glue_into(), @@ -57,8 +48,6 @@ impl Vm { Self { vm: inner_vm, system_env, - batch_env, - last_tx_compressed_bytecodes: vec![], } } } @@ -111,96 +100,23 @@ impl VmInterface for Vm { } } - fn get_bootloader_memory(&self) -> BootloaderMemory { - vec![] - } - - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.last_tx_compressed_bytecodes.clone() - } - fn start_new_l2_block(&mut self, _l2_block_env: L2BlockEnv) { // Do nothing, because vm 1.3.2 doesn't support L2 blocks } - fn get_current_execution_state(&self) -> CurrentExecutionState { - let (raw_events, l1_messages) = self.vm.state.event_sink.flatten(); - let events = merge_events(raw_events) - .into_iter() - .map(|e| e.into_vm_event(self.batch_env.number)) - .collect(); - let l2_to_l1_logs = l1_messages - .into_iter() - .map(|m| { - UserL2ToL1Log(L2ToL1Log { - shard_id: m.shard_id, - is_service: m.is_first, - tx_number_in_block: m.tx_number_in_block, - sender: m.address, - key: u256_to_h256(m.key), - value: u256_to_h256(m.value), - }) - }) - .collect(); - - let used_contract_hashes = self - .vm - .state - .decommittment_processor - .known_bytecodes - .inner() - .keys() - .cloned() - .collect(); - - let storage_log_queries = self.vm.get_final_log_queries(); - - // To allow calling the `vm-1.3.3`s. method, the `v1.3.1`'s `LogQuery` has to be converted - // to the `vm-1.3.3`'s `LogQuery`. Then, we need to convert it back. - let deduplicated_logs: Vec = sort_storage_access_queries( - &storage_log_queries - .iter() - .map(|log| { - GlueInto::::glue_into(log.log_query) - }) - .collect_vec(), - ) - .1 - .into_iter() - .map(GlueInto::::glue_into) - .collect(); - - CurrentExecutionState { - events, - deduplicated_storage_logs: deduplicated_logs - .into_iter() - .map(GlueInto::glue_into) - .collect(), - used_contract_hashes, - user_l2_to_l1_logs: l2_to_l1_logs, - // Fields below are not produced by `vm6` - system_logs: vec![], - storage_refunds: vec![], - pubdata_costs: vec![], - } - } - fn inspect_transaction_with_bytecode_compression( &mut self, tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { if let Some(storage_invocations) = tracer.storage_invocations { self.vm .execution_mode .set_invocation_limit(storage_invocations); } - self.last_tx_compressed_bytecodes = vec![]; + let compressed_bytecodes: Vec<_>; let bytecodes = if with_compression { let deps = &tx.execute.factory_deps; let mut deps_hashes = HashSet::with_capacity(deps.len()); @@ -217,18 +133,17 @@ impl VmInterface for Vm { bytecode::compress(bytecode.clone()).ok() } }); - let compressed_bytecodes: Vec<_> = filtered_deps.collect(); + compressed_bytecodes = filtered_deps.collect(); - self.last_tx_compressed_bytecodes - .clone_from(&compressed_bytecodes); crate::vm_m6::vm_with_bootloader::push_transaction_to_bootloader_memory( &mut self.vm, &tx, self.system_env.execution_mode.glue_into(), - Some(compressed_bytecodes), + Some(compressed_bytecodes.clone()), ); bytecode_hashes } else { + compressed_bytecodes = vec![]; crate::vm_m6::vm_with_bootloader::push_transaction_to_bootloader_memory( &mut self.vm, &tx, @@ -267,7 +182,7 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + (Ok(compressed_bytecodes), result) } } @@ -288,10 +203,6 @@ impl VmInterface for Vm { } } - fn gas_remaining(&self) -> u32 { - self.vm.gas_remaining() - } - fn finish_batch(&mut self) -> FinishedL1Batch { self.vm .execute_till_block_end( diff --git a/core/lib/multivm/src/versions/vm_m6/vm_instance.rs b/core/lib/multivm/src/versions/vm_m6/vm_instance.rs index bc60530b6f55..d6c418da4c20 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm_instance.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm_instance.rs @@ -159,6 +159,7 @@ pub struct VmPartialExecutionResult { pub contracts_used: usize, pub cycles_used: u32, pub computational_gas_used: u32, + pub gas_remaining: u32, } #[derive(Debug, Clone, PartialEq)] @@ -673,6 +674,7 @@ impl VmInstance { cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, computational_gas_used, + gas_remaining: self.gas_remaining(), }, call_traces: tx_tracer.call_traces(), }) @@ -775,6 +777,7 @@ impl VmInstance { .get_decommitted_bytecodes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, computational_gas_used, + gas_remaining: self.gas_remaining(), }; // Collecting `block_tip_result` needs logs with timestamp, so we drain events for the `full_result` @@ -823,6 +826,7 @@ impl VmInstance { contracts_used: 0, cycles_used: 0, computational_gas_used: 0, + gas_remaining: 0, }, } } else { @@ -876,6 +880,7 @@ impl VmInstance { .get_decommitted_bytecodes_after_timestamp(timestamp_initial), cycles_used: self.state.local_state.monotonic_cycle_counter - cycles_initial, computational_gas_used, + gas_remaining: self.gas_remaining(), } } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs index 2289cca7a47c..f7ab9ae8b517 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs @@ -5,7 +5,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, - CompressedBytecodeInfo, VmInterface, + CompressedBytecodeInfo, }, utils::bytecode, vm_refunds_enhancement::Vm, @@ -15,15 +15,18 @@ use crate::{ impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { - self.get_last_tx_compressed_bytecodes().iter().any(|info| { - !self - .state - .storage - .storage - .get_ptr() - .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) - }) + self.bootloader_state + .get_last_tx_compressed_bytecodes() + .iter() + .any(|info| { + !self + .state + .storage + .storage + .get_ptr() + .borrow_mut() + .is_bytecode_known(&hash_bytecode(&info.original)) + }) } } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/execution.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/execution.rs index 3f6dd7e0e9e5..cadd183735e6 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/execution.rs @@ -4,7 +4,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, VmExecutionStopReason}, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + VmExecutionMode, VmExecutionResultAndLogs, }, vm_refunds_enhancement::{ old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/gas.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/gas.rs index 0f4b5c6b6b0e..d957697a0681 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/gas.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{storage::WriteStorage, VmInterface}, + interface::storage::WriteStorage, vm_refunds_enhancement::{tracers::DefaultExecutionTracer, vm::Vm}, HistoryMode, }; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs index 821a8144249e..2aa3ba05e662 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs @@ -5,9 +5,10 @@ use crate::{ glue::GlueInto, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, - L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, - VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, + BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, + FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, + VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, + VmMemoryMetrics, }, vm_latest::HistoryEnabled, vm_refunds_enhancement::{ @@ -34,40 +35,11 @@ pub struct Vm { _phantom: std::marker::PhantomData, } -impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; - - /// Push tx into memory for the future execution - fn push_transaction(&mut self, tx: Transaction) { - self.push_transaction_with_compression(tx, true) - } - - /// Execute VM with custom tracers. - fn inspect( - &mut self, - dispatcher: Self::TracerDispatcher, - execution_mode: VmExecutionMode, - ) -> VmExecutionResultAndLogs { - self.inspect_inner(dispatcher, execution_mode) - } - - /// Get current state of bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { - self.bootloader_state.start_new_l2_block(l2_block_env); +impl Vm { + pub(super) fn gas_remaining(&self) -> u32 { + self.state.local_state.callstack.current.ergs_remaining } - /// Get current state of virtual machine. - /// This method should be used only after the batch execution. - /// Otherwise it can panic. fn get_current_execution_state(&self) -> CurrentExecutionState { let (raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) @@ -98,6 +70,28 @@ impl VmInterface for Vm { pubdata_costs: Vec::new(), } } +} + +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + /// Push tx into memory for the future execution + fn push_transaction(&mut self, tx: Transaction) { + self.push_transaction_with_compression(tx, true) + } + + /// Execute VM with custom tracers. + fn inspect( + &mut self, + dispatcher: Self::TracerDispatcher, + execution_mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(dispatcher, execution_mode) + } + + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + self.bootloader_state.start_new_l2_block(l2_block_env); + } /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( @@ -105,10 +99,7 @@ impl VmInterface for Vm { dispatcher: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect(dispatcher, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { @@ -117,17 +108,29 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + ( + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + result, + ) } } - fn gas_remaining(&self) -> u32 { - self.state.local_state.callstack.current.ergs_remaining - } - fn record_vm_memory_metrics(&self) -> VmMemoryMetrics { self.record_vm_memory_metrics_inner() } + + fn finish_batch(&mut self) -> FinishedL1Batch { + let result = self.inspect(TracerDispatcher::default(), VmExecutionMode::Batch); + let execution_state = self.get_current_execution_state(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); + FinishedL1Batch { + block_tip_execution_result: result, + final_execution_state: execution_state, + final_bootloader_memory: Some(bootloader_memory), + pubdata_input: None, + state_diffs: None, + } + } } impl VmFactory for Vm { diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs index 96a30d508054..d5f2b50b83fc 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs @@ -5,7 +5,7 @@ use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, - CompressedBytecodeInfo, VmInterface, + CompressedBytecodeInfo, }, utils::bytecode, vm_virtual_blocks::Vm, @@ -15,15 +15,18 @@ use crate::{ impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { - self.get_last_tx_compressed_bytecodes().iter().any(|info| { - !self - .state - .storage - .storage - .get_ptr() - .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) - }) + self.bootloader_state + .get_last_tx_compressed_bytecodes() + .iter() + .any(|info| { + !self + .state + .storage + .storage + .get_ptr() + .borrow_mut() + .is_bytecode_known(&hash_bytecode(&info.original)) + }) } } diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/execution.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/execution.rs index aafcca3821be..42709c345ea6 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/execution.rs @@ -4,7 +4,7 @@ use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStopReason, VmExecutionStopReason}, - VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + VmExecutionMode, VmExecutionResultAndLogs, }, vm_virtual_blocks::{ old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/gas.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/gas.rs index 28f0ec6df4a9..3b7af470f2cd 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/gas.rs @@ -1,5 +1,5 @@ use crate::{ - interface::{storage::WriteStorage, VmInterface}, + interface::storage::WriteStorage, vm_virtual_blocks::{tracers::DefaultExecutionTracer, vm::Vm}, HistoryMode, }; diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs index 8991ee1b4b9f..6080df2bf2f1 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs @@ -5,9 +5,10 @@ use crate::{ glue::GlueInto, interface::{ storage::{StoragePtr, WriteStorage}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, - L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, - VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, + BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, + FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, + VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, + VmMemoryMetrics, }, vm_latest::HistoryEnabled, vm_virtual_blocks::{ @@ -34,40 +35,11 @@ pub struct Vm { _phantom: std::marker::PhantomData, } -impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; - - /// Push tx into memory for the future execution - fn push_transaction(&mut self, tx: Transaction) { - self.push_transaction_with_compression(tx, true) - } - - /// Execute VM with custom tracers. - fn inspect( - &mut self, - tracer: TracerDispatcher, - execution_mode: VmExecutionMode, - ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode) - } - - /// Get current state of bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory { - self.bootloader_state.bootloader_memory() - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - self.bootloader_state.get_last_tx_compressed_bytecodes() - } - - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { - self.bootloader_state.start_new_l2_block(l2_block_env); +impl Vm { + pub(super) fn gas_remaining(&self) -> u32 { + self.state.local_state.callstack.current.ergs_remaining } - /// Get current state of virtual machine. - /// This method should be used only after the batch execution. - /// Otherwise it can panic. fn get_current_execution_state(&self) -> CurrentExecutionState { let (raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) @@ -98,6 +70,28 @@ impl VmInterface for Vm { pubdata_costs: Vec::new(), } } +} + +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + /// Push tx into memory for the future execution + fn push_transaction(&mut self, tx: Transaction) { + self.push_transaction_with_compression(tx, true) + } + + /// Execute VM with custom tracers. + fn inspect( + &mut self, + tracer: TracerDispatcher, + execution_mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(tracer, execution_mode) + } + + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + self.bootloader_state.start_new_l2_block(l2_block_env); + } /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( @@ -105,10 +99,7 @@ impl VmInterface for Vm { tracer: TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { @@ -117,17 +108,29 @@ impl VmInterface for Vm { result, ) } else { - (Ok(()), result) + ( + Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + result, + ) } } - fn gas_remaining(&self) -> u32 { - self.state.local_state.callstack.current.ergs_remaining - } - fn record_vm_memory_metrics(&self) -> VmMemoryMetrics { self.record_vm_memory_metrics_inner() } + + fn finish_batch(&mut self) -> FinishedL1Batch { + let result = self.inspect(TracerDispatcher::default(), VmExecutionMode::Batch); + let execution_state = self.get_current_execution_state(); + let bootloader_memory = self.bootloader_state.bootloader_memory(); + FinishedL1Batch { + block_tip_execution_result: result, + final_execution_state: execution_state, + final_bootloader_memory: Some(bootloader_memory), + pubdata_input: None, + state_diffs: None, + } + } } impl VmFactory for Vm { diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index 0e4cefd3c808..0fc626d9ac48 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -4,10 +4,9 @@ use crate::{ glue::history_mode::HistoryMode, interface::{ storage::{ImmutableStorageView, ReadStorage, StoragePtr, StorageView}, - BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState, - FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, - VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, - VmMemoryMetrics, + BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, + VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, + VmInterfaceHistoryEnabled, VmMemoryMetrics, }, tracers::TracerDispatcher, versions::shadow::ShadowVm, @@ -56,12 +55,6 @@ impl VmInterface for VmInstance { dispatch_vm!(self.push_transaction(tx)) } - /// Execute the batch without stops after each tx. - /// This method allows to execute the part of the VM cycle after executing all txs. - fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs { - dispatch_vm!(self.execute(execution_mode)) - } - /// Execute next transaction with custom tracers fn inspect( &mut self, @@ -71,45 +64,17 @@ impl VmInterface for VmInstance { dispatch_vm!(self.inspect(dispatcher.into(), execution_mode)) } - fn get_bootloader_memory(&self) -> BootloaderMemory { - dispatch_vm!(self.get_bootloader_memory()) - } - - /// Get compressed bytecodes of the last executed transaction - fn get_last_tx_compressed_bytecodes(&self) -> Vec { - dispatch_vm!(self.get_last_tx_compressed_bytecodes()) - } - fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { dispatch_vm!(self.start_new_l2_block(l2_block_env)) } - fn get_current_execution_state(&self) -> CurrentExecutionState { - dispatch_vm!(self.get_current_execution_state()) - } - - /// Execute transaction with optional bytecode compression. - fn execute_transaction_with_bytecode_compression( - &mut self, - tx: zksync_types::Transaction, - with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { - dispatch_vm!(self.execute_transaction_with_bytecode_compression(tx, with_compression)) - } - /// Inspect transaction with optional bytecode compression. fn inspect_transaction_with_bytecode_compression( &mut self, dispatcher: Self::TracerDispatcher, tx: zksync_types::Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { dispatch_vm!(self.inspect_transaction_with_bytecode_compression( dispatcher.into(), tx, @@ -121,10 +86,6 @@ impl VmInterface for VmInstance { dispatch_vm!(self.record_vm_memory_metrics()) } - fn gas_remaining(&self) -> u32 { - dispatch_vm!(self.gas_remaining()) - } - /// Return the results of execution of all batch fn finish_batch(&mut self) -> FinishedL1Batch { dispatch_vm!(self.finish_batch()) diff --git a/core/lib/tee_verifier/src/lib.rs b/core/lib/tee_verifier/src/lib.rs index 4234754a75f2..8728a4e52749 100644 --- a/core/lib/tee_verifier/src/lib.rs +++ b/core/lib/tee_verifier/src/lib.rs @@ -244,7 +244,7 @@ fn execute_tx( // Attempt to run VM with bytecode compression on. vm.make_snapshot(); if vm - .execute_transaction_with_bytecode_compression(tx.clone(), true) + .inspect_transaction_with_bytecode_compression(Default::default(), tx.clone(), true) .0 .is_ok() { @@ -255,7 +255,7 @@ fn execute_tx( // If failed with bytecode compression, attempt to run without bytecode compression. vm.rollback_to_the_latest_snapshot(); if vm - .execute_transaction_with_bytecode_compression(tx.clone(), false) + .inspect_transaction_with_bytecode_compression(Default::default(), tx.clone(), false) .0 .is_err() { diff --git a/core/lib/vm_interface/src/lib.rs b/core/lib/vm_interface/src/lib.rs index 120812842ad0..dba93a49ec86 100644 --- a/core/lib/vm_interface/src/lib.rs +++ b/core/lib/vm_interface/src/lib.rs @@ -20,8 +20,8 @@ pub use crate::{ types::{ errors::{ - BytecodeCompressionError, Halt, TxRevertReason, VmRevertReason, - VmRevertReasonParsingError, + BytecodeCompressionError, BytecodeCompressionResult, Halt, TxRevertReason, + VmRevertReason, VmRevertReasonParsingError, }, inputs::{ L1BatchEnv, L2BlockEnv, OneshotEnv, StoredL2BlockEnv, SystemEnv, TxExecutionMode, @@ -36,7 +36,7 @@ pub use crate::{ }, tracer, }, - vm::{VmFactory, VmInterface, VmInterfaceHistoryEnabled}, + vm::{VmFactory, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled}, }; pub mod storage; diff --git a/core/lib/vm_interface/src/types/errors/bytecode_compression.rs b/core/lib/vm_interface/src/types/errors/bytecode_compression.rs index 418be6b85733..1dd69dc7398d 100644 --- a/core/lib/vm_interface/src/types/errors/bytecode_compression.rs +++ b/core/lib/vm_interface/src/types/errors/bytecode_compression.rs @@ -1,3 +1,5 @@ +use crate::CompressedBytecodeInfo; + /// Errors related to bytecode compression. #[derive(Debug, thiserror::Error)] #[non_exhaustive] @@ -5,3 +7,6 @@ pub enum BytecodeCompressionError { #[error("Bytecode compression failed")] BytecodeCompressionFailed, } + +/// Result of compressing bytecodes used by a transaction. +pub type BytecodeCompressionResult = Result, BytecodeCompressionError>; diff --git a/core/lib/vm_interface/src/types/errors/mod.rs b/core/lib/vm_interface/src/types/errors/mod.rs index 070e7aa28427..a8b2df15c62b 100644 --- a/core/lib/vm_interface/src/types/errors/mod.rs +++ b/core/lib/vm_interface/src/types/errors/mod.rs @@ -1,6 +1,6 @@ pub use self::{ bootloader_error::BootloaderErrorCode, - bytecode_compression::BytecodeCompressionError, + bytecode_compression::{BytecodeCompressionError, BytecodeCompressionResult}, halt::Halt, tx_revert_reason::TxRevertReason, vm_revert_reason::{VmRevertReason, VmRevertReasonParsingError}, diff --git a/core/lib/vm_interface/src/vm.rs b/core/lib/vm_interface/src/vm.rs index b8614a46c147..b6be2c7581f7 100644 --- a/core/lib/vm_interface/src/vm.rs +++ b/core/lib/vm_interface/src/vm.rs @@ -14,9 +14,8 @@ use zksync_types::Transaction; use crate::{ - storage::StoragePtr, BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, - CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, - VmExecutionResultAndLogs, VmMemoryMetrics, + storage::StoragePtr, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, + SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmMemoryMetrics, }; pub trait VmInterface { @@ -25,11 +24,6 @@ pub trait VmInterface { /// Push transaction to bootloader memory. fn push_transaction(&mut self, tx: Transaction); - /// Execute next VM step (either next transaction or bootloader or the whole batch). - fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs { - self.inspect(Self::TracerDispatcher::default(), execution_mode) - } - /// Execute next VM step (either next transaction or bootloader or the whole batch) /// with custom tracers. fn inspect( @@ -38,67 +32,48 @@ pub trait VmInterface { execution_mode: VmExecutionMode, ) -> VmExecutionResultAndLogs; - /// Get bootloader memory. - fn get_bootloader_memory(&self) -> BootloaderMemory; - - /// Get last transaction's compressed bytecodes. - fn get_last_tx_compressed_bytecodes(&self) -> Vec; - /// Start a new L2 block. fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv); - /// Get the current state of the virtual machine. - fn get_current_execution_state(&self) -> CurrentExecutionState; - - /// Execute transaction with optional bytecode compression. - fn execute_transaction_with_bytecode_compression( - &mut self, - tx: Transaction, - with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { - self.inspect_transaction_with_bytecode_compression( - Self::TracerDispatcher::default(), - tx, - with_compression, - ) - } - /// Execute transaction with optional bytecode compression using custom tracers. fn inspect_transaction_with_bytecode_compression( &mut self, tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> ( - Result<(), BytecodeCompressionError>, - VmExecutionResultAndLogs, - ); + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs); /// Record VM memory metrics. fn record_vm_memory_metrics(&self) -> VmMemoryMetrics; - /// How much gas is left in the current stack frame. - fn gas_remaining(&self) -> u32; - /// Execute batch till the end and return the result, with final execution state /// and bootloader memory. - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.execute(VmExecutionMode::Batch); - let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.get_bootloader_memory(); - FinishedL1Batch { - block_tip_execution_result: result, - final_execution_state: execution_state, - final_bootloader_memory: Some(bootloader_memory), - pubdata_input: None, - state_diffs: None, - } + fn finish_batch(&mut self) -> FinishedL1Batch; +} + +/// Extension trait for [`VmInterface`] that provides some additional methods. +pub trait VmInterfaceExt: VmInterface { + /// Executes the next VM step (either next transaction or bootloader or the whole batch). + fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs { + self.inspect(Self::TracerDispatcher::default(), execution_mode) + } + + /// Executes a transaction with optional bytecode compression. + fn execute_transaction_with_bytecode_compression( + &mut self, + tx: Transaction, + with_compression: bool, + ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + self.inspect_transaction_with_bytecode_compression( + Self::TracerDispatcher::default(), + tx, + with_compression, + ) } } +impl VmInterfaceExt for T {} + /// Encapsulates creating VM instance based on the provided environment. pub trait VmFactory: VmInterface { /// Creates a new VM instance. diff --git a/core/node/api_server/src/execution_sandbox/apply.rs b/core/node/api_server/src/execution_sandbox/apply.rs index 0ec857e1e2b1..8b5cf69822bf 100644 --- a/core/node/api_server/src/execution_sandbox/apply.rs +++ b/core/node/api_server/src/execution_sandbox/apply.rs @@ -405,7 +405,13 @@ where let tracers = VmSandbox::wrap_tracers(tracers, &env, missed_storage_invocation_limit); let executor = VmSandbox::new(storage, env, args); executor.apply(|vm, transaction| { - vm.inspect_transaction_with_bytecode_compression(tracers.into(), transaction, true) + let (bytecodes_result, exec_result) = vm + .inspect_transaction_with_bytecode_compression( + tracers.into(), + transaction, + true, + ); + (bytecodes_result.map(drop), exec_result) }) }) .await diff --git a/core/node/state_keeper/src/batch_executor/main_executor.rs b/core/node/state_keeper/src/batch_executor/main_executor.rs index db4daeb77444..7d1bf5f47b17 100644 --- a/core/node/state_keeper/src/batch_executor/main_executor.rs +++ b/core/node/state_keeper/src/batch_executor/main_executor.rs @@ -205,7 +205,7 @@ impl CommandReceiver { } let tx_metrics = ExecutionMetricsForCriteria::new(Some(tx), &tx_result); - let gas_remaining = vm.gas_remaining(); + let gas_remaining = tx_result.statistics.gas_remaining; Ok(TxExecutionResult::Success { tx_result: Box::new(tx_result), @@ -270,11 +270,9 @@ impl CommandReceiver { vec![] }; - if let (Ok(()), tx_result) = + if let (Ok(compressed_bytecodes), tx_result) = vm.inspect_transaction_with_bytecode_compression(tracer.into(), tx.clone(), true) { - let compressed_bytecodes = vm.get_last_tx_compressed_bytecodes(); - let calls = Arc::try_unwrap(call_tracer_result) .map_err(|_| anyhow::anyhow!("failed extracting call traces"))? .take() @@ -300,8 +298,8 @@ impl CommandReceiver { let (compression_result, tx_result) = vm.inspect_transaction_with_bytecode_compression(tracer.into(), tx.clone(), false); - compression_result.context("compression failed when it wasn't applied")?; - let compressed_bytecodes = vm.get_last_tx_compressed_bytecodes(); + let compressed_bytecodes = + compression_result.context("compression failed when it wasn't applied")?; // TODO implement tracer manager which will be responsible // for collecting result from all tracers and save it to the database @@ -330,10 +328,9 @@ impl CommandReceiver { vec![] }; - let (published_bytecodes, mut tx_result) = + let (bytecodes_result, mut tx_result) = vm.inspect_transaction_with_bytecode_compression(tracer.into(), tx.clone(), true); - if published_bytecodes.is_ok() { - let compressed_bytecodes = vm.get_last_tx_compressed_bytecodes(); + if let Ok(compressed_bytecodes) = bytecodes_result { let calls = Arc::try_unwrap(call_tracer_result) .map_err(|_| anyhow::anyhow!("failed extracting call traces"))? .take() diff --git a/core/tests/vm-benchmark/src/vm.rs b/core/tests/vm-benchmark/src/vm.rs index e805554d5584..f3c00667c7dd 100644 --- a/core/tests/vm-benchmark/src/vm.rs +++ b/core/tests/vm-benchmark/src/vm.rs @@ -6,7 +6,8 @@ use zksync_multivm::{ interface::{ storage::{InMemoryStorage, StorageView}, ExecutionResult, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, - VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, + VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceExt, + VmInterfaceHistoryEnabled, }, vm_fast, vm_latest, vm_latest::{constants::BATCH_COMPUTATIONAL_GAS_LIMIT, HistoryEnabled},