Skip to content

Commit

Permalink
Mirrors branch deniallugo-vm-perf-optimization from private at 008df6…
Browse files Browse the repository at this point in the history
…deb6bd627ec9dc901a78aca374f16fd14e
  • Loading branch information
Deniallugo committed Sep 29, 2023
1 parent d8ab843 commit 57259be
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 44 deletions.
1 change: 0 additions & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
.github/release-please/** @RomanBrodetski @perekopskiy @Deniallugo @popzxc
**/CHANGELOG.md @RomanBrodetski @perekopskiy @Deniallugo @popzxc
CODEOWNERS @RomanBrodetski @perekopskiy @Deniallugo @popzxc
.github/workflows/** @matter-labs/devops
31 changes: 25 additions & 6 deletions core/lib/vm/src/implementation/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
mut tracers: Vec<Box<dyn VmTracer<S, H>>>,
execution_mode: VmExecutionMode,
) -> VmExecutionResultAndLogs {
let mut enable_refund_tracer = false;
if let VmExecutionMode::OneTx = execution_mode {
// For correct results we have to include refunds tracer to the desired tracers
tracers.push(RefundsTracer::new(self.batch_env.clone()).into_boxed());
// Move the pointer to the next transaction
self.bootloader_state.move_tx_to_execute_pointer();
enable_refund_tracer = true;
}
let (_, result) = self.inspect_and_collect_results(tracers, execution_mode);
let (_, result) = self.inspect_and_collect_results(tracers, execution_mode, enable_refund_tracer);
result
}

Expand All @@ -35,12 +34,19 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
&mut self,
tracers: Vec<Box<dyn VmTracer<S, H>>>,
execution_mode: VmExecutionMode,
with_refund_tracer: bool,
) -> (VmExecutionStopReason, VmExecutionResultAndLogs) {
let refund_tracers = if with_refund_tracer {
Some(RefundsTracer::new(self.batch_env.clone()))
} else {
None
};
let mut tx_tracer: DefaultExecutionTracer<S, H> = DefaultExecutionTracer::new(
self.system_env.default_validation_computational_gas_limit,
execution_mode,
tracers,
self.storage.clone(),
refund_tracers,
);

let timestamp_initial = Timestamp(self.state.local_state.timestamp);
Expand All @@ -66,11 +72,17 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {

let result = tx_tracer.result_tracer.into_result();

let refunds = if let Some(refund_tracer) = tx_tracer.refund_tracer {
refund_tracer.get_refunds()
} else {
Default::default()
};

let mut result = VmExecutionResultAndLogs {
result,
logs,
statistics,
refunds: Default::default(),
refunds,
};

for tracer in tx_tracer.custom_tracers.iter_mut() {
Expand All @@ -83,7 +95,14 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
fn execute_with_default_tracer(
&mut self,
tracer: &mut DefaultExecutionTracer<S, H>,
) -> VmExecutionStopReason {
) -> VmExecutionResultAndLogs {
let (_stop_reason, result) =
self.inspect_and_collect_results(tracers, ExecutionMode::Block, false);
result
}

/// Execute vm with given tracers until the stop reason is reached.
fn execute(&mut self, tracer: &mut DefaultExecutionTracer<S, H>) -> VmExecutionStopReason {
tracer.initialize_tracer(&mut self.state);
let result = loop {
// Sanity check: we should never reach the maximum value, because then we won't be able to process the next cycle.
Expand Down
14 changes: 1 addition & 13 deletions core/lib/vm/src/old_vm/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,24 +269,12 @@ impl<H: HistoryMode> Memory for SimpleMemory<H> {

fn finish_global_frame(
&mut self,
base_page: MemoryPage,
_base_page: MemoryPage,
returndata_fat_pointer: FatPointer,
timestamp: Timestamp,
) {
// Safe to unwrap here, since `finish_global_frame` is never called with empty stack
let current_observable_pages = self.observable_pages.inner().current_frame();
let returndata_page = returndata_fat_pointer.memory_page;

for &page in current_observable_pages {
// If the page's number is greater than or equal to the base_page,
// it means that it was created by the internal calls of this contract.
// We need to add this check as the calldata pointer is also part of the
// observable pages.
if page >= base_page.0 && page != returndata_page {
self.memory.clear_page(page as usize, timestamp);
}
}

self.observable_pages.clear_frame(timestamp);
self.observable_pages.merge_frame(timestamp);

Expand Down
54 changes: 38 additions & 16 deletions core/lib/vm/src/tracers/default_tracers.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::fmt::{Debug, Formatter};

use zk_evm::witness_trace::DummyTracer;
use zk_evm::zkevm_opcode_defs::{Opcode, RetOpcode};
use zk_evm::{
tracing::{
AfterDecodingData, AfterExecutionData, BeforeExecutionData, Tracer, VmLocalStateData,
},
vm_state::VmLocalState,
witness_trace::DummyTracer,
zkevm_opcode_defs::{decoding::EncodingModeProduction, Opcode, RetOpcode},
};
use zksync_state::{StoragePtr, WriteStorage};
use zksync_types::Timestamp;
Expand All @@ -21,7 +21,7 @@ use crate::tracers::utils::{
computational_gas_price, gas_spent_on_bytecodes_and_long_messages_this_opcode,
print_debug_if_needed, VmHook,
};
use crate::tracers::ResultTracer;
use crate::tracers::{RefundsTracer, ResultTracer};
use crate::types::internals::ZkSyncVmState;
use crate::{VmExecutionMode, VmExecutionStopReason};

Expand All @@ -38,6 +38,7 @@ pub(crate) struct DefaultExecutionTracer<S, H: HistoryMode> {
in_account_validation: bool,
final_batch_info_requested: bool,
pub(crate) result_tracer: ResultTracer,
pub(crate) refund_tracer: Option<RefundsTracer>,
pub(crate) custom_tracers: Vec<Box<dyn VmTracer<S, H>>>,
ret_from_the_bootloader: Option<RetOpcode>,
storage: StoragePtr<S>,
Expand All @@ -50,17 +51,17 @@ impl<S, H: HistoryMode> Debug for DefaultExecutionTracer<S, H> {
}

impl<S, H: HistoryMode> Tracer for DefaultExecutionTracer<S, H> {
const CALL_BEFORE_DECODING: bool = true;
const CALL_BEFORE_DECODING: bool = false;
const CALL_AFTER_DECODING: bool = true;
const CALL_BEFORE_EXECUTION: bool = true;
const CALL_AFTER_EXECUTION: bool = true;
type SupportedMemory = SimpleMemory<H>;

fn before_decoding(&mut self, state: VmLocalStateData<'_>, memory: &Self::SupportedMemory) {
<ResultTracer as DynTracer<S, H>>::before_decoding(&mut self.result_tracer, state, memory);
for tracer in self.custom_tracers.iter_mut() {
tracer.before_decoding(state, memory)
}
fn before_decoding(
&mut self,
_state: VmLocalStateData<'_, 8, EncodingModeProduction>,
_memory: &Self::SupportedMemory,
) {
}

fn after_decoding(
Expand All @@ -75,6 +76,11 @@ impl<S, H: HistoryMode> Tracer for DefaultExecutionTracer<S, H> {
data,
memory,
);

if let Some(refund_tracer) = &mut self.refund_tracer {
<RefundsTracer as DynTracer<S, H>>::after_decoding(refund_tracer, state, data, memory);
}

for tracer in self.custom_tracers.iter_mut() {
tracer.after_decoding(state, data, memory)
}
Expand Down Expand Up @@ -107,6 +113,10 @@ impl<S, H: HistoryMode> Tracer for DefaultExecutionTracer<S, H> {
gas_spent_on_bytecodes_and_long_messages_this_opcode(&state, &data);
self.result_tracer
.before_execution(state, data, memory, self.storage.clone());

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());
}
Expand Down Expand Up @@ -134,6 +144,9 @@ impl<S, H: HistoryMode> Tracer for DefaultExecutionTracer<S, H> {

self.result_tracer
.after_execution(state, data, memory, self.storage.clone());
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());
}
Expand All @@ -148,6 +161,10 @@ impl<S: WriteStorage, H: HistoryMode> ExecutionEndTracer<H> for DefaultExecution
VmExecutionMode::Bootloader => self.ret_from_the_bootloader == Some(RetOpcode::Ok),
};
should_stop = should_stop || self.validation_run_out_of_gas();
if let Some(refund_tracer) = &self.refund_tracer {
should_stop = should_stop
|| <RefundsTracer as ExecutionEndTracer<H>>::should_stop_execution(refund_tracer)
}
for tracer in self.custom_tracers.iter() {
should_stop = should_stop || tracer.should_stop_execution();
}
Expand All @@ -161,6 +178,7 @@ impl<S: WriteStorage, H: HistoryMode> DefaultExecutionTracer<S, H> {
execution_mode: VmExecutionMode,
custom_tracers: Vec<Box<dyn VmTracer<S, H>>>,
storage: StoragePtr<S>,
refund_tracer: Option<RefundsTracer>,
) -> Self {
Self {
tx_has_been_processed: false,
Expand All @@ -171,6 +189,7 @@ impl<S: WriteStorage, H: HistoryMode> DefaultExecutionTracer<S, H> {
in_account_validation: false,
final_batch_info_requested: false,
result_tracer: ResultTracer::new(execution_mode),
refund_tracer,
custom_tracers,
ret_from_the_bootloader: None,
storage,
Expand Down Expand Up @@ -211,15 +230,11 @@ impl<S, H: HistoryMode> DynTracer<S, H> for DefaultExecutionTracer<S, H> {}
impl<S: WriteStorage, H: HistoryMode> ExecutionProcessing<S, H> for DefaultExecutionTracer<S, H> {
fn initialize_tracer(&mut self, state: &mut ZkSyncVmState<S, H>) {
self.result_tracer.initialize_tracer(state);
for processor in self.custom_tracers.iter_mut() {
processor.initialize_tracer(state);
if let Some(refund_tracer) = &mut self.refund_tracer {
refund_tracer.initialize_tracer(state);
}
}

fn before_cycle(&mut self, state: &mut ZkSyncVmState<S, H>) {
self.result_tracer.before_cycle(state);
for processor in self.custom_tracers.iter_mut() {
processor.before_cycle(state);
processor.initialize_tracer(state);
}
}

Expand All @@ -232,6 +247,9 @@ impl<S: WriteStorage, H: HistoryMode> ExecutionProcessing<S, H> for DefaultExecu
for processor in self.custom_tracers.iter_mut() {
processor.after_cycle(state, bootloader_state);
}
if let Some(refund_tracer) = &mut self.refund_tracer {
refund_tracer.after_cycle(state, bootloader_state);
}
if self.final_batch_info_requested {
self.set_fictive_l2_block(state, bootloader_state)
}
Expand All @@ -245,6 +263,10 @@ impl<S: WriteStorage, H: HistoryMode> ExecutionProcessing<S, H> for DefaultExecu
) {
self.result_tracer
.after_vm_execution(state, bootloader_state, stop_reason);

if let Some(refund_tracer) = &mut self.refund_tracer {
refund_tracer.after_vm_execution(state, bootloader_state, stop_reason);
}
for processor in self.custom_tracers.iter_mut() {
processor.after_vm_execution(state, bootloader_state, stop_reason);
}
Expand Down
17 changes: 9 additions & 8 deletions core/lib/vm/src/tracers/refunds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ impl RefundsTracer {
0
}

pub(crate) fn get_refunds(&self) -> Refunds {
Refunds {
gas_refunded: self.refund_gas,
operator_suggested_refund: self.operator_refund.unwrap_or_default(),
}
}

pub(crate) fn tx_body_refund(
&self,
bootloader_refund: u32,
Expand Down Expand Up @@ -147,6 +154,7 @@ impl<S, H: HistoryMode> DynTracer<S, H> for RefundsTracer {
memory: &SimpleMemory<H>,
_storage: StoragePtr<S>,
) {
self.timestamp_before_cycle = Timestamp(state.vm_local_state.timestamp);
let hook = VmHook::from_opcode_memory(&state, &data);
match hook {
VmHook::NotifyAboutRefund => self.refund_gas = get_vm_hook_params(memory)[0].as_u32(),
Expand All @@ -170,10 +178,6 @@ impl<S: WriteStorage, H: HistoryMode> ExecutionProcessing<S, H> for RefundsTrace
self.spent_pubdata_counter_before = state.local_state.spent_pubdata_counter;
}

fn before_cycle(&mut self, state: &mut ZkSyncVmState<S, H>) {
self.timestamp_before_cycle = Timestamp(state.local_state.timestamp);
}

fn after_cycle(
&mut self,
state: &mut ZkSyncVmState<S, H>,
Expand Down Expand Up @@ -386,9 +390,6 @@ fn pubdata_published_for_writes<S: WriteStorage, H: HistoryMode>(

impl<S: WriteStorage, H: HistoryMode> VmTracer<S, H> for RefundsTracer {
fn save_results(&mut self, result: &mut VmExecutionResultAndLogs) {
result.refunds = Refunds {
gas_refunded: self.refund_gas,
operator_suggested_refund: self.operator_refund.unwrap_or_default(),
}
result.refunds = self.get_refunds();
}
}

0 comments on commit 57259be

Please sign in to comment.