Skip to content

Commit

Permalink
feat: Conditionally enable EVM emulation (#355)
Browse files Browse the repository at this point in the history
# What

- Updates `zksync-era` dependencies. Remove `zksync_state` and `zksync_node_fee_model` deps as unnecessary.
- Conditionally enables EVM emulation using `--emulate-evm` flag. For now, this requires local contracts with EVM emulation support.

# Why

- Local node can assist with EVM emulator development.
  • Loading branch information
slowli authored Oct 22, 2024
1 parent ceee937 commit 56c4e92
Show file tree
Hide file tree
Showing 17 changed files with 554 additions and 1,634 deletions.
1,285 changes: 82 additions & 1,203 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ publish = false # We don't want to pub

[dependencies]
zkevm_opcode_defs = { git = "https://github.com/matter-labs/era-zkevm_opcode_defs.git", branch = "v1.5.0" }
zksync_basic_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_node_fee_model = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_multivm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7" }
zksync_web3_decl = { git = "https://github.com/matter-labs/zksync-era.git", rev = "7ad0425e00a44e0dd1c3abf38ab2f6335c2f86e7", features = [
zksync_basic_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "cfbcc11be0826e8c55fafa84ae01b2aead25d127" }
zksync_multivm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "cfbcc11be0826e8c55fafa84ae01b2aead25d127" }
zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "cfbcc11be0826e8c55fafa84ae01b2aead25d127" }
zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "cfbcc11be0826e8c55fafa84ae01b2aead25d127" }
zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "cfbcc11be0826e8c55fafa84ae01b2aead25d127" }
zksync_web3_decl = { git = "https://github.com/matter-labs/zksync-era.git", rev = "cfbcc11be0826e8c55fafa84ae01b2aead25d127", features = [
"server",
] }
sha3 = "0.10.6"
Expand Down
2 changes: 1 addition & 1 deletion src/bootloader_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use zksync_multivm::{

use once_cell::sync::OnceCell;
use zksync_basic_types::U256;
use zksync_multivm::interface::storage::WriteStorage;
use zksync_multivm::vm_latest::{
constants::BOOTLOADER_HEAP_PAGE, BootloaderState, HistoryMode, SimpleMemory, VmTracer,
ZkSyncVmState,
};
use zksync_state::interface::WriteStorage;

/// Magic value that we put in bootloader.yul at the beginning of the debug section - to detect that
/// debugger was enabled.
Expand Down
4 changes: 4 additions & 0 deletions src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ pub struct Cli {
#[arg(long)]
pub dev_system_contracts: Option<DevSystemContracts>,

/// Enables EVM emulation. Currently, this requires local system contracts because there is no canonical EVM interpreter released yet.
#[arg(long, requires = "dev-system-contracts")]
pub emulate_evm: bool,

/// Log filter level - default: info
#[arg(long)]
pub log: Option<LogLevel>,
Expand Down
10 changes: 10 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ impl TestNodeConfig {
DevSystemContracts::Local => system_contracts::Options::Local,
};
}
if opt.emulate_evm {
assert_eq!(
self.node.system_contracts_options,
system_contracts::Options::Local,
"EVM emulation currently requires using local contracts"
);
self.node.use_evm_emulator = true;
}

// [`GasConfig`]
if let Some(l1_gas_price) = &opt.l1_gas_price {
Expand Down Expand Up @@ -140,6 +148,7 @@ pub mod node {
pub show_gas_details: ShowGasDetails,
pub resolve_hashes: bool,
pub system_contracts_options: system_contracts::Options,
pub use_evm_emulator: bool,
}

impl Default for InMemoryNodeConfig {
Expand All @@ -153,6 +162,7 @@ pub mod node {
show_gas_details: Default::default(),
resolve_hashes: Default::default(),
system_contracts_options: Default::default(),
use_evm_emulator: false,
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/deps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use zksync_types::{
H256,
};
pub mod storage_view;
use zksync_state::interface::ReadStorage;
use zksync_multivm::interface::storage::ReadStorage;

/// In-memory storage.
#[derive(Debug, Default, Clone, PartialEq)]
Expand All @@ -20,8 +20,12 @@ impl InMemoryStorage {
chain_id: L2ChainId,
bytecode_hasher: impl Fn(&[u8]) -> H256,
system_contracts_options: &crate::system_contracts::Options,
use_evm_emulator: bool,
) -> Self {
let contracts = crate::system_contracts::get_deployed_contracts(system_contracts_options);
let contracts = crate::system_contracts::get_deployed_contracts(
system_contracts_options,
use_evm_emulator,
);

let system_context_init_log = get_system_context_init_logs(chain_id);

Expand Down
2 changes: 1 addition & 1 deletion src/deps/storage_view.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{cell::RefCell, collections::HashMap, fmt, rc::Rc};

use zksync_state::interface::{ReadStorage, WriteStorage};
use zksync_multivm::interface::storage::{ReadStorage, WriteStorage};
use zksync_types::{StorageKey, StorageValue, H256};

/// `StorageView` is a buffer for `StorageLog`s between storage and transaction execution code.
Expand Down
10 changes: 6 additions & 4 deletions src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use zksync_types::{
ProtocolVersionId, StorageKey,
};

use zksync_state::interface::ReadStorage;
use zksync_multivm::interface::storage::ReadStorage;
use zksync_utils::{bytecode::hash_bytecode, h256_to_u256};

use zksync_web3_decl::{
Expand Down Expand Up @@ -124,6 +124,7 @@ impl<S: ForkSource> ForkStorage<S> {
pub fn new(
fork: Option<ForkDetails>,
system_contracts_options: &system_contracts::Options,
use_evm_emulator: bool,
) -> Self {
let chain_id = fork
.as_ref()
Expand All @@ -137,6 +138,7 @@ impl<S: ForkSource> ForkStorage<S> {
chain_id,
hash_bytecode,
system_contracts_options,
use_evm_emulator,
),
value_read_cache: Default::default(),
fork,
Expand Down Expand Up @@ -723,7 +725,7 @@ impl ForkDetails {
#[cfg(test)]
mod tests {
use zksync_basic_types::{AccountTreeId, L1BatchNumber, H256};
use zksync_state::interface::ReadStorage;
use zksync_multivm::interface::storage::ReadStorage;
use zksync_types::{api::TransactionVariant, StorageKey};

use crate::config::cache::CacheConfig;
Expand Down Expand Up @@ -769,11 +771,11 @@ mod tests {
};

let mut fork_storage: ForkStorage<testing::ExternalStorage> =
ForkStorage::new(Some(fork_details), &options);
ForkStorage::new(Some(fork_details), &options, false);

assert!(fork_storage.is_write_initial(&never_written_key));
assert!(!fork_storage.is_write_initial(&key_with_some_value));
// This is the current limitation of the sytem. In theory, this should return false - as the value was written, but we don't have the API to the
// This is the current limitation of the system. In theory, this should return false - as the value was written, but we don't have the API to the
// backend to get this information.
assert!(fork_storage.is_write_initial(&key_with_value_0));

Expand Down
2 changes: 1 addition & 1 deletion src/node/call_error_tracer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use zksync_multivm::interface::storage::WriteStorage;
use zksync_multivm::{
tracers::dynamic::vm_1_5_0::DynTracer,
vm_latest::{HistoryMode, SimpleMemory, VmTracer},
Expand All @@ -6,7 +7,6 @@ use zksync_multivm::{
vm_state::ErrorFlags,
},
};
use zksync_state::interface::WriteStorage;

pub struct CallErrorTracer {}

Expand Down
15 changes: 5 additions & 10 deletions src/node/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,24 +158,19 @@ impl<S: ForkSource + std::fmt::Debug + Clone + Send + Sync + 'static> DebugNames
)))
})?;

let mut l2_tx = match L2Tx::from_request(request.into(), MAX_TX_SIZE) {
Ok(tx) => tx,
Err(e) => {
let error = Web3Error::SerializationError(e);
return Err(into_jsrpc_error(error));
}
};
let system_contracts = inner.system_contracts.contracts_for_l2_call();
let allow_no_target = system_contracts.evm_emulator.is_some();
let mut l2_tx = L2Tx::from_request(request.into(), MAX_TX_SIZE, allow_no_target)
.map_err(|err| into_jsrpc_error(Web3Error::SerializationError(err)))?;
let execution_mode = zksync_multivm::interface::TxExecutionMode::EthCall;
let storage = StorageView::new(&inner.fork_storage).into_rc_ptr();

let bootloader_code = inner.system_contracts.contracts_for_l2_call();

// init vm
let (mut l1_batch_env, _block_context) = inner.create_l1_batch_env(storage.clone());

// update the enforced_base_fee within l1_batch_env to match the logic in zksync_core
l1_batch_env.enforced_base_fee = Some(l2_tx.common_data.fee.max_fee_per_gas.as_u64());
let system_env = inner.create_system_env(bootloader_code.clone(), execution_mode);
let system_env = inner.create_system_env(system_contracts.clone(), execution_mode);
let mut vm: Vm<_, HistoryDisabled> = Vm::new(l1_batch_env, system_env, storage);

// We must inject *some* signature (otherwise bootloader code fails to generate hash).
Expand Down
Loading

0 comments on commit 56c4e92

Please sign in to comment.