Skip to content

Commit 8419488

Browse files
authored
feat: enable evm interpreter (#1167)
* support evm interpreter * require --zksync arg for --zk-evm-intepreter
1 parent 9a3a6b7 commit 8419488

File tree

28 files changed

+362
-129
lines changed

28 files changed

+362
-129
lines changed

crates/chisel/src/executor.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,10 @@ impl SessionSource {
212212
Some(backend) => backend,
213213
None => {
214214
let fork = self.config.evm_opts.get_fork(&self.config.foundry_config, env.clone());
215-
let backend = Backend::spawn(fork, strategy.runner.new_backend_strategy())?;
215+
let backend = Backend::spawn(
216+
fork,
217+
strategy.runner.new_backend_strategy(strategy.context.as_ref()),
218+
)?;
216219
self.config.backend = Some(backend.clone());
217220
backend
218221
}

crates/cli/src/opts/build/zksync.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ pub struct ZkSyncArgs {
3131
)]
3232
pub startup: Option<bool>,
3333

34+
/// Enable zkVM EVM intepreter
35+
#[clap(
36+
long = "zk-evm-interpreter",
37+
display_order = 0,
38+
value_name = "ENABLE_ZKVM_EVM_INTERPRETER",
39+
num_args = 0..=1,
40+
require_equals = true,
41+
default_missing_value = "false",
42+
requires = "startup",
43+
)]
44+
pub evm_interpreter: Option<bool>,
45+
3446
#[clap(
3547
help = "Solc compiler path to use when compiling with zksolc",
3648
long = "zk-solc-path",
@@ -156,6 +168,7 @@ impl ZkSyncArgs {
156168

157169
set_if_some!(self.compile, zksync.compile);
158170
set_if_some!(self.startup, zksync.startup);
171+
set_if_some!(self.evm_interpreter, zksync.evm_interpreter);
159172
set_if_some!(self.solc_path.clone(), zksync.solc_path);
160173
set_if_some!(self.enable_eravm_extensions, zksync.enable_eravm_extensions);
161174
set_if_some!(self.llvm_options.clone(), zksync.llvm_options);

crates/cli/src/utils/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,13 @@ pub fn get_provider(config: &Config) -> Result<RetryProvider> {
115115

116116
pub fn get_executor_strategy(config: &Config) -> ExecutorStrategy {
117117
if config.zksync.should_compile() {
118-
info!("using zksync strategy");
119-
ExecutorStrategy::new_zksync()
118+
if config.zksync.evm_interpreter {
119+
info!("using zksync strategy (EVM-interpreter)");
120+
} else {
121+
info!("using zksync strategy");
122+
}
123+
124+
ExecutorStrategy::new_zksync(config.zksync.evm_interpreter)
120125
} else {
121126
info!("using evm strategy");
122127
ExecutorStrategy::new_evm()

crates/config/src/zksync.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ pub struct ZkSyncConfig {
3939
/// Start VM in zkVM mode
4040
pub startup: bool,
4141

42+
/// Whether to use EVM interpreter.
43+
pub evm_interpreter: bool,
44+
4245
/// The zkSolc instance to use if any.
4346
pub zksolc: Option<SolcReq>,
4447

@@ -87,6 +90,7 @@ impl Default for ZkSyncConfig {
8790
Self {
8891
compile: false,
8992
startup: false,
93+
evm_interpreter: false,
9094
zksolc: Default::default(),
9195
solc_path: Default::default(),
9296
hash_type: Default::default(),
@@ -110,6 +114,12 @@ impl ZkSyncConfig {
110114
self.compile && self.startup
111115
}
112116

117+
/// Returns true if zk mode is enabled, if tests should be run in zk mode, and if EVM
118+
/// interpreter is enabled.
119+
pub fn run_in_zk_evm_interpreter_mode(&self) -> bool {
120+
self.run_in_zk_mode() && self.evm_interpreter
121+
}
122+
113123
/// Returns true if contracts should be compiled for zk
114124
pub fn should_compile(&self) -> bool {
115125
self.compile

crates/evm/evm/src/executors/strategy.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub trait ExecutorStrategyRunner: Debug + Send + Sync + ExecutorStrategyExt {
124124
inspector: &mut InspectorStack,
125125
) -> Result<ResultAndState>;
126126

127-
fn new_backend_strategy(&self) -> BackendStrategy;
127+
fn new_backend_strategy(&self, ctx: &dyn ExecutorStrategyContext) -> BackendStrategy;
128128
fn new_cheatcode_inspector_strategy(
129129
&self,
130130
ctx: &dyn ExecutorStrategyContext,
@@ -260,7 +260,7 @@ impl ExecutorStrategyRunner for EvmExecutorStrategyRunner {
260260
backend.inspect(env, inspector, Box::new(()))
261261
}
262262

263-
fn new_backend_strategy(&self) -> BackendStrategy {
263+
fn new_backend_strategy(&self, _ctx: &dyn ExecutorStrategyContext) -> BackendStrategy {
264264
BackendStrategy::new_evm()
265265
}
266266

crates/evm/evm/src/executors/trace.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ impl TracingExecutor {
3131
state_overrides: Option<StateOverride>,
3232
strategy: ExecutorStrategy,
3333
) -> eyre::Result<Self> {
34-
let db = Backend::spawn(fork, strategy.runner.new_backend_strategy())?;
34+
let db =
35+
Backend::spawn(fork, strategy.runner.new_backend_strategy(strategy.context.as_ref()))?;
3536

3637
// configures a bare version of the evm executor: no cheatcode inspector is enabled,
3738
// tracing will be enabled only for the targeted transaction

crates/forge/src/multi_runner.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,10 @@ impl MultiContractRunner {
181181
trace!("running all tests");
182182

183183
// The DB backend that serves all the data.
184-
let db = Backend::spawn(self.fork.take(), self.strategy.runner.new_backend_strategy())?;
184+
let db = Backend::spawn(
185+
self.fork.take(),
186+
self.strategy.runner.new_backend_strategy(self.strategy.context.as_ref()),
187+
)?;
185188

186189
let find_timer = Instant::now();
187190
let contracts = self.matching_contracts(filter).collect::<Vec<_>>();

crates/forge/tests/cli/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,7 @@ path = "out"
10691069
[profile.default.zksync]
10701070
compile = false
10711071
startup = false
1072+
evm_interpreter = false
10721073
size_fallback = false
10731074
enable_eravm_extensions = false
10741075
force_evmla = false
@@ -1379,6 +1380,7 @@ exclude = []
13791380
"zksync": {
13801381
"compile": false,
13811382
"startup": false,
1383+
"evm_interpreter": false,
13821384
"zksolc": null,
13831385
"solc_path": null,
13841386
"hash_type": null,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! Forge tests for zksync evm interpreter.
2+
3+
use crate::{config::*, test_helpers::TEST_DATA_DEFAULT};
4+
use foundry_test_utils::Filter;
5+
use revm::primitives::hardfork::SpecId;
6+
7+
#[tokio::test(flavor = "multi_thread")]
8+
async fn test_zk_evm_interpreter_create() {
9+
let mut zk_config = TEST_DATA_DEFAULT.zk_test_data.as_ref().unwrap().zk_config.clone();
10+
zk_config.verbosity = 5;
11+
zk_config.zksync.evm_interpreter = true;
12+
let runner = TEST_DATA_DEFAULT.runner_with_zksync_config(zk_config);
13+
let filter = Filter::new("testCreate|testCall", "EvmInterpreterTest", ".*");
14+
15+
TestConfig::with_filter(runner, filter).spec_id(SpecId::SHANGHAI).run().await;
16+
}

crates/forge/tests/it/zk/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod contracts;
77
mod create;
88
mod create2;
99
mod deploy;
10+
mod evm_interpreter;
1011
mod factory;
1112
mod factory_deps;
1213
mod fork;

0 commit comments

Comments
 (0)