From 1a9841733cc62ec89a2e61ba4f6ea03c51efc402 Mon Sep 17 00:00:00 2001 From: Danil Date: Tue, 7 Nov 2023 13:06:27 +0100 Subject: [PATCH] Apply interface for latest and vm refunds enhancement Signed-off-by: Danil --- .../system-constants-generator/src/utils.rs | 2 +- core/lib/multivm/src/glue/init_vm.rs | 1 - core/lib/multivm/src/glue/tracers/mod.rs | 24 +- .../traits/tracers/dyn_tracers/mod.rs | 1 + .../traits/tracers/dyn_tracers/vm_1_4_0.rs | 33 ++ .../multivm/src/tracers/call_tracer/mod.rs | 1 + .../src/tracers/call_tracer/vm_latest/mod.rs | 2 +- .../vm_refunds_enhancement/mod.rs} | 74 +--- .../src/tracers/storage_invocation/mod.rs | 1 + .../storage_invocation/vm_latest/mod.rs | 2 +- .../vm_refunds_enhancement/mod.rs | 30 ++ core/lib/multivm/src/tracers/validator/mod.rs | 1 + .../src/tracers/validator/vm_latest/mod.rs | 34 +- .../validator/vm_refunds_enhancement/mod.rs | 201 +++++++++ .../vm_latest/implementation/execution.rs | 4 +- .../versions/vm_latest/implementation/gas.rs | 2 +- .../versions/vm_latest/implementation/logs.rs | 6 +- .../vm_latest/implementation/statistics.rs | 2 +- .../vm_latest/tracers/default_tracers.rs | 13 +- .../versions/vm_latest/tracers/dispatcher.rs | 4 +- .../vm_latest/tracers/pubdata_tracer.rs | 14 +- .../src/versions/vm_latest/tracers/refunds.rs | 2 +- .../vm_latest/tracers/result_tracer.rs | 2 +- .../src/versions/vm_latest/tracers/traits.rs | 8 +- core/lib/multivm/src/versions/vm_latest/vm.rs | 4 +- .../implementation/bytecode.rs | 4 +- .../implementation/execution.rs | 35 +- .../implementation/gas.rs | 4 +- .../implementation/logs.rs | 2 +- .../implementation/snapshots.rs | 5 +- .../implementation/statistics.rs | 4 +- .../implementation/tx.rs | 2 +- .../versions/vm_refunds_enhancement/mod.rs | 9 +- .../tracers/default_tracers.rs | 68 +-- .../tracers/dispatcher.rs | 115 +++++ .../vm_refunds_enhancement/tracers/mod.rs | 7 +- .../vm_refunds_enhancement/tracers/refunds.rs | 28 +- .../tracers/result_tracer.rs | 12 +- .../tracers/storage_invocations.rs | 45 -- .../vm_refunds_enhancement/tracers/traits.rs | 81 +--- .../vm_refunds_enhancement/tracers/utils.rs | 22 +- .../tracers/validation/error.rs | 22 - .../tracers/validation/mod.rs | 409 ------------------ .../tracers/validation/params.rs | 18 - .../tracers/validation/types.rs | 18 - .../src/versions/vm_refunds_enhancement/vm.rs | 60 +-- .../src/versions/vm_virtual_blocks/mod.rs | 1 - .../vm_virtual_blocks/tracers/utils.rs | 6 - core/lib/multivm/src/vm_instance.rs | 28 +- 49 files changed, 619 insertions(+), 854 deletions(-) create mode 100644 core/lib/multivm/src/interface/traits/tracers/dyn_tracers/vm_1_4_0.rs rename core/lib/multivm/src/{versions/vm_refunds_enhancement/tracers/call.rs => tracers/call_tracer/vm_refunds_enhancement/mod.rs} (77%) create mode 100644 core/lib/multivm/src/tracers/storage_invocation/vm_refunds_enhancement/mod.rs create mode 100644 core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs create mode 100644 core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/dispatcher.rs delete mode 100644 core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/storage_invocations.rs delete mode 100644 core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/error.rs delete mode 100644 core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/mod.rs delete mode 100644 core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/params.rs delete mode 100644 core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/types.rs diff --git a/core/bin/system-constants-generator/src/utils.rs b/core/bin/system-constants-generator/src/utils.rs index 6f66693f9a17..bb0a8f31663e 100644 --- a/core/bin/system-constants-generator/src/utils.rs +++ b/core/bin/system-constants-generator/src/utils.rs @@ -1,4 +1,4 @@ -use multivm::interface::dyn_tracers::vm_1_3_3::DynTracer; +use multivm::interface::dyn_tracers::vm_1_4_0::DynTracer; use multivm::interface::tracer::VmExecutionStopReason; use multivm::interface::{ L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmInterface, diff --git a/core/lib/multivm/src/glue/init_vm.rs b/core/lib/multivm/src/glue/init_vm.rs index 9593e7e53ffb..cf16b31301e0 100644 --- a/core/lib/multivm/src/glue/init_vm.rs +++ b/core/lib/multivm/src/glue/init_vm.rs @@ -180,7 +180,6 @@ impl VmInstance { l1_batch_env.glue_into(), system_env.clone(), storage_view.clone(), - H::VmBoojumIntegration::default(), ); let vm = VmInstanceVersion::VmBoojumIntegration(Box::new(vm)); Self { diff --git a/core/lib/multivm/src/glue/tracers/mod.rs b/core/lib/multivm/src/glue/tracers/mod.rs index 1313dd2b53f1..b9c0e083b84c 100644 --- a/core/lib/multivm/src/glue/tracers/mod.rs +++ b/core/lib/multivm/src/glue/tracers/mod.rs @@ -47,7 +47,7 @@ pub trait MultivmTracer: } pub trait IntoLatestTracer { - fn latest(&self) -> crate::vm_latest::TracerPointer; + fn latest(&self) -> crate::vm_latest::TracerPointer; } pub trait IntoVmVirtualBlocksTracer { @@ -68,7 +68,7 @@ where H: HistoryMode, T: crate::vm_latest::VmTracer + Clone + 'static, { - fn latest(&self) -> crate::vm_latest::TracerPointer { + fn latest(&self) -> crate::vm_latest::TracerPointer { Box::new(self.clone()) } } @@ -86,10 +86,28 @@ where } } +impl IntoVmRefundsEnhancementTracer for T +where + S: WriteStorage, + H: HistoryMode, + T: crate::vm_refunds_enhancement::VmTracer + + Clone + + 'static, +{ + fn vm_refunds_enhancement( + &self, + ) -> Box> + { + Box::new(self.clone()) + } +} + impl MultivmTracer for T where S: WriteStorage, H: HistoryMode, - T: IntoLatestTracer + IntoVmVirtualBlocksTracer, + T: IntoLatestTracer + + IntoVmVirtualBlocksTracer + + IntoVmRefundsEnhancementTracer, { } diff --git a/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/mod.rs b/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/mod.rs index b34df6bfa2a3..bc34775e6133 100644 --- a/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/mod.rs +++ b/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/mod.rs @@ -1 +1,2 @@ pub mod vm_1_3_3; +pub mod vm_1_4_0; diff --git a/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/vm_1_4_0.rs b/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/vm_1_4_0.rs new file mode 100644 index 000000000000..61d7831393d2 --- /dev/null +++ b/core/lib/multivm/src/interface/traits/tracers/dyn_tracers/vm_1_4_0.rs @@ -0,0 +1,33 @@ +use zk_evm_1_4_0::abstractions::Memory; +use zk_evm_1_4_0::tracing::{ + AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, +}; +use zksync_state::StoragePtr; + +/// Version of zk_evm_1_3_3::Tracer suitable for dynamic dispatch. +pub trait DynTracer { + fn before_decoding(&mut self, _state: VmLocalStateData<'_>, _memory: &M) {} + fn after_decoding( + &mut self, + _state: VmLocalStateData<'_>, + _data: AfterDecodingData, + _memory: &M, + ) { + } + fn before_execution( + &mut self, + _state: VmLocalStateData<'_>, + _data: BeforeExecutionData, + _memory: &M, + _storage: StoragePtr, + ) { + } + fn after_execution( + &mut self, + _state: VmLocalStateData<'_>, + _data: AfterExecutionData, + _memory: &M, + _storage: StoragePtr, + ) { + } +} diff --git a/core/lib/multivm/src/tracers/call_tracer/mod.rs b/core/lib/multivm/src/tracers/call_tracer/mod.rs index 6694dd760d52..90343a53bf66 100644 --- a/core/lib/multivm/src/tracers/call_tracer/mod.rs +++ b/core/lib/multivm/src/tracers/call_tracer/mod.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use zksync_types::vm_trace::Call; pub mod vm_latest; +pub mod vm_refunds_enhancement; pub mod vm_virtual_blocks; #[derive(Debug, Clone)] diff --git a/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs b/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs index c0ba34b668ec..7266293861b5 100644 --- a/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs @@ -1,5 +1,5 @@ use crate::interface::tracer::VmExecutionStopReason; -use crate::interface::{traits::tracers::dyn_tracers::vm_1_3_3::DynTracer, VmRevertReason}; +use crate::interface::{traits::tracers::dyn_tracers::vm_1_4_0::DynTracer, VmRevertReason}; use crate::tracers::call_tracer::{CallTracer, FarcallAndNearCallCount}; use crate::vm_latest::VmTracer; use crate::vm_latest::{BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/call.rs b/core/lib/multivm/src/tracers/call_tracer/vm_refunds_enhancement/mod.rs similarity index 77% rename from core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/call.rs rename to core/lib/multivm/src/tracers/call_tracer/vm_refunds_enhancement/mod.rs index 557d0fc58906..d0e8cec18e0e 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/call.rs +++ b/core/lib/multivm/src/tracers/call_tracer/vm_refunds_enhancement/mod.rs @@ -1,49 +1,20 @@ -use once_cell::sync::OnceCell; -use std::marker::PhantomData; -use std::sync::Arc; - +use crate::interface::tracer::VmExecutionStopReason; +use crate::interface::{traits::tracers::dyn_tracers::vm_1_3_3::DynTracer, VmRevertReason}; +use crate::tracers::call_tracer::{CallTracer, FarcallAndNearCallCount}; +use crate::vm_refunds_enhancement::VmTracer; +use crate::vm_refunds_enhancement::{BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}; use zk_evm_1_3_3::tracing::{AfterExecutionData, VmLocalStateData}; use zk_evm_1_3_3::zkevm_opcode_defs::{ - FarCallABI, FarCallOpcode, FatPointer, Opcode, RetOpcode, - CALL_IMPLICIT_CALLDATA_FAT_PTR_REGISTER, RET_IMPLICIT_RETURNDATA_PARAMS_REGISTER, + FarCallABI, FatPointer, Opcode, RetOpcode, CALL_IMPLICIT_CALLDATA_FAT_PTR_REGISTER, + RET_IMPLICIT_RETURNDATA_PARAMS_REGISTER, }; - -use crate::interface::VmRevertReason; use zksync_state::{StoragePtr, WriteStorage}; use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; use zksync_types::vm_trace::{Call, CallType}; +use zksync_types::FarCallOpcode; use zksync_types::U256; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; -use crate::vm_refunds_enhancement::old_vm::memory::SimpleMemory; -use crate::vm_refunds_enhancement::tracers::traits::{DynTracer, VmTracer}; -use crate::vm_refunds_enhancement::types::internals::ZkSyncVmState; -use crate::vm_refunds_enhancement::{BootloaderState, VmExecutionStopReason}; - -#[derive(Debug, Clone)] -pub struct CallTracer { - stack: Vec, - pub result: Arc>>, - _phantom: PhantomData H>, -} - -#[derive(Debug, Clone)] -struct FarcallAndNearCallCount { - farcall: Call, - near_calls_after: usize, -} - -impl CallTracer { - pub fn new(resulted_stack: Arc>>, _history: H) -> Self { - Self { - stack: vec![], - result: resulted_stack, - _phantom: PhantomData, - } - } -} - -impl DynTracer for CallTracer { +impl DynTracer> for CallTracer { fn after_execution( &mut self, state: VmLocalStateData<'_>, @@ -75,43 +46,35 @@ impl DynTracer for CallTracer { ..Default::default() }; - self.handle_far_call_op_code(state, data, memory, &mut current_call); + self.handle_far_call_op_code_refunds_enhancement(state, memory, &mut current_call); self.stack.push(FarcallAndNearCallCount { farcall: current_call, near_calls_after: 0, }); } Opcode::Ret(ret_code) => { - self.handle_ret_op_code(state, data, memory, ret_code); + self.handle_ret_op_code_refunds_enhancement(state, memory, ret_code); } _ => {} }; } } -impl VmTracer for CallTracer { +impl VmTracer for CallTracer { fn after_vm_execution( &mut self, _state: &mut ZkSyncVmState, _bootloader_state: &BootloaderState, _stop_reason: VmExecutionStopReason, ) { - self.result - .set( - std::mem::take(&mut self.stack) - .into_iter() - .map(|x| x.farcall) - .collect(), - ) - .expect("Result is already set"); + self.store_result() } } -impl CallTracer { - fn handle_far_call_op_code( +impl CallTracer { + fn handle_far_call_op_code_refunds_enhancement( &mut self, state: VmLocalStateData<'_>, - _data: AfterExecutionData, memory: &SimpleMemory, current_call: &mut Call, ) { @@ -164,7 +127,7 @@ impl CallTracer { current_call.gas = current.ergs_remaining; } - fn save_output( + fn save_output_refunds_enhancement( &mut self, state: VmLocalStateData<'_>, memory: &SimpleMemory, @@ -208,10 +171,9 @@ impl CallTracer { } } - fn handle_ret_op_code( + fn handle_ret_op_code_refunds_enhancement( &mut self, state: VmLocalStateData<'_>, - _data: AfterExecutionData, memory: &SimpleMemory, ret_opcode: RetOpcode, ) { @@ -230,7 +192,7 @@ impl CallTracer { .parent_gas .saturating_sub(state.vm_local_state.callstack.current.ergs_remaining); - self.save_output(state, memory, ret_opcode, &mut current_call.farcall); + self.save_output_refunds_enhancement(state, memory, ret_opcode, &mut current_call.farcall); // If there is a parent call, push the current call to it // Otherwise, push the current call to the stack, because it's the top level call diff --git a/core/lib/multivm/src/tracers/storage_invocation/mod.rs b/core/lib/multivm/src/tracers/storage_invocation/mod.rs index f27b646a95f4..3816d2a07a14 100644 --- a/core/lib/multivm/src/tracers/storage_invocation/mod.rs +++ b/core/lib/multivm/src/tracers/storage_invocation/mod.rs @@ -1,4 +1,5 @@ pub mod vm_latest; +pub mod vm_refunds_enhancement; pub mod vm_virtual_blocks; /// Tracer responsible for calculating the number of storage invocations and diff --git a/core/lib/multivm/src/tracers/storage_invocation/vm_latest/mod.rs b/core/lib/multivm/src/tracers/storage_invocation/vm_latest/mod.rs index 2e64cbe0879c..09e1292e5024 100644 --- a/core/lib/multivm/src/tracers/storage_invocation/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/storage_invocation/vm_latest/mod.rs @@ -1,5 +1,5 @@ use crate::interface::tracer::{TracerExecutionStatus, TracerExecutionStopReason}; -use crate::interface::{traits::tracers::dyn_tracers::vm_1_3_3::DynTracer, Halt}; +use crate::interface::{traits::tracers::dyn_tracers::vm_1_4_0::DynTracer, Halt}; use crate::tracers::storage_invocation::StorageInvocations; use crate::vm_latest::VmTracer; use crate::vm_latest::{BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}; diff --git a/core/lib/multivm/src/tracers/storage_invocation/vm_refunds_enhancement/mod.rs b/core/lib/multivm/src/tracers/storage_invocation/vm_refunds_enhancement/mod.rs new file mode 100644 index 000000000000..fe4fc33418db --- /dev/null +++ b/core/lib/multivm/src/tracers/storage_invocation/vm_refunds_enhancement/mod.rs @@ -0,0 +1,30 @@ +use crate::interface::tracer::{TracerExecutionStatus, TracerExecutionStopReason}; +use crate::interface::{traits::tracers::dyn_tracers::vm_1_3_3::DynTracer, Halt}; +use crate::tracers::storage_invocation::StorageInvocations; +use crate::vm_refunds_enhancement::VmTracer; +use crate::vm_refunds_enhancement::{BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}; +use zksync_state::WriteStorage; + +impl DynTracer> for StorageInvocations {} + +impl VmTracer for StorageInvocations { + fn finish_cycle( + &mut self, + state: &mut ZkSyncVmState, + _bootloader_state: &mut BootloaderState, + ) -> TracerExecutionStatus { + let current = state + .storage + .storage + .get_ptr() + .borrow() + .missed_storage_invocations(); + + if current >= self.limit { + return TracerExecutionStatus::Stop(TracerExecutionStopReason::Abort( + Halt::TracerCustom("Storage invocations limit reached".to_string()), + )); + } + TracerExecutionStatus::Continue + } +} diff --git a/core/lib/multivm/src/tracers/validator/mod.rs b/core/lib/multivm/src/tracers/validator/mod.rs index 88e76f854db8..26d3b0ad926c 100644 --- a/core/lib/multivm/src/tracers/validator/mod.rs +++ b/core/lib/multivm/src/tracers/validator/mod.rs @@ -1,5 +1,6 @@ mod types; mod vm_latest; +mod vm_refunds_enhancement; mod vm_virtual_blocks; use std::sync::Arc; diff --git a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs index 2d04098253ca..4d5ff43ec470 100644 --- a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs @@ -1,4 +1,4 @@ -use zk_evm_1_3_3::{ +use zk_evm_1_4_0::{ tracing::{BeforeExecutionData, VmLocalStateData}, zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; @@ -15,23 +15,25 @@ use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h25 use crate::vm_latest::tracers::utils::{ computational_gas_price, get_calldata_page_via_abi, print_debug_if_needed, VmHook, }; -use crate::vm_latest::SimpleMemory; -use crate::vm_latest::VmTracer; -use crate::interface::traits::tracers::dyn_tracers::vm_1_3_3::DynTracer; -use crate::interface::types::tracer::{TracerExecutionStatus, TracerExecutionStopReason}; -use crate::interface::Halt; -use crate::tracers::validator::types::{NewTrustedValidationItems, ValidationTracerMode}; -use crate::tracers::validator::{ValidationRoundResult, ValidationTracer}; +use crate::interface::{ + traits::tracers::dyn_tracers::vm_1_4_0::DynTracer, + types::tracer::{TracerExecutionStatus, TracerExecutionStopReason}, + Halt, +}; +use crate::tracers::validator::{ + types::{NewTrustedValidationItems, ValidationTracerMode}, + {ValidationRoundResult, ValidationTracer}, +}; -use crate::vm_latest::{BootloaderState, ZkSyncVmState}; +use crate::vm_latest::{BootloaderState, SimpleMemory, VmTracer, ZkSyncVmState}; impl ValidationTracer { fn check_user_restrictions_vm_latest( &mut self, state: VmLocalStateData<'_>, data: BeforeExecutionData, - memory: &SimpleMemory, + memory: &SimpleMemory, storage: StoragePtr, ) -> ValidationRoundResult { if self.computational_gas_used > self.computational_gas_limit { @@ -125,14 +127,14 @@ impl ValidationTracer { } } -impl - DynTracer> for ValidationTracer +impl DynTracer> + for ValidationTracer { fn before_execution( &mut self, state: VmLocalStateData<'_>, data: BeforeExecutionData, - memory: &SimpleMemory, + memory: &SimpleMemory, storage: StoragePtr, ) { // For now, we support only validations for users. @@ -180,12 +182,10 @@ impl } } -impl VmTracer - for ValidationTracer -{ +impl VmTracer for ValidationTracer { fn finish_cycle( &mut self, - _state: &mut ZkSyncVmState, + _state: &mut ZkSyncVmState, _bootloader_state: &mut BootloaderState, ) -> TracerExecutionStatus { if self.should_stop_execution { diff --git a/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs b/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs new file mode 100644 index 000000000000..7e9cc124b6a6 --- /dev/null +++ b/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs @@ -0,0 +1,201 @@ +use zk_evm_1_3_3::{ + tracing::{BeforeExecutionData, VmLocalStateData}, + zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, +}; + +use zksync_state::{StoragePtr, WriteStorage}; +use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; + +use crate::HistoryMode; +use zksync_types::{ + get_code_key, vm_trace::ViolatedValidationRule, AccountTreeId, StorageKey, H256, +}; +use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; + +use crate::vm_refunds_enhancement::tracers::utils::{ + computational_gas_price, get_calldata_page_via_abi, print_debug_if_needed, VmHook, +}; +use crate::vm_refunds_enhancement::SimpleMemory; +use crate::vm_refunds_enhancement::VmTracer; + +use crate::interface::traits::tracers::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::types::tracer::{TracerExecutionStatus, TracerExecutionStopReason}; +use crate::interface::Halt; +use crate::tracers::validator::types::{NewTrustedValidationItems, ValidationTracerMode}; +use crate::tracers::validator::{ValidationRoundResult, ValidationTracer}; + +use crate::vm_refunds_enhancement::{BootloaderState, ZkSyncVmState}; + +impl ValidationTracer { + fn check_user_restrictions_vm_refunds_enhancement( + &mut self, + state: VmLocalStateData<'_>, + data: BeforeExecutionData, + memory: &SimpleMemory, + storage: StoragePtr, + ) -> ValidationRoundResult { + if self.computational_gas_used > self.computational_gas_limit { + return Err(ViolatedValidationRule::TookTooManyComputationalGas( + self.computational_gas_limit, + )); + } + + let opcode_variant = data.opcode.variant; + match opcode_variant.opcode { + Opcode::FarCall(_) => { + let packed_abi = data.src0_value.value; + let call_destination_value = data.src1_value.value; + + let called_address = u256_to_account_address(&call_destination_value); + let far_call_abi = FarCallABI::from_u256(packed_abi); + + if called_address == KECCAK256_PRECOMPILE_ADDRESS + && far_call_abi.memory_quasi_fat_pointer.length == 64 + { + let calldata_page = get_calldata_page_via_abi( + &far_call_abi, + state.vm_local_state.callstack.current.base_memory_page, + ); + let calldata = memory.read_unaligned_bytes( + calldata_page as usize, + far_call_abi.memory_quasi_fat_pointer.start as usize, + 64, + ); + + let slot_to_add = + self.slot_to_add_from_keccak_call(&calldata, self.user_address); + + if let Some(slot) = slot_to_add { + return Ok(NewTrustedValidationItems { + new_allowed_slots: vec![slot], + ..Default::default() + }); + } + } else if called_address != self.user_address { + let code_key = get_code_key(&called_address); + let code = storage.borrow_mut().read_value(&code_key); + + if code == H256::zero() { + // The users are not allowed to call contracts with no code + return Err(ViolatedValidationRule::CalledContractWithNoCode( + called_address, + )); + } + } + } + Opcode::Context(context) => { + match context { + ContextOpcode::Meta => { + return Err(ViolatedValidationRule::TouchedUnallowedContext); + } + ContextOpcode::ErgsLeft => { + // TODO (SMA-1168): implement the correct restrictions for the gas left opcode. + } + _ => {} + } + } + Opcode::Log(LogOpcode::StorageRead) => { + let key = data.src0_value.value; + let this_address = state.vm_local_state.callstack.current.this_address; + let msg_sender = state.vm_local_state.callstack.current.msg_sender; + + if !self.is_allowed_storage_read(storage.clone(), this_address, key, msg_sender) { + return Err(ViolatedValidationRule::TouchedUnallowedStorageSlots( + this_address, + key, + )); + } + + if self.trusted_address_slots.contains(&(this_address, key)) { + let storage_key = + StorageKey::new(AccountTreeId::new(this_address), u256_to_h256(key)); + + let value = storage.borrow_mut().read_value(&storage_key); + + return Ok(NewTrustedValidationItems { + new_trusted_addresses: vec![h256_to_account_address(&value)], + ..Default::default() + }); + } + } + _ => {} + } + + Ok(Default::default()) + } +} + +impl + DynTracer> for ValidationTracer +{ + fn before_execution( + &mut self, + state: VmLocalStateData<'_>, + data: BeforeExecutionData, + memory: &SimpleMemory, + storage: StoragePtr, + ) { + // For now, we support only validations for users. + if let ValidationTracerMode::UserTxValidation = self.validation_mode { + self.computational_gas_used = self + .computational_gas_used + .saturating_add(computational_gas_price(state, &data)); + + let validation_round_result = + self.check_user_restrictions_vm_refunds_enhancement(state, data, memory, storage); + self.process_validation_round_result(validation_round_result); + } + + let hook = VmHook::from_opcode_memory(&state, &data); + print_debug_if_needed(&hook, &state, memory); + + let current_mode = self.validation_mode; + match (current_mode, hook) { + (ValidationTracerMode::NoValidation, VmHook::AccountValidationEntered) => { + // Account validation can be entered when there is no prior validation (i.e. "nested" validations are not allowed) + self.validation_mode = ValidationTracerMode::UserTxValidation; + } + (ValidationTracerMode::NoValidation, VmHook::PaymasterValidationEntered) => { + // Paymaster validation can be entered when there is no prior validation (i.e. "nested" validations are not allowed) + self.validation_mode = ValidationTracerMode::PaymasterTxValidation; + } + (_, VmHook::AccountValidationEntered | VmHook::PaymasterValidationEntered) => { + panic!( + "Unallowed transition inside the validation tracer. Mode: {:#?}, hook: {:#?}", + self.validation_mode, hook + ); + } + (_, VmHook::NoValidationEntered) => { + // Validation can be always turned off + self.validation_mode = ValidationTracerMode::NoValidation; + } + (_, VmHook::ValidationStepEndeded) => { + // The validation step has ended. + self.should_stop_execution = true; + } + (_, _) => { + // The hook is not relevant to the validation tracer. Ignore. + } + } + } +} + +impl VmTracer + for ValidationTracer +{ + fn finish_cycle( + &mut self, + _state: &mut ZkSyncVmState, + _bootloader_state: &mut BootloaderState, + ) -> TracerExecutionStatus { + if self.should_stop_execution { + return TracerExecutionStatus::Stop(TracerExecutionStopReason::Finish); + } + if let Some(result) = self.result.get() { + return TracerExecutionStatus::Stop(TracerExecutionStopReason::Abort( + Halt::TracerCustom(format!("Validation error: {:#?}", result)), + )); + } + TracerExecutionStatus::Continue + } +} 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 dce926493736..f2c952f3fc89 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs @@ -7,13 +7,13 @@ use crate::interface::types::tracer::TracerExecutionStatus; use crate::interface::{VmExecutionMode, VmExecutionResultAndLogs}; use crate::vm_latest::old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}; use crate::vm_latest::tracers::dispatcher::TracerDispatcher; -use crate::vm_latest::tracers::{DefaultExecutionTracer, RefundsTracer}; +use crate::vm_latest::tracers::{DefaultExecutionTracer, PubdataTracer, RefundsTracer}; use crate::vm_latest::vm::Vm; impl Vm { pub(crate) fn inspect_inner( &mut self, - dispatcher: TracerDispatcher, + dispatcher: TracerDispatcher, execution_mode: VmExecutionMode, ) -> VmExecutionResultAndLogs { let mut enable_refund_tracer = false; 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 9f494179c0ea..c970cd4e5d24 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/gas.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/gas.rs @@ -19,7 +19,7 @@ impl Vm { pub(crate) fn calculate_computational_gas_used( &self, - tracer: &DefaultExecutionTracer, + tracer: &DefaultExecutionTracer, gas_remaining_before: u32, spent_pubdata_counter_before: u32, ) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/logs.rs b/core/lib/multivm/src/versions/vm_latest/implementation/logs.rs index a1813d414343..c468cf87817c 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/logs.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/logs.rs @@ -3,11 +3,11 @@ use zksync_state::WriteStorage; use zksync_types::event::extract_l2tol1logs_from_l1_messenger; use crate::HistoryMode; -use zksync_types::l2_to_l1_log::L2ToL1Log; -use zksync_types::tx::tx_execution_info::VmExecutionLogs; +use zksync_types::l2_to_l1_log::{L2ToL1Log, SystemL2ToL1Log, UserL2ToL1Log}; use zksync_types::VmEvent; -use crate::vm_latest::old_vm::events::merge_events; +use crate::interface::types::outputs::VmExecutionLogs; + use crate::vm_latest::old_vm::utils::precompile_calls_count_after_timestamp; use crate::vm_latest::utils::logs; use crate::vm_latest::vm::Vm; diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/statistics.rs b/core/lib/multivm/src/versions/vm_latest/implementation/statistics.rs index d95e3e1c929b..71ecc1a203d3 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/statistics.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/statistics.rs @@ -18,7 +18,7 @@ impl Vm { &self, timestamp_initial: Timestamp, cycles_initial: u32, - tracer: &DefaultExecutionTracer, + tracer: &DefaultExecutionTracer, gas_remaining_before: u32, gas_remaining_after: u32, spent_pubdata_counter_before: u32, diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs b/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs index 1aa45b5b4973..bfcf331243c4 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs @@ -14,7 +14,7 @@ use zk_evm_1_4_0::{ use zksync_state::{StoragePtr, WriteStorage}; use zksync_types::Timestamp; -use crate::interface::traits::tracers::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::traits::tracers::dyn_tracers::vm_1_4_0::DynTracer; use crate::interface::types::tracer::TracerExecutionStatus; use crate::vm_latest::bootloader_state::utils::apply_l2_block; use crate::vm_latest::bootloader_state::BootloaderState; @@ -85,7 +85,7 @@ impl Tracer for DefaultExecutionTracer { data: AfterDecodingData, memory: &Self::SupportedMemory, ) { - >::after_decoding( + >>::after_decoding( &mut self.result_tracer, state, data, @@ -93,7 +93,7 @@ impl Tracer for DefaultExecutionTracer { ); if let Some(refund_tracer) = &mut self.refund_tracer { - >::after_decoding( + >>::after_decoding( refund_tracer, state, data, @@ -101,7 +101,12 @@ impl Tracer for DefaultExecutionTracer { ); } if let Some(pubdata_tracer) = &mut self.pubdata_tracer { - >::after_decoding(pubdata_tracer, state, data, memory); + >>::after_decoding( + pubdata_tracer, + state, + data, + memory, + ); } self.dispatcher.after_decoding(state, data, memory) } diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs b/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs index 241c192dbf82..72124d8f6611 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs @@ -1,9 +1,9 @@ -use crate::interface::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::dyn_tracers::vm_1_4_0::DynTracer; use crate::interface::tracer::{TracerExecutionStatus, VmExecutionStopReason}; use crate::vm_latest::{ BootloaderState, HistoryMode, SimpleMemory, TracerPointer, VmTracer, ZkSyncVmState, }; -use zk_evm_1_3_3::tracing::{ +use zk_evm_1_4_0::tracing::{ AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, }; use zksync_state::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs index b43c96cb9124..0c6dfa5611c9 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs @@ -20,16 +20,12 @@ use crate::vm_latest::{ old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, types::internals::pubdata::PubdataInput, }; -use crate::{ - vm_latest::StorageOracle, - vm_latest::{constants::BOOTLOADER_HEAP_PAGE, TracerExecutionStatus}, -}; +use crate::{vm_latest::constants::BOOTLOADER_HEAP_PAGE, vm_latest::StorageOracle}; +use crate::interface::dyn_tracers::vm_1_4_0::DynTracer; +use crate::interface::tracer::{TracerExecutionStatus, TracerExecutionStopReason}; use crate::interface::types::inputs::L1BatchEnv; -use crate::vm_latest::tracers::{ - traits::{DynTracer, TracerExecutionStopReason, VmTracer}, - utils::VmHook, -}; +use crate::vm_latest::tracers::{traits::VmTracer, utils::VmHook}; use crate::vm_latest::types::internals::ZkSyncVmState; use crate::vm_latest::utils::logs::collect_events_and_l1_system_logs_after_timestamp; use crate::{ @@ -164,7 +160,7 @@ impl PubdataTracer { } } -impl DynTracer for PubdataTracer { +impl DynTracer> for PubdataTracer { fn before_execution( &mut self, state: VmLocalStateData<'_>, diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs index e22108dd28cd..321fdae852f0 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs @@ -1,6 +1,6 @@ use vise::{Buckets, EncodeLabelSet, EncodeLabelValue, Family, Histogram, Metrics}; -use crate::interface::traits::tracers::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::traits::tracers::dyn_tracers::vm_1_4_0::DynTracer; use crate::interface::types::tracer::TracerExecutionStatus; use crate::interface::{L1BatchEnv, Refunds}; use zk_evm_1_4_0::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs index 60611801371c..19c878dfc6ac 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs @@ -6,7 +6,7 @@ use zk_evm_1_4_0::{ use zksync_state::{StoragePtr, WriteStorage}; use crate::interface::{ - tracer::VmExecutionStopReason, traits::tracers::dyn_tracers::vm_1_3_3::DynTracer, + tracer::VmExecutionStopReason, traits::tracers::dyn_tracers::vm_1_4_0::DynTracer, types::tracer::TracerExecutionStopReason, ExecutionResult, Halt, TxRevertReason, VmExecutionMode, VmRevertReason, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs b/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs index dd8cf1d48662..a3970541bac2 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs @@ -1,8 +1,6 @@ -use crate::interface::Halt; -use zk_evm_1_4_0::tracing::{ - AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, -}; -use zksync_state::{StoragePtr, WriteStorage}; +use crate::interface::dyn_tracers::vm_1_4_0::DynTracer; +use crate::interface::tracer::{TracerExecutionStatus, VmExecutionStopReason}; +use zksync_state::WriteStorage; use crate::vm_latest::bootloader_state::BootloaderState; use crate::vm_latest::old_vm::history_recorder::HistoryMode; diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index c292465e94f9..e9787b6ac460 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -23,7 +23,7 @@ use crate::vm_latest::types::internals::{new_vm_state, VmSnapshot, ZkSyncVmState pub struct Vm { pub(crate) bootloader_state: BootloaderState, // Current state and oracles of virtual machine - pub(crate) state: ZkSyncVmState, + pub(crate) state: ZkSyncVmState, pub(crate) storage: StoragePtr, pub(crate) system_env: SystemEnv, pub(crate) batch_env: L1BatchEnv, @@ -34,7 +34,7 @@ pub struct Vm { /// Public interface for VM impl VmInterface for Vm { - type TracerDispatcher = TracerDispatcher; + type TracerDispatcher = TracerDispatcher; fn new(batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr) -> Self { let (state, bootloader_state) = new_vm_state(storage.clone(), &system_env, &batch_env); 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 2092c03e06e3..4b7e529fc5b0 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 @@ -1,11 +1,13 @@ use itertools::Itertools; +use crate::interface::VmInterface; +use crate::HistoryMode; use zksync_state::{StoragePtr, WriteStorage}; use zksync_types::U256; use zksync_utils::bytecode::{compress_bytecode, hash_bytecode, CompressedBytecodeInfo}; use zksync_utils::bytes_to_be_words; -use crate::vm_refunds_enhancement::{HistoryMode, Vm}; +use crate::vm_refunds_enhancement::Vm; impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. 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 2691b5395d7f..9e55180d66f6 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 @@ -1,22 +1,20 @@ +use crate::HistoryMode; use zk_evm_1_3_3::aux_structures::Timestamp; use zksync_state::WriteStorage; +use crate::interface::tracer::{TracerExecutionStatus, VmExecutionStopReason}; use crate::interface::{VmExecutionMode, VmExecutionResultAndLogs}; -use crate::vm_refunds_enhancement::old_vm::{ - history_recorder::HistoryMode, - utils::{vm_may_have_ended_inner, VmExecutionResult}, -}; +use crate::vm_refunds_enhancement::old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}; +use crate::vm_refunds_enhancement::tracers::dispatcher::TracerDispatcher; use crate::vm_refunds_enhancement::tracers::{ - traits::{TracerExecutionStatus, VmTracer}, - DefaultExecutionTracer, RefundsTracer, + traits::VmTracer, DefaultExecutionTracer, RefundsTracer, }; use crate::vm_refunds_enhancement::vm::Vm; -use crate::vm_refunds_enhancement::VmExecutionStopReason; impl Vm { pub(crate) fn inspect_inner( &mut self, - tracers: Vec>>, + dispatcher: TracerDispatcher, execution_mode: VmExecutionMode, ) -> VmExecutionResultAndLogs { let mut enable_refund_tracer = false; @@ -26,7 +24,7 @@ impl Vm { enable_refund_tracer = true; } let (_, result) = - self.inspect_and_collect_results(tracers, execution_mode, enable_refund_tracer); + self.inspect_and_collect_results(dispatcher, execution_mode, enable_refund_tracer); result } @@ -34,19 +32,20 @@ impl Vm { /// Collect the result from the default tracers. fn inspect_and_collect_results( &mut self, - tracers: Vec>>, + dispatcher: TracerDispatcher, execution_mode: VmExecutionMode, with_refund_tracer: bool, ) -> (VmExecutionStopReason, VmExecutionResultAndLogs) { let refund_tracers = with_refund_tracer.then_some(RefundsTracer::new(self.batch_env.clone())); - let mut tx_tracer: DefaultExecutionTracer = DefaultExecutionTracer::new( - self.system_env.default_validation_computational_gas_limit, - execution_mode, - tracers, - self.storage.clone(), - refund_tracers, - ); + let mut tx_tracer: DefaultExecutionTracer = + DefaultExecutionTracer::new( + self.system_env.default_validation_computational_gas_limit, + execution_mode, + dispatcher, + self.storage.clone(), + refund_tracers, + ); let timestamp_initial = Timestamp(self.state.local_state.timestamp); let cycles_initial = self.state.local_state.monotonic_cycle_counter; @@ -91,7 +90,7 @@ impl Vm { /// Execute vm with given tracers until the stop reason is reached. fn execute_with_default_tracer( &mut self, - tracer: &mut DefaultExecutionTracer, + tracer: &mut DefaultExecutionTracer, ) -> VmExecutionStopReason { tracer.initialize_tracer(&mut self.state); let result = loop { 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 7f85ba7dda3e..cce9bfad6999 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,6 +1,6 @@ +use crate::HistoryMode; use zksync_state::WriteStorage; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; use crate::vm_refunds_enhancement::tracers::DefaultExecutionTracer; use crate::vm_refunds_enhancement::vm::Vm; @@ -19,7 +19,7 @@ impl Vm { pub(crate) fn calculate_computational_gas_used( &self, - tracer: &DefaultExecutionTracer, + tracer: &DefaultExecutionTracer, gas_remaining_before: u32, spent_pubdata_counter_before: u32, ) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/logs.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/logs.rs index 327a054afc09..b8e8652f3012 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/logs.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/logs.rs @@ -1,12 +1,12 @@ use zk_evm_1_3_3::aux_structures::Timestamp; use zksync_state::WriteStorage; +use crate::HistoryMode; use zksync_types::l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}; use zksync_types::VmEvent; use crate::interface::types::outputs::VmExecutionLogs; use crate::vm_refunds_enhancement::old_vm::events::merge_events; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; use crate::vm_refunds_enhancement::old_vm::utils::precompile_calls_count_after_timestamp; use crate::vm_refunds_enhancement::vm::Vm; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/snapshots.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/snapshots.rs index d7cf0fbb85e8..972d50e5d76e 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/snapshots.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/snapshots.rs @@ -2,13 +2,12 @@ use vise::{Buckets, EncodeLabelSet, EncodeLabelValue, Family, Histogram, Metrics use std::time::Duration; +use crate::vm_latest::HistoryEnabled; use zk_evm_1_3_3::aux_structures::Timestamp; use zksync_state::WriteStorage; use crate::vm_refunds_enhancement::{ - old_vm::{history_recorder::HistoryEnabled, oracles::OracleWithHistory}, - types::internals::VmSnapshot, - vm::Vm, + old_vm::oracles::OracleWithHistory, types::internals::VmSnapshot, vm::Vm, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EncodeLabelSet, EncodeLabelValue)] diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/statistics.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/statistics.rs index a113a09be701..ce65cab2d496 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/statistics.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/statistics.rs @@ -1,10 +1,10 @@ use zk_evm_1_3_3::aux_structures::Timestamp; use zksync_state::WriteStorage; +use crate::HistoryMode; use zksync_types::U256; use crate::interface::{VmExecutionStatistics, VmMemoryMetrics}; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; use crate::vm_refunds_enhancement::tracers::DefaultExecutionTracer; use crate::vm_refunds_enhancement::vm::Vm; @@ -18,7 +18,7 @@ impl Vm { &self, timestamp_initial: Timestamp, cycles_initial: u32, - tracer: &DefaultExecutionTracer, + tracer: &DefaultExecutionTracer, gas_remaining_before: u32, gas_remaining_after: u32, spent_pubdata_counter_before: u32, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/tx.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/tx.rs index 2d748040b476..d6fd4858870d 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/tx.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/tx.rs @@ -7,9 +7,9 @@ use zksync_state::WriteStorage; use zksync_types::l1::is_l1_tx_type; use zksync_types::Transaction; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; use crate::vm_refunds_enhancement::types::internals::TransactionData; use crate::vm_refunds_enhancement::vm::Vm; +use crate::HistoryMode; impl Vm { pub(crate) fn push_raw_transaction( diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/mod.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/mod.rs index 8cfe50ffbf33..146ea5e659f1 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/mod.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/mod.rs @@ -5,12 +5,7 @@ pub use old_vm::{ pub use oracles::storage::StorageOracle; -pub use tracers::{ - call::CallTracer, - traits::{BoxedTracer, DynTracer, TracerExecutionStatus, TracerExecutionStopReason, VmTracer}, - utils::VmExecutionStopReason, - StorageInvocations, ValidationError, ValidationTracer, ValidationTracerParams, -}; +pub use tracers::traits::{TracerPointer, VmTracer}; pub use utils::transaction_encoding::TransactionVmExt; @@ -23,7 +18,7 @@ mod bootloader_state; mod implementation; mod old_vm; mod oracles; -mod tracers; +pub(crate) mod tracers; mod types; mod vm; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/default_tracers.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/default_tracers.rs index f06a42af286b..51fbf06d855d 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/default_tracers.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/default_tracers.rs @@ -1,6 +1,11 @@ use std::fmt::{Debug, Formatter}; +use crate::interface::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::tracer::{ + TracerExecutionStatus, TracerExecutionStopReason, VmExecutionStopReason, +}; use crate::interface::{Halt, VmExecutionMode}; +use crate::vm_refunds_enhancement::VmTracer; use zk_evm_1_3_3::{ tracing::{ AfterDecodingData, AfterExecutionData, BeforeExecutionData, Tracer, VmLocalStateData, @@ -17,19 +22,16 @@ use crate::vm_refunds_enhancement::bootloader_state::BootloaderState; use crate::vm_refunds_enhancement::constants::BOOTLOADER_HEAP_PAGE; use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; use crate::vm_refunds_enhancement::old_vm::memory::SimpleMemory; -use crate::vm_refunds_enhancement::tracers::traits::{ - DynTracer, TracerExecutionStatus, TracerExecutionStopReason, VmTracer, -}; +use crate::vm_refunds_enhancement::tracers::dispatcher::TracerDispatcher; use crate::vm_refunds_enhancement::tracers::utils::{ computational_gas_price, gas_spent_on_bytecodes_and_long_messages_this_opcode, print_debug_if_needed, VmHook, }; use crate::vm_refunds_enhancement::tracers::{RefundsTracer, ResultTracer}; use crate::vm_refunds_enhancement::types::internals::ZkSyncVmState; -use crate::vm_refunds_enhancement::VmExecutionStopReason; /// Default tracer for the VM. It manages the other tracers execution and stop the vm when needed. -pub(crate) struct DefaultExecutionTracer { +pub(crate) struct DefaultExecutionTracer { tx_has_been_processed: bool, execution_mode: VmExecutionMode, @@ -45,18 +47,18 @@ pub(crate) struct DefaultExecutionTracer { // ensures static dispatch, enhancing performance by avoiding dynamic dispatch overhead. // Additionally, being an internal tracer, it saves the results directly to VmResultAndLogs. pub(crate) refund_tracer: Option, - pub(crate) custom_tracers: Vec>>, + pub(crate) dispatcher: TracerDispatcher, ret_from_the_bootloader: Option, storage: StoragePtr, } -impl Debug for DefaultExecutionTracer { +impl Debug for DefaultExecutionTracer { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("DefaultExecutionTracer").finish() } } -impl Tracer for DefaultExecutionTracer { +impl Tracer for DefaultExecutionTracer { const CALL_BEFORE_DECODING: bool = false; const CALL_AFTER_DECODING: bool = true; const CALL_BEFORE_EXECUTION: bool = true; @@ -76,7 +78,7 @@ impl Tracer for DefaultExecutionTracer { data: AfterDecodingData, memory: &Self::SupportedMemory, ) { - >::after_decoding( + >>::after_decoding( &mut self.result_tracer, state, data, @@ -84,12 +86,15 @@ impl Tracer for DefaultExecutionTracer { ); if let Some(refund_tracer) = &mut self.refund_tracer { - >::after_decoding(refund_tracer, state, data, memory); + >>::after_decoding( + refund_tracer, + state, + data, + memory, + ); } - for tracer in self.custom_tracers.iter_mut() { - tracer.after_decoding(state, data, memory) - } + self.dispatcher.after_decoding(state, data, memory); } fn before_execution( @@ -123,9 +128,8 @@ impl Tracer for DefaultExecutionTracer { if let Some(refund_tracer) = &mut self.refund_tracer { refund_tracer.before_execution(state, data, memory, self.storage.clone()); } - for tracer in self.custom_tracers.iter_mut() { - tracer.before_execution(state, data, memory, self.storage.clone()); - } + self.dispatcher + .before_execution(state, data, memory, self.storage.clone()); } fn after_execution( @@ -153,9 +157,8 @@ impl Tracer for DefaultExecutionTracer { if let Some(refund_tracer) = &mut self.refund_tracer { refund_tracer.after_execution(state, data, memory, self.storage.clone()) } - for tracer in self.custom_tracers.iter_mut() { - tracer.after_execution(state, data, memory, self.storage.clone()); - } + self.dispatcher + .after_execution(state, data, memory, self.storage.clone()); } } @@ -163,7 +166,7 @@ impl DefaultExecutionTracer { pub(crate) fn new( computational_gas_limit: u32, execution_mode: VmExecutionMode, - custom_tracers: Vec>>, + dispatcher: TracerDispatcher, storage: StoragePtr, refund_tracer: Option, ) -> Self { @@ -177,7 +180,7 @@ impl DefaultExecutionTracer { final_batch_info_requested: false, result_tracer: ResultTracer::new(execution_mode), refund_tracer, - custom_tracers, + dispatcher, ret_from_the_bootloader: None, storage, } @@ -230,7 +233,10 @@ impl DefaultExecutionTracer { } } -impl DynTracer for DefaultExecutionTracer {} +impl DynTracer> + for DefaultExecutionTracer +{ +} impl VmTracer for DefaultExecutionTracer { fn initialize_tracer(&mut self, state: &mut ZkSyncVmState) { @@ -238,9 +244,7 @@ impl VmTracer for DefaultExecutionTracer< if let Some(refund_tracer) = &mut self.refund_tracer { refund_tracer.initialize_tracer(state); } - for processor in self.custom_tracers.iter_mut() { - processor.initialize_tracer(state); - } + self.dispatcher.initialize_tracer(state); } fn finish_cycle( @@ -258,11 +262,10 @@ impl VmTracer for DefaultExecutionTracer< .finish_cycle(state, bootloader_state) .stricter(&result); } - for processor in self.custom_tracers.iter_mut() { - result = processor - .finish_cycle(state, bootloader_state) - .stricter(&result); - } + result = self + .dispatcher + .finish_cycle(state, bootloader_state) + .stricter(&result); result.stricter(&self.should_stop_execution()) } @@ -278,9 +281,8 @@ impl VmTracer for DefaultExecutionTracer< if let Some(refund_tracer) = &mut self.refund_tracer { refund_tracer.after_vm_execution(state, bootloader_state, stop_reason.clone()); } - for processor in self.custom_tracers.iter_mut() { - processor.after_vm_execution(state, bootloader_state, stop_reason.clone()); - } + self.dispatcher + .after_vm_execution(state, bootloader_state, stop_reason.clone()); } } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/dispatcher.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/dispatcher.rs new file mode 100644 index 000000000000..ec249eaa4847 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/dispatcher.rs @@ -0,0 +1,115 @@ +use crate::interface::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::tracer::{TracerExecutionStatus, VmExecutionStopReason}; +use crate::vm_refunds_enhancement::{ + BootloaderState, HistoryMode, SimpleMemory, TracerPointer, VmTracer, ZkSyncVmState, +}; +use zk_evm_1_3_3::tracing::{ + AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, +}; +use zksync_state::{StoragePtr, WriteStorage}; + +/// Tracer dispatcher is a tracer that can dispatch calls to multiple tracers. +pub struct TracerDispatcher { + tracers: Vec>, +} + +impl From> for TracerDispatcher { + fn from(value: TracerPointer) -> Self { + Self { + tracers: vec![value], + } + } +} + +impl From>> for TracerDispatcher { + fn from(value: Vec>) -> Self { + Self { tracers: value } + } +} + +impl Default for TracerDispatcher { + fn default() -> Self { + Self { tracers: vec![] } + } +} + +impl DynTracer> for TracerDispatcher { + #[inline(always)] + fn before_decoding(&mut self, _state: VmLocalStateData<'_>, _memory: &SimpleMemory) { + for tracer in self.tracers.iter_mut() { + tracer.before_decoding(_state, _memory); + } + } + + #[inline(always)] + fn after_decoding( + &mut self, + _state: VmLocalStateData<'_>, + _data: AfterDecodingData, + _memory: &SimpleMemory, + ) { + for tracer in self.tracers.iter_mut() { + tracer.after_decoding(_state, _data, _memory); + } + } + + #[inline(always)] + fn before_execution( + &mut self, + _state: VmLocalStateData<'_>, + _data: BeforeExecutionData, + _memory: &SimpleMemory, + _storage: StoragePtr, + ) { + for tracer in self.tracers.iter_mut() { + tracer.before_execution(_state, _data, _memory, _storage.clone()); + } + } + + #[inline(always)] + fn after_execution( + &mut self, + _state: VmLocalStateData<'_>, + _data: AfterExecutionData, + _memory: &SimpleMemory, + _storage: StoragePtr, + ) { + for tracer in self.tracers.iter_mut() { + tracer.after_execution(_state, _data, _memory, _storage.clone()); + } + } +} + +impl VmTracer for TracerDispatcher { + fn initialize_tracer(&mut self, _state: &mut ZkSyncVmState) { + for tracer in self.tracers.iter_mut() { + tracer.initialize_tracer(_state); + } + } + + /// Run after each vm execution cycle + #[inline(always)] + fn finish_cycle( + &mut self, + _state: &mut ZkSyncVmState, + _bootloader_state: &mut BootloaderState, + ) -> TracerExecutionStatus { + let mut result = TracerExecutionStatus::Continue; + for tracer in self.tracers.iter_mut() { + result = result.stricter(&tracer.finish_cycle(_state, _bootloader_state)); + } + result + } + + /// Run after the vm execution + fn after_vm_execution( + &mut self, + _state: &mut ZkSyncVmState, + _bootloader_state: &BootloaderState, + _stop_reason: VmExecutionStopReason, + ) { + for tracer in self.tracers.iter_mut() { + tracer.after_vm_execution(_state, _bootloader_state, _stop_reason.clone()); + } + } +} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/mod.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/mod.rs index 11fefedc85a5..af17b77237ec 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/mod.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/mod.rs @@ -1,15 +1,10 @@ pub(crate) use default_tracers::DefaultExecutionTracer; pub(crate) use refunds::RefundsTracer; pub(crate) use result_tracer::ResultTracer; -pub use storage_invocations::StorageInvocations; -pub use validation::{ValidationError, ValidationTracer, ValidationTracerParams}; pub(crate) mod default_tracers; +pub mod dispatcher; pub(crate) mod refunds; pub(crate) mod result_tracer; - -pub(crate) mod call; -pub(crate) mod storage_invocations; pub(crate) mod traits; pub(crate) mod utils; -pub(crate) mod validation; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs index b451e7209676..5256561b5eb5 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs @@ -1,6 +1,5 @@ use vise::{Buckets, EncodeLabelSet, EncodeLabelValue, Family, Histogram, Metrics}; -use crate::interface::{L1BatchEnv, Refunds}; use zk_evm_1_3_3::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, @@ -16,22 +15,25 @@ use zksync_types::{ use zksync_utils::bytecode::bytecode_len_in_bytes; use zksync_utils::{ceil_div_u256, u256_to_h256}; +use crate::interface::{ + dyn_tracers::vm_1_3_3::DynTracer, tracer::TracerExecutionStatus, L1BatchEnv, Refunds, +}; use crate::vm_refunds_enhancement::constants::{ BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET, }; -use crate::vm_refunds_enhancement::old_vm::{ - events::merge_events, history_recorder::HistoryMode, memory::SimpleMemory, - utils::eth_price_per_pubdata_byte, -}; -use crate::vm_refunds_enhancement::bootloader_state::BootloaderState; -use crate::vm_refunds_enhancement::tracers::utils::gas_spent_on_bytecodes_and_long_messages_this_opcode; -use crate::vm_refunds_enhancement::tracers::{ - traits::{DynTracer, VmTracer}, - utils::{get_vm_hook_params, VmHook}, +use crate::vm_refunds_enhancement::{ + bootloader_state::BootloaderState, + old_vm::{ + events::merge_events, history_recorder::HistoryMode, memory::SimpleMemory, + utils::eth_price_per_pubdata_byte, + }, + tracers::{ + traits::VmTracer, + utils::{gas_spent_on_bytecodes_and_long_messages_this_opcode, get_vm_hook_params, VmHook}, + }, + types::internals::ZkSyncVmState, }; -use crate::vm_refunds_enhancement::types::internals::ZkSyncVmState; -use crate::vm_refunds_enhancement::TracerExecutionStatus; /// Tracer responsible for collecting information about refunds. #[derive(Debug, Clone)] @@ -150,7 +152,7 @@ impl RefundsTracer { } } -impl DynTracer for RefundsTracer { +impl DynTracer> for RefundsTracer { fn before_execution( &mut self, state: VmLocalStateData<'_>, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/result_tracer.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/result_tracer.rs index da70d06418a1..c0a8e5d6cc0d 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/result_tracer.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/result_tracer.rs @@ -5,6 +5,8 @@ use zk_evm_1_3_3::{ }; use zksync_state::{StoragePtr, WriteStorage}; +use crate::interface::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::tracer::{TracerExecutionStopReason, VmExecutionStopReason}; use crate::interface::{ExecutionResult, Halt, TxRevertReason, VmExecutionMode, VmRevertReason}; use zksync_types::U256; @@ -14,15 +16,11 @@ use crate::vm_refunds_enhancement::old_vm::{ memory::SimpleMemory, utils::{vm_may_have_ended_inner, VmExecutionResult}, }; -use crate::vm_refunds_enhancement::tracers::{ - traits::{DynTracer, VmTracer}, - utils::{get_vm_hook_params, read_pointer, VmHook}, -}; +use crate::vm_refunds_enhancement::tracers::utils::{get_vm_hook_params, read_pointer, VmHook}; use crate::vm_refunds_enhancement::constants::{BOOTLOADER_HEAP_PAGE, RESULT_SUCCESS_FIRST_SLOT}; -use crate::vm_refunds_enhancement::tracers::traits::TracerExecutionStopReason; use crate::vm_refunds_enhancement::types::internals::ZkSyncVmState; -use crate::vm_refunds_enhancement::VmExecutionStopReason; +use crate::vm_refunds_enhancement::VmTracer; #[derive(Debug, Clone)] enum Result { @@ -56,7 +54,7 @@ fn current_frame_is_bootloader(local_state: &VmLocalState) -> bool { local_state.callstack.inner.len() == 1 } -impl DynTracer for ResultTracer { +impl DynTracer> for ResultTracer { fn after_decoding( &mut self, state: VmLocalStateData<'_>, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/storage_invocations.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/storage_invocations.rs deleted file mode 100644 index 95d496c6a862..000000000000 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/storage_invocations.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::interface::Halt; -use crate::vm_refunds_enhancement::bootloader_state::BootloaderState; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; -use crate::vm_refunds_enhancement::tracers::traits::{ - DynTracer, TracerExecutionStatus, TracerExecutionStopReason, VmTracer, -}; -use crate::vm_refunds_enhancement::types::internals::ZkSyncVmState; -use zksync_state::WriteStorage; - -#[derive(Debug, Default, Clone)] -pub struct StorageInvocations { - pub limit: usize, -} - -impl StorageInvocations { - pub fn new(limit: usize) -> Self { - Self { limit } - } -} - -/// Tracer responsible for calculating the number of storage invocations and -/// stopping the VM execution if the limit is reached. -impl DynTracer for StorageInvocations {} - -impl VmTracer for StorageInvocations { - fn finish_cycle( - &mut self, - state: &mut ZkSyncVmState, - _bootloader_state: &mut BootloaderState, - ) -> TracerExecutionStatus { - let current = state - .storage - .storage - .get_ptr() - .borrow() - .missed_storage_invocations(); - - if current >= self.limit { - return TracerExecutionStatus::Stop(TracerExecutionStopReason::Abort( - Halt::TracerCustom("Storage invocations limit reached".to_string()), - )); - } - TracerExecutionStatus::Continue - } -} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/traits.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/traits.rs index af79da8a20cf..13b295b9fe9b 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/traits.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/traits.rs @@ -1,17 +1,16 @@ -use crate::interface::Halt; -use zk_evm_1_3_3::tracing::{ - AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, -}; -use zksync_state::{StoragePtr, WriteStorage}; +use crate::interface::dyn_tracers::vm_1_3_3::DynTracer; +use crate::interface::tracer::{TracerExecutionStatus, VmExecutionStopReason}; +use zksync_state::WriteStorage; use crate::vm_refunds_enhancement::bootloader_state::BootloaderState; use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; use crate::vm_refunds_enhancement::old_vm::memory::SimpleMemory; use crate::vm_refunds_enhancement::types::internals::ZkSyncVmState; -use crate::vm_refunds_enhancement::VmExecutionStopReason; + +pub type TracerPointer = Box>; /// Run tracer for collecting data during the vm execution cycles -pub trait VmTracer: DynTracer { +pub trait VmTracer: DynTracer> { /// Initialize the tracer before the vm execution fn initialize_tracer(&mut self, _state: &mut ZkSyncVmState) {} /// Run after each vm execution cycle @@ -32,72 +31,12 @@ pub trait VmTracer: DynTracer { } } -/// Version of zk_evm_1_3_3::Tracer suitable for dynamic dispatch. -pub trait DynTracer { - fn before_decoding(&mut self, _state: VmLocalStateData<'_>, _memory: &SimpleMemory) {} - fn after_decoding( - &mut self, - _state: VmLocalStateData<'_>, - _data: AfterDecodingData, - _memory: &SimpleMemory, - ) { - } - fn before_execution( - &mut self, - _state: VmLocalStateData<'_>, - _data: BeforeExecutionData, - _memory: &SimpleMemory, - _storage: StoragePtr, - ) { - } - fn after_execution( - &mut self, - _state: VmLocalStateData<'_>, - _data: AfterExecutionData, - _memory: &SimpleMemory, - _storage: StoragePtr, - ) { - } +pub trait ToTracerPointer { + fn into_tracer_pointer(self) -> TracerPointer; } -pub trait BoxedTracer { - fn into_boxed(self) -> Box>; -} - -impl + 'static> BoxedTracer for T { - fn into_boxed(self) -> Box> { +impl + 'static> ToTracerPointer for T { + fn into_tracer_pointer(self) -> TracerPointer { Box::new(self) } } - -#[derive(Debug, Clone, PartialEq)] -pub enum TracerExecutionStopReason { - Finish, - Abort(Halt), -} - -#[derive(Debug, Clone, PartialEq)] -pub enum TracerExecutionStatus { - Continue, - Stop(TracerExecutionStopReason), -} - -impl TracerExecutionStatus { - /// Chose the stricter ExecutionStatus - /// If both statuses are Continue, then the result is Continue - /// If one of the statuses is Abort, then the result is Abort - /// If one of the statuses is Finish, then the result is Finish - pub fn stricter(&self, other: &Self) -> Self { - match (self, other) { - (Self::Continue, Self::Continue) => Self::Continue, - (Self::Stop(TracerExecutionStopReason::Abort(reason)), _) - | (_, Self::Stop(TracerExecutionStopReason::Abort(reason))) => { - Self::Stop(TracerExecutionStopReason::Abort(reason.clone())) - } - (Self::Stop(TracerExecutionStopReason::Finish), _) - | (_, Self::Stop(TracerExecutionStopReason::Finish)) => { - Self::Stop(TracerExecutionStopReason::Finish) - } - } - } -} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs index d561a522733b..654c7300e4ad 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs @@ -1,8 +1,9 @@ -use zk_evm_1_3_3::aux_structures::MemoryPage; -use zk_evm_1_3_3::zkevm_opcode_defs::{FarCallABI, FarCallForwardPageType}; use zk_evm_1_3_3::{ + aux_structures::MemoryPage, tracing::{BeforeExecutionData, VmLocalStateData}, - zkevm_opcode_defs::{FatPointer, LogOpcode, Opcode, UMAOpcode}, + zkevm_opcode_defs::{ + FarCallABI, FarCallForwardPageType, FatPointer, LogOpcode, Opcode, UMAOpcode, + }, }; use zksync_system_constants::{ @@ -15,10 +16,11 @@ use zksync_utils::u256_to_h256; use crate::vm_refunds_enhancement::constants::{ BOOTLOADER_HEAP_PAGE, VM_HOOK_PARAMS_COUNT, VM_HOOK_PARAMS_START_POSITION, VM_HOOK_POSITION, }; -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; -use crate::vm_refunds_enhancement::old_vm::memory::SimpleMemory; -use crate::vm_refunds_enhancement::old_vm::utils::{aux_heap_page_from_base, heap_page_from_base}; -use crate::vm_refunds_enhancement::tracers::traits::TracerExecutionStopReason; +use crate::vm_refunds_enhancement::old_vm::{ + history_recorder::HistoryMode, + memory::SimpleMemory, + utils::{aux_heap_page_from_base, heap_page_from_base}, +}; #[derive(Clone, Debug, Copy)] pub(crate) enum VmHook { @@ -217,9 +219,3 @@ pub(crate) fn get_vm_hook_params(memory: &SimpleMemory) -> Ve VM_HOOK_PARAMS_START_POSITION..VM_HOOK_PARAMS_START_POSITION + VM_HOOK_PARAMS_COUNT, ) } - -#[derive(Debug, Clone, PartialEq)] -pub enum VmExecutionStopReason { - VmFinished, - TracerRequestedStop(TracerExecutionStopReason), -} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/error.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/error.rs deleted file mode 100644 index 4b9741ddaa5f..000000000000 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/error.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::interface::Halt; -use std::fmt::Display; -use zksync_types::vm_trace::ViolatedValidationRule; - -#[derive(Debug, Clone)] -pub enum ValidationError { - FailedTx(Halt), - ViolatedRule(ViolatedValidationRule), -} - -impl Display for ValidationError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::FailedTx(revert_reason) => { - write!(f, "Validation revert: {}", revert_reason) - } - Self::ViolatedRule(rule) => { - write!(f, "Violated validation rules: {}", rule) - } - } - } -} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/mod.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/mod.rs deleted file mode 100644 index 187d61ba0edc..000000000000 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/mod.rs +++ /dev/null @@ -1,409 +0,0 @@ -mod error; -mod params; -mod types; - -use std::sync::Arc; -use std::{collections::HashSet, marker::PhantomData}; - -use once_cell::sync::OnceCell; -use zk_evm_1_3_3::{ - tracing::{BeforeExecutionData, VmLocalStateData}, - zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, -}; - -use zksync_state::{StoragePtr, WriteStorage}; -use zksync_system_constants::{ - ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, CONTRACT_DEPLOYER_ADDRESS, - KECCAK256_PRECOMPILE_ADDRESS, L2_ETH_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, - SYSTEM_CONTEXT_ADDRESS, -}; - -use zksync_types::{ - get_code_key, vm_trace::ViolatedValidationRule, web3::signing::keccak256, AccountTreeId, - Address, StorageKey, H256, U256, -}; -use zksync_utils::{ - be_bytes_to_safe_address, h256_to_account_address, u256_to_account_address, u256_to_h256, -}; - -use crate::vm_refunds_enhancement::old_vm::history_recorder::HistoryMode; -use crate::vm_refunds_enhancement::old_vm::memory::SimpleMemory; -use crate::vm_refunds_enhancement::tracers::traits::{ - DynTracer, TracerExecutionStatus, TracerExecutionStopReason, VmTracer, -}; -use crate::vm_refunds_enhancement::tracers::utils::{ - computational_gas_price, get_calldata_page_via_abi, print_debug_if_needed, VmHook, -}; - -pub use error::ValidationError; -pub use params::ValidationTracerParams; - -use crate::interface::Halt; -use types::NewTrustedValidationItems; -use types::ValidationTracerMode; - -use crate::vm_refunds_enhancement::{BootloaderState, ZkSyncVmState}; - -/// Tracer that is used to ensure that the validation adheres to all the rules -/// to prevent DDoS attacks on the server. -#[derive(Debug, Clone)] -pub struct ValidationTracer { - validation_mode: ValidationTracerMode, - auxilary_allowed_slots: HashSet, - - user_address: Address, - #[allow(dead_code)] - paymaster_address: Address, - should_stop_execution: bool, - trusted_slots: HashSet<(Address, U256)>, - trusted_addresses: HashSet
, - trusted_address_slots: HashSet<(Address, U256)>, - computational_gas_used: u32, - computational_gas_limit: u32, - pub result: Arc>, - _marker: PhantomData H>, -} - -type ValidationRoundResult = Result; - -impl ValidationTracer { - pub fn new(params: ValidationTracerParams) -> (Self, Arc>) { - let result = Arc::new(OnceCell::new()); - ( - Self { - validation_mode: ValidationTracerMode::NoValidation, - auxilary_allowed_slots: Default::default(), - - should_stop_execution: false, - user_address: params.user_address, - paymaster_address: params.paymaster_address, - trusted_slots: params.trusted_slots, - trusted_addresses: params.trusted_addresses, - trusted_address_slots: params.trusted_address_slots, - computational_gas_used: 0, - computational_gas_limit: params.computational_gas_limit, - result: result.clone(), - _marker: Default::default(), - }, - result, - ) - } - - fn process_validation_round_result(&mut self, result: ValidationRoundResult) { - match result { - Ok(NewTrustedValidationItems { - new_allowed_slots, - new_trusted_addresses, - }) => { - self.auxilary_allowed_slots.extend(new_allowed_slots); - self.trusted_addresses.extend(new_trusted_addresses); - } - Err(err) => { - if self.result.get().is_some() { - tracing::trace!("Validation error is already set, skipping"); - return; - } - self.result.set(err).expect("Result should be empty"); - } - } - } - - // Checks whether such storage access is acceptable. - fn is_allowed_storage_read( - &self, - storage: StoragePtr, - address: Address, - key: U256, - msg_sender: Address, - ) -> bool { - // If there are no restrictions, all storage reads are valid. - // We also don't support the paymaster validation for now. - if matches!( - self.validation_mode, - ValidationTracerMode::NoValidation | ValidationTracerMode::PaymasterTxValidation - ) { - return true; - } - - // The pair of MSG_VALUE_SIMULATOR_ADDRESS & L2_ETH_TOKEN_ADDRESS simulates the behavior of transfering ETH - // that is safe for the DDoS protection rules. - if valid_eth_token_call(address, msg_sender) { - return true; - } - - if self.trusted_slots.contains(&(address, key)) - || self.trusted_addresses.contains(&address) - || self.trusted_address_slots.contains(&(address, key)) - { - return true; - } - - if touches_allowed_context(address, key) { - return true; - } - - // The user is allowed to touch its own slots or slots semantically related to him. - let valid_users_slot = address == self.user_address - || u256_to_account_address(&key) == self.user_address - || self.auxilary_allowed_slots.contains(&u256_to_h256(key)); - if valid_users_slot { - return true; - } - - if is_constant_code_hash(address, key, storage) { - return true; - } - - false - } - - // Used to remember user-related fields (its balance/allowance/etc). - // Note that it assumes that the length of the calldata is 64 bytes. - fn slot_to_add_from_keccak_call( - &self, - calldata: &[u8], - validated_address: Address, - ) -> Option { - assert_eq!(calldata.len(), 64); - - let (potential_address_bytes, potential_position_bytes) = calldata.split_at(32); - let potential_address = be_bytes_to_safe_address(potential_address_bytes); - - // If the validation_address is equal to the potential_address, - // then it is a request that could be used for mapping of kind mapping(address => ...). - // - // If the potential_position_bytes were already allowed before, then this keccak might be used - // for ERC-20 allowance or any other of mapping(address => mapping(...)) - if potential_address == Some(validated_address) - || self - .auxilary_allowed_slots - .contains(&H256::from_slice(potential_position_bytes)) - { - // This is request that could be used for mapping of kind mapping(address => ...) - - // We could theoretically wait for the slot number to be returned by the - // keccak256 precompile itself, but this would complicate the code even further - // so let's calculate it here. - let slot = keccak256(calldata); - - // Adding this slot to the allowed ones - Some(H256(slot)) - } else { - None - } - } - - pub fn params(&self) -> ValidationTracerParams { - ValidationTracerParams { - user_address: self.user_address, - paymaster_address: self.paymaster_address, - trusted_slots: self.trusted_slots.clone(), - trusted_addresses: self.trusted_addresses.clone(), - trusted_address_slots: self.trusted_address_slots.clone(), - computational_gas_limit: self.computational_gas_limit, - } - } - - fn check_user_restrictions( - &mut self, - state: VmLocalStateData<'_>, - data: BeforeExecutionData, - memory: &SimpleMemory, - storage: StoragePtr, - ) -> ValidationRoundResult { - if self.computational_gas_used > self.computational_gas_limit { - return Err(ViolatedValidationRule::TookTooManyComputationalGas( - self.computational_gas_limit, - )); - } - - let opcode_variant = data.opcode.variant; - match opcode_variant.opcode { - Opcode::FarCall(_) => { - let packed_abi = data.src0_value.value; - let call_destination_value = data.src1_value.value; - - let called_address = u256_to_account_address(&call_destination_value); - let far_call_abi = FarCallABI::from_u256(packed_abi); - - if called_address == KECCAK256_PRECOMPILE_ADDRESS - && far_call_abi.memory_quasi_fat_pointer.length == 64 - { - let calldata_page = get_calldata_page_via_abi( - &far_call_abi, - state.vm_local_state.callstack.current.base_memory_page, - ); - let calldata = memory.read_unaligned_bytes( - calldata_page as usize, - far_call_abi.memory_quasi_fat_pointer.start as usize, - 64, - ); - - let slot_to_add = - self.slot_to_add_from_keccak_call(&calldata, self.user_address); - - if let Some(slot) = slot_to_add { - return Ok(NewTrustedValidationItems { - new_allowed_slots: vec![slot], - ..Default::default() - }); - } - } else if called_address != self.user_address { - let code_key = get_code_key(&called_address); - let code = storage.borrow_mut().read_value(&code_key); - - if code == H256::zero() { - // The users are not allowed to call contracts with no code - return Err(ViolatedValidationRule::CalledContractWithNoCode( - called_address, - )); - } - } - } - Opcode::Context(context) => { - match context { - ContextOpcode::Meta => { - return Err(ViolatedValidationRule::TouchedUnallowedContext); - } - ContextOpcode::ErgsLeft => { - // TODO (SMA-1168): implement the correct restrictions for the gas left opcode. - } - _ => {} - } - } - Opcode::Log(LogOpcode::StorageRead) => { - let key = data.src0_value.value; - let this_address = state.vm_local_state.callstack.current.this_address; - let msg_sender = state.vm_local_state.callstack.current.msg_sender; - - if !self.is_allowed_storage_read(storage.clone(), this_address, key, msg_sender) { - return Err(ViolatedValidationRule::TouchedUnallowedStorageSlots( - this_address, - key, - )); - } - - if self.trusted_address_slots.contains(&(this_address, key)) { - let storage_key = - StorageKey::new(AccountTreeId::new(this_address), u256_to_h256(key)); - - let value = storage.borrow_mut().read_value(&storage_key); - - return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], - ..Default::default() - }); - } - } - _ => {} - } - - Ok(Default::default()) - } -} - -impl DynTracer for ValidationTracer { - fn before_execution( - &mut self, - state: VmLocalStateData<'_>, - data: BeforeExecutionData, - memory: &SimpleMemory, - storage: StoragePtr, - ) { - // For now, we support only validations for users. - if let ValidationTracerMode::UserTxValidation = self.validation_mode { - self.computational_gas_used = self - .computational_gas_used - .saturating_add(computational_gas_price(state, &data)); - - let validation_round_result = - self.check_user_restrictions(state, data, memory, storage); - self.process_validation_round_result(validation_round_result); - } - - let hook = VmHook::from_opcode_memory(&state, &data); - print_debug_if_needed(&hook, &state, memory); - - let current_mode = self.validation_mode; - match (current_mode, hook) { - (ValidationTracerMode::NoValidation, VmHook::AccountValidationEntered) => { - // Account validation can be entered when there is no prior validation (i.e. "nested" validations are not allowed) - self.validation_mode = ValidationTracerMode::UserTxValidation; - } - (ValidationTracerMode::NoValidation, VmHook::PaymasterValidationEntered) => { - // Paymaster validation can be entered when there is no prior validation (i.e. "nested" validations are not allowed) - self.validation_mode = ValidationTracerMode::PaymasterTxValidation; - } - (_, VmHook::AccountValidationEntered | VmHook::PaymasterValidationEntered) => { - panic!( - "Unallowed transition inside the validation tracer. Mode: {:#?}, hook: {:#?}", - self.validation_mode, hook - ); - } - (_, VmHook::NoValidationEntered) => { - // Validation can be always turned off - self.validation_mode = ValidationTracerMode::NoValidation; - } - (_, VmHook::ValidationStepEndeded) => { - // The validation step has ended. - self.should_stop_execution = true; - } - (_, _) => { - // The hook is not relevant to the validation tracer. Ignore. - } - } - } -} - -impl VmTracer for ValidationTracer { - fn finish_cycle( - &mut self, - _state: &mut ZkSyncVmState, - _bootloader_state: &mut BootloaderState, - ) -> TracerExecutionStatus { - if self.should_stop_execution { - return TracerExecutionStatus::Stop(TracerExecutionStopReason::Finish); - } - if let Some(result) = self.result.get() { - return TracerExecutionStatus::Stop(TracerExecutionStopReason::Abort( - Halt::TracerCustom(format!("Validation error: {:#?}", result)), - )); - } - TracerExecutionStatus::Continue - } -} - -fn touches_allowed_context(address: Address, key: U256) -> bool { - // Context is not touched at all - if address != SYSTEM_CONTEXT_ADDRESS { - return false; - } - - // Only chain_id is allowed to be touched. - key == U256::from(0u32) -} - -fn is_constant_code_hash( - address: Address, - key: U256, - storage: StoragePtr, -) -> bool { - if address != ACCOUNT_CODE_STORAGE_ADDRESS { - // Not a code hash - return false; - } - - let value = storage.borrow_mut().read_value(&StorageKey::new( - AccountTreeId::new(address), - u256_to_h256(key), - )); - - value != H256::zero() -} - -fn valid_eth_token_call(address: Address, msg_sender: Address) -> bool { - let is_valid_caller = msg_sender == MSG_VALUE_SIMULATOR_ADDRESS - || msg_sender == CONTRACT_DEPLOYER_ADDRESS - || msg_sender == BOOTLOADER_ADDRESS; - address == L2_ETH_TOKEN_ADDRESS && is_valid_caller -} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/params.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/params.rs deleted file mode 100644 index 1a4ced478b67..000000000000 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/params.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::collections::HashSet; -use zksync_types::{Address, U256}; - -#[derive(Debug, Clone)] -pub struct ValidationTracerParams { - pub user_address: Address, - pub paymaster_address: Address, - /// Slots that are trusted (i.e. the user can access them). - pub trusted_slots: HashSet<(Address, U256)>, - /// Trusted addresses (the user can access any slots on these addresses). - pub trusted_addresses: HashSet
, - /// Slots, that are trusted and the value of them is the new trusted address. - /// They are needed to work correctly with beacon proxy, where the address of the implementation is - /// stored in the beacon. - pub trusted_address_slots: HashSet<(Address, U256)>, - /// Number of computational gas that validation step is allowed to use. - pub computational_gas_limit: u32, -} diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/types.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/types.rs deleted file mode 100644 index b9d442279927..000000000000 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/validation/types.rs +++ /dev/null @@ -1,18 +0,0 @@ -use zksync_types::{Address, H256}; - -#[derive(Debug, Clone, Eq, PartialEq, Copy)] -#[allow(clippy::enum_variant_names)] -pub(super) enum ValidationTracerMode { - /// Should be activated when the transaction is being validated by user. - UserTxValidation, - /// Should be activated when the transaction is being validated by the paymaster. - PaymasterTxValidation, - /// Is a state when there are no restrictions on the execution. - NoValidation, -} - -#[derive(Debug, Clone, Default)] -pub(super) struct NewTrustedValidationItems { - pub(super) new_allowed_slots: Vec, - pub(super) new_trusted_addresses: Vec
, -} 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 c9d7d2b06ab5..d7edcfe7ff97 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs @@ -1,18 +1,19 @@ +use crate::HistoryMode; use zksync_state::{StoragePtr, WriteStorage}; use zksync_types::l2_to_l1_log::UserL2ToL1Log; use zksync_types::Transaction; use zksync_utils::bytecode::CompressedBytecodeInfo; use crate::vm_refunds_enhancement::old_vm::events::merge_events; -use crate::vm_refunds_enhancement::old_vm::history_recorder::{HistoryEnabled, HistoryMode}; use crate::interface::BytecodeCompressionError; use crate::interface::{ BootloaderMemory, CurrentExecutionState, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode, - VmExecutionResultAndLogs, + VmExecutionResultAndLogs, VmInterface, VmInterfaceHistoryEnabled, }; +use crate::vm_latest::HistoryEnabled; use crate::vm_refunds_enhancement::bootloader_state::BootloaderState; -use crate::vm_refunds_enhancement::tracers::traits::VmTracer; +use crate::vm_refunds_enhancement::tracers::dispatcher::TracerDispatcher; use crate::vm_refunds_enhancement::types::internals::{new_vm_state, VmSnapshot, ZkSyncVmState}; /// Main entry point for Virtual Machine integration. @@ -21,7 +22,7 @@ use crate::vm_refunds_enhancement::types::internals::{new_vm_state, VmSnapshot, pub struct Vm { pub(crate) bootloader_state: BootloaderState, // Current state and oracles of virtual machine - pub(crate) state: ZkSyncVmState, + pub(crate) state: ZkSyncVmState, pub(crate) storage: StoragePtr, pub(crate) system_env: SystemEnv, pub(crate) batch_env: L1BatchEnv, @@ -31,8 +32,10 @@ pub struct Vm { } /// Public interface for VM -impl Vm { - pub fn new(batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr, _: H) -> Self { +impl VmInterface for Vm { + type TracerDispatcher = TracerDispatcher; + + fn new(batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr) -> Self { let (state, bootloader_state) = new_vm_state(storage.clone(), &system_env, &batch_env); Self { bootloader_state, @@ -46,43 +49,37 @@ impl Vm { } /// Push tx into memory for the future execution - pub fn push_transaction(&mut self, tx: Transaction) { + fn push_transaction(&mut self, tx: Transaction) { self.push_transaction_with_compression(tx, true) } - /// Execute VM with default tracers. The execution mode determines whether the VM will stop and - /// how the vm will be processed. - pub fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs { - self.inspect(vec![], execution_mode) - } - /// Execute VM with custom tracers. - pub fn inspect( + fn inspect( &mut self, - tracers: Vec>>, + dispatcher: Self::TracerDispatcher, execution_mode: VmExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracers, execution_mode) + self.inspect_inner(dispatcher, execution_mode) } /// Get current state of bootloader memory. - pub fn get_bootloader_memory(&self) -> BootloaderMemory { + fn get_bootloader_memory(&self) -> BootloaderMemory { self.bootloader_state.bootloader_memory() } /// Get compressed bytecodes of the last executed transaction - pub fn get_last_tx_compressed_bytecodes(&self) -> Vec { + fn get_last_tx_compressed_bytecodes(&self) -> Vec { self.bootloader_state.get_last_tx_compressed_bytecodes() } - pub fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { + fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { self.bootloader_state.start_new_l2_block(l2_block_env); } /// Get current state of virtual machine. /// This method should be used only after the batch execution. /// Otherwise it can panic. - pub fn get_current_execution_state(&self) -> CurrentExecutionState { + fn get_current_execution_state(&self) -> CurrentExecutionState { let (deduplicated_events_logs, raw_events, l1_messages) = self.state.event_sink.flatten(); let events: Vec<_> = merge_events(raw_events) .into_iter() @@ -114,24 +111,15 @@ impl Vm { } } - /// Execute transaction with optional bytecode compression. - pub fn execute_transaction_with_bytecode_compression( - &mut self, - tx: Transaction, - with_compression: bool, - ) -> Result { - self.inspect_transaction_with_bytecode_compression(vec![], tx, with_compression) - } - /// Inspect transaction with optional bytecode compression. - pub fn inspect_transaction_with_bytecode_compression( + fn inspect_transaction_with_bytecode_compression( &mut self, - tracers: Vec>>, + dispatcher: Self::TracerDispatcher, tx: Transaction, with_compression: bool, ) -> Result { self.push_transaction_with_compression(tx, with_compression); - let result = self.inspect(tracers, VmExecutionMode::OneTx); + let result = self.inspect(dispatcher, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { Err(BytecodeCompressionError::BytecodeCompressionFailed) } else { @@ -141,14 +129,14 @@ impl Vm { } /// Methods of vm, which required some history manipullations -impl Vm { +impl VmInterfaceHistoryEnabled for Vm { /// Create snapshot of current vm state and push it into the memory - pub fn make_snapshot(&mut self) { + fn make_snapshot(&mut self) { self.make_snapshot_inner() } /// Rollback vm state to the latest snapshot and destroy the snapshot - pub fn rollback_to_the_latest_snapshot(&mut self) { + fn rollback_to_the_latest_snapshot(&mut self) { let snapshot = self .snapshots .pop() @@ -157,7 +145,7 @@ impl Vm { } /// Pop the latest snapshot from the memory and destroy it - pub fn pop_snapshot_no_rollback(&mut self) { + fn pop_snapshot_no_rollback(&mut self) { self.snapshots .pop() .expect("Snapshot should be created before rolling it back"); diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/mod.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/mod.rs index 899ad28a65f6..3a7a96e729d7 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/mod.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/mod.rs @@ -7,7 +7,6 @@ pub use old_vm::{ pub use tracers::{ dispatcher::TracerDispatcher, traits::{ExecutionEndTracer, ExecutionProcessing, TracerPointer, VmTracer}, - utils::VmExecutionStopReason, }; pub use types::internals::ZkSyncVmState; diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs index a2698e85c101..abf8714bbe9a 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs @@ -216,9 +216,3 @@ pub(crate) fn get_vm_hook_params(memory: &SimpleMemory) -> Ve VM_HOOK_PARAMS_START_POSITION..VM_HOOK_PARAMS_START_POSITION + VM_HOOK_PARAMS_COUNT, ) } - -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum VmExecutionStopReason { - VmFinished, - TracerRequestedStop, -} diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index aa81b4352087..0cf4a992b962 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -25,7 +25,7 @@ pub(crate) enum VmInstanceVersion { Vm1_3_2(Box, H::Vm1_3_2Mode>>), VmVirtualBlocks(Box, H>>), VmVirtualBlocksRefundsEnhancement(Box, H>>), - VmBoojumIntegration(Box, H::VmBoojumIntegration>>), + VmBoojumIntegration(Box, H>>), } impl VmInstance { @@ -213,13 +213,16 @@ impl VmInstance { vm.inspect(tracers.into(), VmExecutionMode::OneTx) } VmInstanceVersion::VmVirtualBlocksRefundsEnhancement(vm) => { + let tracers: Vec<_> = tracers + .into_iter() + .map(|t| t.vm_refunds_enhancement()) + .collect(); + vm.inspect(tracers.into(), VmExecutionMode::OneTx) + } + VmInstanceVersion::VmBoojumIntegration(vm) => { let tracers: Vec<_> = tracers.into_iter().map(|t| t.latest()).collect(); vm.inspect(tracers.into(), VmExecutionMode::OneTx) } - VmInstanceVersion::VmBoojumIntegration(vm) => vm.inspect( - tracers.into_iter().map(|tracer| tracer.latest()).collect(), - VmExecutionMode::OneTx, - ), _ => self.execute_next_transaction(), } } @@ -402,19 +405,24 @@ impl VmInstance { ) } VmInstanceVersion::VmVirtualBlocksRefundsEnhancement(vm) => { - let tracers: Vec<_> = tracers.into_iter().map(|t| t.latest()).collect(); + let tracers: Vec<_> = tracers + .into_iter() + .map(|t| t.vm_refunds_enhancement()) + .collect(); vm.inspect_transaction_with_bytecode_compression( tracers.into(), tx, with_compression, ) } - VmInstanceVersion::VmBoojumIntegration(vm) => vm - .inspect_transaction_with_bytecode_compression( - tracers.into_iter().map(|tracer| tracer.latest()).collect(), + VmInstanceVersion::VmBoojumIntegration(vm) => { + let tracers: Vec<_> = tracers.into_iter().map(|t| t.latest()).collect(); + vm.inspect_transaction_with_bytecode_compression( + tracers.into(), tx, with_compression, - ), + ) + } _ => { self.last_tx_compressed_bytecodes = vec![]; self.execute_transaction_with_bytecode_compression(tx, with_compression)