Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vm): Split old and new VM implementations #2915

Merged
merged 19 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/lib/multivm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use crate::{
vm_1_3_2, vm_1_4_1, vm_1_4_2, vm_boojum_integration, vm_fast, vm_latest, vm_m5, vm_m6,
vm_refunds_enhancement, vm_virtual_blocks,
},
vm_instance::VmInstance,
vm_instance::{FastVmInstance, LegacyVmInstance},
};

mod glue;
Expand Down
33 changes: 19 additions & 14 deletions core/lib/multivm/src/versions/shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ use crate::{
};

#[derive(Debug)]
pub struct ShadowVm<S, T> {
pub struct ShadowVm<S, T, Tr> {
main: T,
shadow: vm_fast::Vm<ImmutableStorageView<S>>,
shadow: vm_fast::Vm<ImmutableStorageView<S>, Tr>,
}

impl<S, T> VmFactory<StorageView<S>> for ShadowVm<S, T>
impl<S, T, Tr> VmFactory<StorageView<S>> for ShadowVm<S, T, Tr>
where
S: ReadStorage,
T: VmFactory<StorageView<S>>,
Tr: vm_fast::Tracer + Default + 'static,
{
fn new(
batch_env: L1BatchEnv,
Expand All @@ -39,12 +40,13 @@ where
}
}

impl<S, T> VmInterface for ShadowVm<S, T>
impl<S, T, Tr> VmInterface for ShadowVm<S, T, Tr>
where
S: ReadStorage,
T: VmInterface,
Tr: vm_fast::Tracer + Default + 'static,
{
type TracerDispatcher = T::TracerDispatcher;
type TracerDispatcher<'a> = (T::TracerDispatcher<'a>, &'a mut Tr);

fn push_transaction(&mut self, tx: Transaction) {
self.shadow.push_transaction(tx.clone());
Expand All @@ -53,11 +55,11 @@ where

fn inspect(
&mut self,
dispatcher: Self::TracerDispatcher,
(main_tracer, shadow_tracer): Self::TracerDispatcher<'_>,
execution_mode: VmExecutionMode,
) -> VmExecutionResultAndLogs {
let shadow_result = self.shadow.inspect((), execution_mode);
let main_result = self.main.inspect(dispatcher, execution_mode);
let shadow_result = self.shadow.inspect(shadow_tracer, execution_mode);
let main_result = self.main.inspect(main_tracer, execution_mode);
let mut errors = DivergenceErrors::default();
errors.check_results_match(&main_result, &shadow_result);
errors
Expand All @@ -74,19 +76,21 @@ where

fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
(main_tracer, shadow_tracer): Self::TracerDispatcher<'_>,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) {
let tx_hash = tx.hash();
let main_result = self.main.inspect_transaction_with_bytecode_compression(
tracer,
main_tracer,
tx.clone(),
with_compression,
);
let shadow_result =
self.shadow
.inspect_transaction_with_bytecode_compression((), tx, with_compression);
let shadow_result = self.shadow.inspect_transaction_with_bytecode_compression(
shadow_tracer,
tx,
with_compression,
);
let mut errors = DivergenceErrors::default();
errors.check_results_match(&main_result.1, &shadow_result.1);
errors
Expand Down Expand Up @@ -283,10 +287,11 @@ impl UniqueStorageLogs {
}
}

impl<S, T> VmInterfaceHistoryEnabled for ShadowVm<S, T>
impl<S, T, Tr> VmInterfaceHistoryEnabled for ShadowVm<S, T, Tr>
where
S: ReadStorage,
T: VmInterfaceHistoryEnabled,
Tr: vm_fast::Tracer + Default + 'static,
{
fn make_snapshot(&mut self) {
self.shadow.make_snapshot();
Expand Down
6 changes: 3 additions & 3 deletions core/lib/multivm/src/versions/vm_1_3_2/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Vm<S: WriteStorage, H: HistoryMode> {
}

impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher;
type TracerDispatcher<'a> = TracerDispatcher;

fn push_transaction(&mut self, tx: Transaction) {
crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory(
Expand All @@ -36,7 +36,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {

fn inspect(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
execution_mode: VmExecutionMode,
) -> VmExecutionResultAndLogs {
if let Some(storage_invocations) = tracer.storage_invocations {
Expand Down Expand Up @@ -80,7 +80,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {

fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) {
Expand Down
6 changes: 3 additions & 3 deletions core/lib/multivm/src/versions/vm_1_4_1/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
}

impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::Vm1_4_1>;
type TracerDispatcher<'a> = TracerDispatcher<S, H::Vm1_4_1>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
Expand All @@ -90,7 +90,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
/// Execute VM with custom tracers.
fn inspect(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
execution_mode: VmExecutionMode,
) -> VmExecutionResultAndLogs {
self.inspect_inner(tracer, execution_mode, None)
Expand All @@ -102,7 +102,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {

fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) {
Expand Down
6 changes: 3 additions & 3 deletions core/lib/multivm/src/versions/vm_1_4_2/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
}

impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::Vm1_4_2>;
type TracerDispatcher<'a> = TracerDispatcher<S, H::Vm1_4_2>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
Expand All @@ -90,7 +90,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
/// Execute VM with custom tracers.
fn inspect(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
execution_mode: VmExecutionMode,
) -> VmExecutionResultAndLogs {
self.inspect_inner(tracer, execution_mode, None)
Expand All @@ -102,7 +102,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {

fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) {
Expand Down
6 changes: 3 additions & 3 deletions core/lib/multivm/src/versions/vm_boojum_integration/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
}

impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::VmBoojumIntegration>;
type TracerDispatcher<'a> = TracerDispatcher<S, H::VmBoojumIntegration>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
Expand All @@ -90,7 +90,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
/// Execute VM with custom tracers.
fn inspect(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
execution_mode: VmExecutionMode,
) -> VmExecutionResultAndLogs {
self.inspect_inner(tracer, execution_mode)
Expand All @@ -103,7 +103,7 @@ impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
/// Inspect transaction with optional bytecode compression.
fn inspect_transaction_with_bytecode_compression(
&mut self,
tracer: Self::TracerDispatcher,
tracer: Self::TracerDispatcher<'_>,
tx: Transaction,
with_compression: bool,
) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) {
Expand Down
2 changes: 1 addition & 1 deletion core/lib/multivm/src/versions/vm_fast/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
utils::bytecode,
};

impl<S: ReadStorage> Vm<S> {
impl<S: ReadStorage, Tr> Vm<S, Tr> {
/// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown.
pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool {
self.bootloader_state
Expand Down
4 changes: 2 additions & 2 deletions core/lib/multivm/src/versions/vm_fast/circuits_tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use zksync_vm_interface::CircuitStatistic;
use crate::vm_latest::tracers::circuits_capacity::*;

#[derive(Debug, Default, Clone, PartialEq)]
pub(crate) struct CircuitsTracer {
pub struct CircuitsTracer {
main_vm_cycles: u32,
ram_permutation_cycles: u32,
storage_application_cycles: u32,
Expand Down Expand Up @@ -124,7 +124,7 @@ impl Tracer for CircuitsTracer {
}

impl CircuitsTracer {
pub(crate) fn circuit_statistic(&self) -> CircuitStatistic {
pub fn circuit_statistic(&self) -> CircuitStatistic {
CircuitStatistic {
main_vm: self.main_vm_cycles as f32 / GEOMETRY_CONFIG.cycles_per_vm_snapshot as f32,
ram_permutation: self.ram_permutation_cycles as f32
Expand Down
4 changes: 3 additions & 1 deletion core/lib/multivm/src/versions/vm_fast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
pub use self::vm::Vm;
pub use zksync_vm2::Tracer;

pub use self::{circuits_tracer::CircuitsTracer, vm::Vm};

mod bootloader_state;
mod bytecode;
Expand Down
5 changes: 3 additions & 2 deletions core/lib/multivm/src/versions/vm_fast/tests/circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use zksync_types::{Address, Execute, U256};

use super::tester::VmTesterBuilder;
use crate::{
interface::{TxExecutionMode, VmExecutionMode, VmInterface},
interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt},
vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT,
};

Expand All @@ -29,7 +29,8 @@ fn test_circuits() {
None,
);
vm.vm.push_transaction(tx);
let res = vm.vm.inspect((), VmExecutionMode::OneTx);
let res = vm.vm.execute(VmExecutionMode::OneTx);
assert!(!res.result.is_failed(), "{res:#?}");

let s = res.statistics.circuit_statistic;
// Check `circuit_statistic`.
Expand Down
4 changes: 2 additions & 2 deletions core/lib/multivm/src/versions/vm_fast/tests/code_oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256};
use crate::{
interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt},
vm_fast::{
circuits_tracer::CircuitsTracer,
tests::{
tester::{get_empty_storage, VmTesterBuilder},
utils::{load_precompiles_contract, read_precompiles_contract, read_test_contract},
},
CircuitsTracer,
},
};

Expand Down Expand Up @@ -212,7 +212,7 @@ fn refunds_in_code_oracle() {
if decommit {
let (_, is_fresh) = vm.vm.inner.world_diff_mut().decommit_opcode(
&mut vm.vm.world,
&mut CircuitsTracer::default(),
&mut ((), CircuitsTracer::default()),
h256_to_u256(normal_zkevm_bytecode_hash),
);
assert!(is_fresh);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ struct ProxyCounterData {
counter_bytecode_hash: U256,
}

fn execute_proxy_counter(gas: u32) -> (VmTester, ProxyCounterData, VmExecutionResultAndLogs) {
fn execute_proxy_counter(gas: u32) -> (VmTester<()>, ProxyCounterData, VmExecutionResultAndLogs) {
let counter_bytecode = inflated_counter_bytecode();
let counter_bytecode_hash = h256_to_u256(hash_bytecode(&counter_bytecode));
let counter_address = Address::repeat_byte(0x23);
Expand Down
21 changes: 13 additions & 8 deletions core/lib/multivm/src/versions/vm_fast/tests/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use zksync_types::{Address, Execute};

use super::{tester::VmTesterBuilder, utils::read_precompiles_contract};
use crate::{
interface::{TxExecutionMode, VmExecutionMode, VmInterface},
interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt},
vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT,
};

Expand Down Expand Up @@ -36,7 +36,8 @@ fn test_keccak() {
None,
);
vm.vm.push_transaction(tx);
let exec_result = vm.vm.inspect((), VmExecutionMode::OneTx);

let exec_result = vm.vm.execute(VmExecutionMode::OneTx);
assert!(!exec_result.result.is_failed(), "{exec_result:#?}");

let keccak_count = exec_result.statistics.circuit_statistic.keccak256
Expand Down Expand Up @@ -73,11 +74,13 @@ fn test_sha256() {
None,
);
vm.vm.push_transaction(tx);
let exec_result = vm.vm.inspect((), VmExecutionMode::OneTx);

let exec_result = vm.vm.execute(VmExecutionMode::OneTx);
assert!(!exec_result.result.is_failed(), "{exec_result:#?}");

let sha_count = exec_result.statistics.circuit_statistic.sha256
* get_geometry_config().cycles_per_sha256_circuit as f32;
let circuit_statistic = exec_result.statistics.circuit_statistic;
slowli marked this conversation as resolved.
Show resolved Hide resolved
let sha_count =
circuit_statistic.sha256 * get_geometry_config().cycles_per_sha256_circuit as f32;
assert!(sha_count >= 1000.0, "{sha_count}");
}

Expand All @@ -103,10 +106,12 @@ fn test_ecrecover() {
None,
);
vm.vm.push_transaction(tx);
let exec_result = vm.vm.inspect((), VmExecutionMode::OneTx);

let exec_result = vm.vm.execute(VmExecutionMode::OneTx);
assert!(!exec_result.result.is_failed(), "{exec_result:#?}");

let ecrecover_count = exec_result.statistics.circuit_statistic.ecrecover
* get_geometry_config().cycles_per_ecrecover_circuit as f32;
let circuit_statistic = exec_result.statistics.circuit_statistic;
let ecrecover_count =
circuit_statistic.ecrecover * get_geometry_config().cycles_per_ecrecover_circuit as f32;
assert!((ecrecover_count - 1.0).abs() < 1e-4, "{ecrecover_count}");
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
},
};

impl VmTester {
impl VmTester<()> {
pub(crate) fn get_eth_balance(&mut self, address: Address) -> U256 {
let key = storage_key_for_standard_token_balance(
AccountTreeId::new(L2_BASE_TOKEN_ADDRESS),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use super::VmTester;
use crate::{
interface::{
storage::ReadStorage, CurrentExecutionState, ExecutionResult, Halt, TxRevertReason,
VmExecutionMode, VmExecutionResultAndLogs, VmInterface, VmInterfaceExt,
VmInterfaceHistoryEnabled, VmRevertReason,
VmExecutionMode, VmExecutionResultAndLogs, VmInterface, VmInterfaceHistoryEnabled,
VmRevertReason,
},
vm_fast::Vm,
};
Expand Down Expand Up @@ -217,15 +217,15 @@ impl<S: ReadStorage> Vm<S> {
}
}

impl VmTester {
impl VmTester<()> {
pub(crate) fn execute_and_verify_txs(
&mut self,
txs: &[TransactionTestInfo],
) -> CurrentExecutionState {
for tx_test_info in txs {
self.execute_tx_and_verify(tx_test_info.clone());
}
self.vm.execute(VmExecutionMode::Batch);
self.vm.inspect(&mut (), VmExecutionMode::Batch);
slowli marked this conversation as resolved.
Show resolved Hide resolved
let mut state = self.vm.get_current_execution_state();
state.used_contract_hashes.sort();
state
Expand All @@ -238,7 +238,7 @@ impl VmTester {
self.vm.make_snapshot();
let inner_state_before = self.vm.dump_state();
self.vm.push_transaction(tx_test_info.tx.clone());
let result = self.vm.execute(VmExecutionMode::OneTx);
let result = self.vm.inspect(&mut (), VmExecutionMode::OneTx);
tx_test_info.verify_result(&result);
if tx_test_info.should_rollback() {
self.vm.rollback_to_the_latest_snapshot();
Expand Down
Loading
Loading