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(multivm): Remove lifetime from multivm #218

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
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
Loading