Skip to content

Commit

Permalink
Revert "feat(vm): Simplify VM interface (#2760)"
Browse files Browse the repository at this point in the history
This reverts commit c3bde47.
  • Loading branch information
slowli committed Sep 3, 2024
1 parent a8838eb commit ba9cc7b
Show file tree
Hide file tree
Showing 83 changed files with 930 additions and 529 deletions.
2 changes: 1 addition & 1 deletion core/bin/system-constants-generator/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use zksync_multivm::{
storage::{InMemoryStorage, StorageView, WriteStorage},
tracer::VmExecutionStopReason,
L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmFactory,
VmInterface, VmInterfaceExt,
VmInterface,
},
tracers::dynamic::vm_1_5_0::DynTracer,
vm_latest::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ impl GlueFrom<crate::vm_m5::vm_instance::VmPartialExecutionResult>
contracts_used: value.contracts_used,
cycles_used: value.cycles_used,
total_log_queries: value.logs.total_log_queries_count,
gas_remaining: value.gas_remaining,
// There are no such fields in `m5`.
gas_used: 0,
gas_remaining: 0,
computational_gas_used: 0,
pubdata_published: 0,
circuit_statistic: Default::default(),
Expand All @@ -37,10 +37,10 @@ impl GlueFrom<crate::vm_m6::vm_instance::VmPartialExecutionResult>
contracts_used: value.contracts_used,
cycles_used: value.cycles_used,
computational_gas_used: value.computational_gas_used,
gas_remaining: value.gas_remaining,
total_log_queries: value.logs.total_log_queries_count,
// There are no such fields in `m6`.
gas_used: 0,
gas_remaining: 0,
pubdata_published: 0,
circuit_statistic: Default::default(),
},
Expand All @@ -63,10 +63,10 @@ impl GlueFrom<crate::vm_1_3_2::vm_instance::VmPartialExecutionResult>
contracts_used: value.contracts_used,
cycles_used: value.cycles_used,
computational_gas_used: value.computational_gas_used,
gas_remaining: value.gas_remaining,
total_log_queries: value.logs.total_log_queries_count,
// There are no such fields in `1_3_2`.
gas_used: 0,
gas_remaining: 0,
pubdata_published: 0,
circuit_statistic: Default::default(),
},
Expand Down
99 changes: 90 additions & 9 deletions core/lib/multivm/src/versions/shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use zksync_types::{StorageKey, StorageLog, StorageLogWithPreviousValue, Transact
use crate::{
interface::{
storage::{ImmutableStorageView, ReadStorage, StoragePtr, StorageView},
BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv,
SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface,
VmInterfaceHistoryEnabled, VmMemoryMetrics,
BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
VmMemoryMetrics,
},
vm_fast,
};
Expand Down Expand Up @@ -51,6 +52,18 @@ where
self.main.push_transaction(tx);
}

fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs {
let main_result = self.main.execute(execution_mode);
let shadow_result = self.shadow.execute(execution_mode);
let mut errors = DivergenceErrors::default();
errors.check_results_match(&main_result, &shadow_result);
errors
.into_result()
.with_context(|| format!("executing VM with mode {execution_mode:?}"))
.unwrap();
main_result
}

fn inspect(
&mut self,
dispatcher: Self::TracerDispatcher,
Expand All @@ -67,17 +80,73 @@ where
main_result
}

fn get_bootloader_memory(&self) -> BootloaderMemory {
let main_memory = self.main.get_bootloader_memory();
let shadow_memory = self.shadow.get_bootloader_memory();
DivergenceErrors::single("get_bootloader_memory", &main_memory, &shadow_memory).unwrap();
main_memory
}

fn get_last_tx_compressed_bytecodes(&self) -> Vec<CompressedBytecodeInfo> {
let main_bytecodes = self.main.get_last_tx_compressed_bytecodes();
let shadow_bytecodes = self.shadow.get_last_tx_compressed_bytecodes();
DivergenceErrors::single(
"get_last_tx_compressed_bytecodes",
&main_bytecodes,
&shadow_bytecodes,
)
.unwrap();
main_bytecodes
}

fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) {
self.shadow.start_new_l2_block(l2_block_env);
self.main.start_new_l2_block(l2_block_env);
}

