Skip to content

Commit

Permalink
feat(multivm): Remove lifetime from multivm (#218)
Browse files Browse the repository at this point in the history
# What ❔

Remove lifetime from multivm. Update zk_evm 1.3.1 to the version without
lifetime

## Why ❔

For better compatibility with the new VM versions, i've updated zk-evm
by removing lifetime from vm state

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.

---------

Signed-off-by: Danil <deniallugo@gmail.com>
  • Loading branch information
Deniallugo committed Oct 13, 2023
1 parent 86e2794 commit 7eda27c
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 158 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

31 changes: 25 additions & 6 deletions core/lib/multivm/src/glue/init_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,27 @@ use vm_latest::{L1BatchEnv, SystemEnv};
use zksync_state::ReadStorage;
use zksync_utils::h256_to_u256;

impl<'a, S: ReadStorage, H: HistoryMode> VmInstance<'a, S, H> {
impl<S: ReadStorage, H: HistoryMode> VmInstance<S, H> {
pub fn new(
l1_batch_env: L1BatchEnv,
system_env: SystemEnv,
initial_version: &'a mut VmInstanceData<S, H>,
initial_version: VmInstanceData<S, H>,
) -> Self {
match initial_version {
VmInstanceData::M5(data) => {
let oracle_tools =
vm_m5::OracleTools::new(data.storage_view.clone(), data.sub_version);
let block_properties = vm_m5::zk_evm::block_properties::BlockProperties {
default_aa_code_hash: h256_to_u256(
system_env.base_system_smart_contracts.default_aa.hash,
),
zkporter_is_available: false,
};
let inner_vm = vm_m5::vm_with_bootloader::init_vm_with_gas_limit(
data.sub_version,
data.oracle_tools.m5(),
oracle_tools,
l1_batch_env.glue_into(),
data.block_properties.m5(),
block_properties,
system_env.execution_mode.glue_into(),
&system_env.base_system_smart_contracts.clone().glue_into(),
system_env.gas_limit,
Expand All @@ -30,11 +38,22 @@ impl<'a, S: ReadStorage, H: HistoryMode> VmInstance<'a, S, H> {
}
}
VmInstanceData::M6(data) => {
let oracle_tools = vm_m6::OracleTools::new(
data.storage_view.clone(),
data.history_mode.glue_into(),
);
let block_properties = vm_m6::zk_evm::block_properties::BlockProperties {
default_aa_code_hash: h256_to_u256(
system_env.base_system_smart_contracts.default_aa.hash,
),
zkporter_is_available: false,
};

let inner_vm = vm_m6::vm_with_bootloader::init_vm_with_gas_limit(
data.sub_version,
data.oracle_tools.m6(),
oracle_tools,
l1_batch_env.glue_into(),
data.block_properties.m6(),
block_properties,
system_env.execution_mode.glue_into(),
&system_env.base_system_smart_contracts.clone().glue_into(),
system_env.gas_limit,
Expand Down
90 changes: 26 additions & 64 deletions core/lib/multivm/src/vm_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,29 @@ use vm_latest::{
use zksync_state::{ReadStorage, StoragePtr, StorageView};
use zksync_types::VmVersion;
use zksync_utils::bytecode::{hash_bytecode, CompressedBytecodeInfo};
use zksync_utils::h256_to_u256;

use crate::glue::history_mode::HistoryMode;
use crate::glue::tracer::MultivmTracer;
use crate::glue::GlueInto;
use crate::{BlockProperties, OracleTools};

pub struct VmInstance<'a, S: ReadStorage, H: HistoryMode> {
pub(crate) vm: VmInstanceVersion<'a, S, H>,
pub struct VmInstance<S: ReadStorage, H: HistoryMode> {
pub(crate) vm: VmInstanceVersion<S, H>,
pub(crate) system_env: SystemEnv,
pub(crate) last_tx_compressed_bytecodes: Vec<CompressedBytecodeInfo>,
}

#[derive(Debug)]
pub(crate) enum VmInstanceVersion<'a, S: ReadStorage, H: HistoryMode> {
VmM5(Box<vm_m5::VmInstance<'a, StorageView<S>>>),
VmM6(Box<vm_m6::VmInstance<'a, StorageView<S>, H::VmM6Mode>>),
pub(crate) enum VmInstanceVersion<S: ReadStorage, H: HistoryMode> {
VmM5(Box<vm_m5::VmInstance<StorageView<S>>>),
VmM6(Box<vm_m6::VmInstance<StorageView<S>, H::VmM6Mode>>),
Vm1_3_2(Box<vm_1_3_2::VmInstance<StorageView<S>, H::Vm1_3_2Mode>>),
VmVirtualBlocks(Box<vm_virtual_blocks::Vm<StorageView<S>, H::VmVirtualBlocksMode>>),
VmVirtualBlocksRefundsEnhancement(
Box<vm_latest::Vm<StorageView<S>, H::VmVirtualBlocksRefundsEnhancement>>,
),
}

impl<'a, S: ReadStorage, H: HistoryMode> VmInstance<'a, S, H> {
impl<S: ReadStorage, H: HistoryMode> VmInstance<S, H> {
/// Push tx into memory for the future execution
pub fn push_transaction(&mut self, tx: &zksync_types::Transaction) {
match &mut self.vm {
Expand Down Expand Up @@ -446,15 +444,15 @@ impl<'a, S: ReadStorage, H: HistoryMode> VmInstance<'a, S, H> {
}

pub struct M5NecessaryData<S: ReadStorage, H: HistoryMode> {
pub oracle_tools: OracleTools<S, H>,
pub block_properties: BlockProperties,
pub storage_view: StoragePtr<StorageView<S>>,
pub sub_version: vm_m5::vm::MultiVMSubversion,
pub history_mode: H,
}

pub struct M6NecessaryData<S: ReadStorage, H: HistoryMode> {
pub oracle_tools: OracleTools<S, H>,
pub block_properties: BlockProperties,
pub storage_view: StoragePtr<StorageView<S>>,
pub sub_version: vm_m6::vm::MultiVMSubversion,
pub history_mode: H,
}

pub struct Vm1_3_2NecessaryData<S: ReadStorage, H: HistoryMode> {
Expand All @@ -463,7 +461,7 @@ pub struct Vm1_3_2NecessaryData<S: ReadStorage, H: HistoryMode> {
}

pub struct VmVirtualBlocksNecessaryData<S: ReadStorage, H: HistoryMode> {
pub storage_view: zksync_state::StoragePtr<StorageView<S>>,
pub storage_view: StoragePtr<StorageView<S>>,
pub history_mode: H,
}

Expand All @@ -477,25 +475,26 @@ pub enum VmInstanceData<S: ReadStorage, H: HistoryMode> {

impl<S: ReadStorage, H: HistoryMode> VmInstanceData<S, H> {
fn m5(
oracle_tools: OracleTools<S, H>,
block_properties: BlockProperties,
storage_view: StoragePtr<StorageView<S>>,
sub_version: vm_m5::vm::MultiVMSubversion,
history_mode: H,
) -> Self {
Self::M5(M5NecessaryData {
oracle_tools,
block_properties,
storage_view,
sub_version,
history_mode,
})
}

fn m6(
oracle_tools: OracleTools<S, H>,
block_properties: BlockProperties,
storage_view: StoragePtr<StorageView<S>>,
sub_version: vm_m6::vm::MultiVMSubversion,
history_mode: H,
) -> Self {
Self::M6(M6NecessaryData {
oracle_tools,
block_properties,
storage_view,
sub_version,
history_mode,
})
}

Expand Down Expand Up @@ -527,64 +526,27 @@ impl<S: ReadStorage, H: HistoryMode> VmInstanceData<S, H> {
) -> Self {
let protocol_version = system_env.version;
let vm_version: VmVersion = protocol_version.into();
Self::new_for_specific_vm_version(storage_view, system_env, history, vm_version)
Self::new_for_specific_vm_version(storage_view, history, vm_version)
}

// In api we support only subset of vm versions, so we need to create vm instance for specific version
pub fn new_for_specific_vm_version(
storage_view: StoragePtr<StorageView<S>>,
system_env: &SystemEnv,
history: H,
vm_version: VmVersion,
) -> Self {
match vm_version {
VmVersion::M5WithoutRefunds => {
let oracle_tools = OracleTools::new(vm_version, storage_view, history);
let block_properties = BlockProperties::new(
vm_version,
h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash),
);
VmInstanceData::m5(
oracle_tools,
block_properties,
vm_m5::vm::MultiVMSubversion::V1,
)
VmInstanceData::m5(storage_view, vm_m5::vm::MultiVMSubversion::V1, history)
}
VmVersion::M5WithRefunds => {
let oracle_tools = OracleTools::new(vm_version, storage_view, history);
let block_properties = BlockProperties::new(
vm_version,
h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash),
);
VmInstanceData::m5(
oracle_tools,
block_properties,
vm_m5::vm::MultiVMSubversion::V2,
)
VmInstanceData::m5(storage_view, vm_m5::vm::MultiVMSubversion::V2, history)
}
VmVersion::M6Initial => {
let oracle_tools = OracleTools::new(vm_version, storage_view, history);
let block_properties = BlockProperties::new(
vm_version,
h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash),
);
VmInstanceData::m6(
oracle_tools,
block_properties,
vm_m6::vm::MultiVMSubversion::V1,
)
VmInstanceData::m6(storage_view, vm_m6::vm::MultiVMSubversion::V1, history)
}
VmVersion::M6BugWithCompressionFixed => {
let oracle_tools = OracleTools::new(vm_version, storage_view, history);
let block_properties = BlockProperties::new(
vm_version,
h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash),
);
VmInstanceData::m6(
oracle_tools,
block_properties,
vm_m6::vm::MultiVMSubversion::V2,
)
VmInstanceData::m6(storage_view, vm_m6::vm::MultiVMSubversion::V2, history)
}
VmVersion::Vm1_3_2 => VmInstanceData::vm1_3_2(storage_view, history),
VmVersion::VmVirtualBlocks => VmInstanceData::vm_virtual_blocks(storage_view, history),
Expand All @@ -595,7 +557,7 @@ impl<S: ReadStorage, H: HistoryMode> VmInstanceData<S, H> {
}
}

impl<S: ReadStorage> VmInstance<'_, S, vm_latest::HistoryEnabled> {
impl<S: ReadStorage> VmInstance<S, vm_latest::HistoryEnabled> {
pub fn make_snapshot(&mut self) {
match &mut self.vm {
VmInstanceVersion::VmM5(vm) => vm.save_current_vm_as_snapshot(),
Expand Down
11 changes: 3 additions & 8 deletions core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub(super) fn apply_vm_in_sandbox<T>(
connection_pool: &ConnectionPool,
tx: Transaction,
block_args: BlockArgs,
apply: impl FnOnce(&mut VmInstance<'_, PostgresStorage<'_>, HistoryDisabled>, Transaction) -> T,
apply: impl FnOnce(&mut VmInstance<PostgresStorage<'_>, HistoryDisabled>, Transaction) -> T,
) -> T {
let stage_started_at = Instant::now();
let span = tracing::debug_span!("initialization").entered();
Expand Down Expand Up @@ -197,17 +197,12 @@ pub(super) fn apply_vm_in_sandbox<T>(
};

let storage_view = storage_view.to_rc_ptr();
let mut initial_version = VmInstanceData::new_for_specific_vm_version(
let initial_version = VmInstanceData::new_for_specific_vm_version(
storage_view.clone(),
&system_env,
HistoryDisabled,
protocol_version.into_api_vm_version(),
);
let mut vm = Box::new(VmInstance::new(
l1_batch_env,
system_env,
&mut initial_version,
));
let mut vm = Box::new(VmInstance::new(l1_batch_env, system_env, initial_version));

metrics::histogram!("api.web3.sandbox", stage_started_at.elapsed(), "stage" => "initialization");
span.exit();
Expand Down
17 changes: 8 additions & 9 deletions core/lib/zksync_core/src/state_keeper/batch_executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,8 @@ impl BatchExecutor {

let storage_view = StorageView::new(secondary_storage).to_rc_ptr();

let mut instance_data =
VmInstanceData::new(storage_view.clone(), &system_env, HistoryEnabled);
let mut vm = VmInstance::new(l1_batch_params, system_env, &mut instance_data);
let instance_data = VmInstanceData::new(storage_view.clone(), &system_env, HistoryEnabled);
let mut vm = VmInstance::new(l1_batch_params, system_env, instance_data);

while let Some(cmd) = self.commands.blocking_recv() {
match cmd {
Expand Down Expand Up @@ -344,7 +343,7 @@ impl BatchExecutor {
fn execute_tx<S: ReadStorage>(
&self,
tx: &Transaction,
vm: &mut VmInstance<'_, S, HistoryEnabled>,
vm: &mut VmInstance<S, HistoryEnabled>,
) -> TxExecutionResult {
// Save pre-`execute_next_tx` VM snapshot.
vm.make_snapshot();
Expand Down Expand Up @@ -414,7 +413,7 @@ impl BatchExecutor {
}
}

fn rollback_last_tx<S: ReadStorage>(&self, vm: &mut VmInstance<'_, S, HistoryEnabled>) {
fn rollback_last_tx<S: ReadStorage>(&self, vm: &mut VmInstance<S, HistoryEnabled>) {
let stage_started_at = Instant::now();
vm.rollback_to_the_latest_snapshot();
metrics::histogram!(
Expand All @@ -427,14 +426,14 @@ impl BatchExecutor {
fn start_next_miniblock<S: ReadStorage>(
&self,
l2_block_env: L2BlockEnv,
vm: &mut VmInstance<'_, S, HistoryEnabled>,
vm: &mut VmInstance<S, HistoryEnabled>,
) {
vm.start_new_l2_block(l2_block_env);
}

fn finish_batch<S: ReadStorage>(
&self,
vm: &mut VmInstance<'_, S, HistoryEnabled>,
vm: &mut VmInstance<S, HistoryEnabled>,
) -> FinishedL1Batch {
// The vm execution was paused right after the last transaction was executed.
// There is some post-processing work that the VM needs to do before the block is fully processed.
Expand All @@ -452,7 +451,7 @@ impl BatchExecutor {
fn execute_tx_in_vm<S: ReadStorage>(
&self,
tx: &Transaction,
vm: &mut VmInstance<'_, S, HistoryEnabled>,
vm: &mut VmInstance<S, HistoryEnabled>,
) -> (
VmExecutionResultAndLogs,
Vec<CompressedBytecodeInfo>,
Expand Down Expand Up @@ -512,7 +511,7 @@ impl BatchExecutor {

fn dryrun_block_tip<S: ReadStorage>(
&self,
vm: &mut VmInstance<'_, S, HistoryEnabled>,
vm: &mut VmInstance<S, HistoryEnabled>,
) -> (VmExecutionResultAndLogs, ExecutionMetricsForCriteria) {
let started_at = Instant::now();
let mut stage_started_at = Instant::now();
Expand Down
2 changes: 1 addition & 1 deletion core/multivm_deps/vm_m5/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ zksync_config = { path = "../../lib/config" }
zksync_state = { path = "../../lib/state" }
zksync_storage = { path = "../../lib/storage" }

zk_evm = { git = "https://github.com/matter-labs/era-zk_evm.git", tag = "v1.3.1-rc0" }
zk_evm = { git = "https://github.com/matter-labs/era-zk_evm.git", tag = "v1.3.1-rc1" }
zksync_contracts = { path = "../../lib/contracts" }

hex = "0.4"
Expand Down
2 changes: 1 addition & 1 deletion core/multivm_deps/vm_m5/src/pubdata_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use zksync_types::zkevm_test_harness::witness::sort_storage_access::sort_storage
use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS};
use zksync_utils::bytecode::bytecode_len_in_bytes;

impl<'a, S: Storage> VmInstance<'a, S> {
impl<S: Storage> VmInstance<S> {
pub fn pubdata_published(&self, from_timestamp: Timestamp) -> u32 {
let storage_writes_pubdata_published = self.pubdata_published_for_writes(from_timestamp);

Expand Down
2 changes: 1 addition & 1 deletion core/multivm_deps/vm_m5/src/refunds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use zk_evm::aux_structures::Timestamp;
use zksync_types::U256;
use zksync_utils::ceil_div_u256;

impl<'a, S: Storage> VmInstance<'a, S> {
impl<S: Storage> VmInstance<S> {
pub(crate) fn tx_body_refund(
&self,
from_timestamp: Timestamp,
Expand Down
2 changes: 1 addition & 1 deletion core/multivm_deps/vm_m5/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub struct VmInstanceInnerState {
local_state: VmLocalState,
}

impl<'a, S: Storage> VmInstance<'a, S> {
impl<S: Storage> VmInstance<S> {
/// This method is mostly to be used in tests. It dumps the inner state of all the oracles and the VM itself.
pub fn dump_inner_state(&self) -> VmInstanceInnerState {
let event_sink = self.state.event_sink.clone();
Expand Down

0 comments on commit 7eda27c

Please sign in to comment.