fn get_current_execution_state(&self) -> CurrentExecutionState {
let main_state = self.main.get_current_execution_state();
let shadow_state = self.shadow.get_current_execution_state();
DivergenceErrors::single("get_current_execution_state", &main_state, &shadow_state)
.unwrap();
main_state
}

fn execute_transaction_with_bytecode_compression(
&mut self,
tx: Transaction,
with_compression: bool,
) -> (
Result<(), BytecodeCompressionError>,
VmExecutionResultAndLogs,
) {
let tx_hash = tx.hash();
let main_result = self
.main
.execute_transaction_with_bytecode_compression(tx.clone(), with_compression);
let shadow_result = self
.shadow
.execute_transaction_with_bytecode_compression(tx, with_compression);
let mut errors = DivergenceErrors::default();
errors.check_results_match(&main_result.1, &shadow_result.1);
errors
.into_result()
.with_context(|| {
format!("executing transaction {tx_hash:?}, with_compression={with_compression:?}")
})
.unwrap();
main_result
}

fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) {
) -> (
Result<(), BytecodeCompressionError>,
VmExecutionResultAndLogs,
) {
let tx_hash = tx.hash();
let main_result = self.main.inspect_transaction_with_bytecode_compression(
tracer,
Expand All @@ -102,6 +171,13 @@ where
self.main.record_vm_memory_metrics()
}

fn gas_remaining(&self) -> u32 {
let main_gas = self.main.gas_remaining();
let shadow_gas = self.shadow.gas_remaining();
DivergenceErrors::single("gas_remaining", &main_gas, &shadow_gas).unwrap();
main_gas
}

fn finish_batch(&mut self) -> FinishedL1Batch {
let main_batch = self.main.finish_batch();
let shadow_batch = self.shadow.finish_batch();
Expand Down Expand Up @@ -140,6 +216,16 @@ where
pub struct DivergenceErrors(Vec<anyhow::Error>);

impl DivergenceErrors {
fn single<T: fmt::Debug + PartialEq>(
context: &str,
main: &T,
shadow: &T,
) -> anyhow::Result<()> {
let mut this = Self::default();
this.check_match(context, main, shadow);
this.into_result()
}

fn check_results_match(
&mut self,
main_result: &VmExecutionResultAndLogs,
Expand All @@ -165,11 +251,6 @@ impl DivergenceErrors {
let shadow_logs = UniqueStorageLogs::new(&shadow_result.logs.storage_logs);
self.check_match("logs.storage_logs", &main_logs, &shadow_logs);
self.check_match("refunds", &main_result.refunds, &shadow_result.refunds);
self.check_match(
"gas_remaining",
&main_result.statistics.gas_remaining,
&shadow_result.statistics.gas_remaining,
);
}

fn check_match<T: fmt::Debug + PartialEq>(&mut self, context: &str, main: &T, shadow: &T) {
Expand Down
102 changes: 88 additions & 14 deletions core/lib/multivm/src/versions/vm_1_3_2/vm.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
use std::collections::HashSet;

use zksync_types::Transaction;
use zksync_utils::{bytecode::hash_bytecode, h256_to_u256};
use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries;
use zksync_types::{
l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log},
Transaction,
};
use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256};

use crate::{
glue::{history_mode::HistoryMode, GlueInto},
interface::{
storage::{StoragePtr, WriteStorage},
BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv,
L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmExecutionResultAndLogs,
VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics,
BootloaderMemory, BytecodeCompressionError, CompressedBytecodeInfo, CurrentExecutionState,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
VmMemoryMetrics,
},
tracers::old::TracerDispatcher,
utils::bytecode,
vm_1_3_2::VmInstance,
vm_1_3_2::{events::merge_events, VmInstance},
};

#[derive(Debug)]
pub struct Vm<S: WriteStorage, H: HistoryMode> {
pub(crate) vm: VmInstance<S, H::Vm1_3_2Mode>,
pub(crate) system_env: SystemEnv,
pub(crate) batch_env: L1BatchEnv,
pub(crate) last_tx_compressed_bytecodes: Vec<CompressedBytecodeInfo>,
}

impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
Expand Down Expand Up @@ -74,23 +81,83 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
}
}

fn get_bootloader_memory(&self) -> BootloaderMemory {
vec![]
}

fn get_last_tx_compressed_bytecodes(&self) -> Vec<CompressedBytecodeInfo> {
self.last_tx_compressed_bytecodes.clone()
}

fn start_new_l2_block(&mut self, _l2_block_env: L2BlockEnv) {
// Do nothing, because vm 1.3.2 doesn't support L2 blocks
}

fn get_current_execution_state(&self) -> CurrentExecutionState {
let (raw_events, l1_messages) = self.vm.state.event_sink.flatten();
let events = merge_events(raw_events)
.into_iter()
.map(|e| e.into_vm_event(self.batch_env.number))
.collect();
let l2_to_l1_logs = l1_messages
.into_iter()
.map(|m| {
UserL2ToL1Log(L2ToL1Log {
shard_id: m.shard_id,
is_service: m.is_first,
tx_number_in_block: m.tx_number_in_block,
sender: m.address,
key: u256_to_h256(m.key),
value: u256_to_h256(m.value),
})
})
.collect();

let used_contract_hashes = self
.vm
.state
.decommittment_processor
.known_bytecodes
.inner()
.keys()
.cloned()
.collect();

let storage_log_queries = self.vm.state.storage.get_final_log_queries();

let deduped_storage_log_queries =
sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1;

CurrentExecutionState {
events,
deduplicated_storage_logs: deduped_storage_log_queries
.into_iter()
.map(GlueInto::glue_into)
.collect(),
used_contract_hashes,
user_l2_to_l1_logs: l2_to_l1_logs,
system_logs: vec![],
// Fields below are not produced by VM 1.3.2
storage_refunds: vec![],
pubdata_costs: Vec::new(),
}
}

fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) {
) -> (
Result<(), BytecodeCompressionError>,
VmExecutionResultAndLogs,
) {
if let Some(storage_invocations) = tracer.storage_invocations {
self.vm
.execution_mode
.set_invocation_limit(storage_invocations);
}

let compressed_bytecodes: Vec<_>;
self.last_tx_compressed_bytecodes = vec![];
let bytecodes = if with_compression {
let deps = &tx.execute.factory_deps;
let mut deps_hashes = HashSet::with_capacity(deps.len());
Expand All @@ -107,17 +174,18 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
bytecode::compress(bytecode.clone()).ok()
}
});
compressed_bytecodes = filtered_deps.collect();
let compressed_bytecodes: Vec<_> = filtered_deps.collect();

self.last_tx_compressed_bytecodes
.clone_from(&compressed_bytecodes);
crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
self.system_env.execution_mode.glue_into(),
Some(compressed_bytecodes.clone()),
Some(compressed_bytecodes),
);
bytecode_hashes
} else {
compressed_bytecodes = vec![];
crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
Expand Down Expand Up @@ -156,7 +224,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
result,
)
} else {
(Ok(compressed_bytecodes), result)
(Ok(()), result)
}
}

Expand All @@ -177,6 +245,10 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
}
}

fn gas_remaining(&self) -> u32 {
self.vm.gas_remaining()
}

fn finish_batch(&mut self) -> FinishedL1Batch {
self.vm
.execute_till_block_end(
Expand All @@ -198,7 +270,7 @@ impl<S: WriteStorage, H: HistoryMode> VmFactory<S> for Vm<S, H> {
let inner_vm: VmInstance<S, H::Vm1_3_2Mode> =
crate::vm_1_3_2::vm_with_bootloader::init_vm_with_gas_limit(
oracle_tools,
batch_env.glue_into(),
batch_env.clone().glue_into(),
block_properties,
system_env.execution_mode.glue_into(),
&system_env.base_system_smart_contracts.clone().glue_into(),
Expand All @@ -207,6 +279,8 @@ impl<S: WriteStorage, H: HistoryMode> VmFactory<S> for Vm<S, H> {
Self {
vm: inner_vm,
system_env,
batch_env,
last_tx_compressed_bytecodes: vec![],
}
}
}
Expand Down
Loading

0 comments on commit ba9cc7b

Please sign in to comment.