Skip to content

Commit 7b3c869

Browse files
elfedyJrigadadutterbutter
authored
feat: add the ability to use specific gas params in era vm environment and use them on script estimations (#773)
--------- Co-authored-by: Juan Rigada <[email protected]> Co-authored-by: Dustin Brickwood <[email protected]>
1 parent 68fcb7d commit 7b3c869

File tree

17 files changed

+625
-467
lines changed

17 files changed

+625
-467
lines changed

Cargo.lock

Lines changed: 464 additions & 428 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cheatcodes/src/config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use foundry_config::{
99
};
1010
use foundry_evm_core::opts::EvmOpts;
1111
use foundry_zksync_compiler::DualCompiledContracts;
12+
use foundry_zksync_core::vm::ZkEnv;
1213
use semver::Version;
1314
use std::{
1415
path::{Path, PathBuf},
@@ -62,10 +63,13 @@ pub struct CheatsConfig {
6263
pub assertions_revert: bool,
6364
/// Optional seed for the RNG algorithm.
6465
pub seed: Option<U256>,
66+
/// Era Vm environment
67+
pub zk_env: Option<ZkEnv>,
6568
}
6669

6770
impl CheatsConfig {
6871
/// Extracts the necessary settings from the Config
72+
#[allow(clippy::too_many_arguments)]
6973
pub fn new(
7074
config: &Config,
7175
evm_opts: EvmOpts,
@@ -74,6 +78,7 @@ impl CheatsConfig {
7478
running_version: Option<Version>,
7579
dual_compiled_contracts: DualCompiledContracts,
7680
use_zk: bool,
81+
zk_env: Option<ZkEnv>,
7782
) -> Self {
7883
let mut allowed_paths = vec![config.root.0.clone()];
7984
allowed_paths.extend(config.libs.clone());
@@ -107,6 +112,7 @@ impl CheatsConfig {
107112
use_zk,
108113
assertions_revert: config.assertions_revert,
109114
seed: config.fuzz.seed,
115+
zk_env,
110116
}
111117
}
112118

@@ -239,6 +245,7 @@ impl Default for CheatsConfig {
239245
use_zk: false,
240246
assertions_revert: true,
241247
seed: None,
248+
zk_env: Default::default(),
242249
}
243250
}
244251
}
@@ -257,6 +264,7 @@ mod tests {
257264
None,
258265
Default::default(),
259266
false,
267+
None,
260268
)
261269
}
262270

crates/cheatcodes/src/inspector.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ use foundry_wallets::multi_wallet::MultiWallet;
4646
use foundry_zksync_compiler::{DualCompiledContract, DualCompiledContracts};
4747
use foundry_zksync_core::{
4848
convert::{ConvertAddress, ConvertH160, ConvertH256, ConvertRU256, ConvertU256},
49-
get_account_code_key, get_balance_key, get_nonce_key, Call, ZkPaymasterData,
50-
ZkTransactionMetadata, DEFAULT_CREATE2_DEPLOYER_ZKSYNC,
49+
get_account_code_key, get_balance_key, get_nonce_key,
50+
vm::ZkEnv,
51+
Call, ZkPaymasterData, ZkTransactionMetadata, DEFAULT_CREATE2_DEPLOYER_ZKSYNC,
5152
};
5253
use foundry_zksync_inspectors::TraceCollector;
5354
use itertools::Itertools;
@@ -650,6 +651,8 @@ pub struct Cheatcodes {
650651

651652
/// Nonce update persistence behavior in zkEVM for the tx caller.
652653
pub zk_persist_nonce_update: ZkPersistNonceUpdate,
654+
655+
pub zk_env: ZkEnv,
653656
}
654657

655658
// This is not derived because calling this in `fn new` with `..Default::default()` creates a second
@@ -703,6 +706,7 @@ impl Cheatcodes {
703706
persisted_factory_deps.insert(zk_bytecode_hash, zk_deployed_bytecode);
704707

705708
let zk_startup_migration = config.use_zk.then_some(ZkStartupMigration::Defer);
709+
let zk_env = config.zk_env.clone().unwrap_or_default();
706710

707711
Self {
708712
fs_commit: true,
@@ -750,6 +754,7 @@ impl Cheatcodes {
750754
paymaster_params: None,
751755
zk_use_factory_deps: Default::default(),
752756
zk_persist_nonce_update: Default::default(),
757+
zk_env,
753758
}
754759
}
755760

@@ -1304,6 +1309,7 @@ impl Cheatcodes {
13041309
persisted_factory_deps: Some(&mut self.persisted_factory_deps),
13051310
paymaster_data: self.paymaster_params.take(),
13061311
persist_nonce_update: self.broadcast.is_some() || zk_persist_nonce_update,
1312+
zk_env: self.zk_env.clone(),
13071313
};
13081314

13091315
let zk_create = foundry_zksync_core::vm::ZkCreateInputs {
@@ -1968,6 +1974,7 @@ where {
19681974
persisted_factory_deps: Some(&mut self.persisted_factory_deps),
19691975
paymaster_data: self.paymaster_params.take(),
19701976
persist_nonce_update: self.broadcast.is_some() || zk_persist_nonce_update,
1977+
zk_env: self.zk_env.clone(),
19711978
};
19721979

19731980
let mut gas = Gas::new(call.gas_limit);

crates/chisel/src/executor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ impl SessionSource {
338338
Some(self.solc.version.clone()),
339339
Default::default(),
340340
false,
341+
None,
341342
)
342343
.into(),
343344
)

crates/evm/core/src/backend/cow.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use alloy_primitives::{map::HashMap, Address, B256, U256};
1313
use alloy_rpc_types::TransactionRequest;
1414
use eyre::WrapErr;
1515
use foundry_fork_db::DatabaseError;
16-
use foundry_zksync_core::PaymasterParams;
16+
use foundry_zksync_core::{vm::ZkEnv, PaymasterParams};
1717
use revm::{
1818
db::DatabaseRef,
1919
primitives::{
@@ -65,6 +65,7 @@ impl<'a> CowBackend<'a> {
6565
pub fn inspect_ref_zk(
6666
&mut self,
6767
env: &mut Env,
68+
zk_env: &ZkEnv,
6869
persisted_factory_deps: &mut HashMap<foundry_zksync_core::H256, Vec<u8>>,
6970
factory_deps: Option<Vec<Vec<u8>>>,
7071
paymaster_data: Option<PaymasterParams>,
@@ -78,6 +79,7 @@ impl<'a> CowBackend<'a> {
7879
factory_deps,
7980
paymaster_data,
8081
env,
82+
zk_env,
8183
self,
8284
)
8385
}

crates/evm/core/src/backend/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use eyre::Context;
1616
use foundry_common::{is_known_system_sender, SYSTEM_TRANSACTION_TYPE};
1717
pub use foundry_fork_db::{cache::BlockchainDbMeta, BlockchainDb, SharedBackend};
1818
use foundry_zksync_core::{
19-
convert::ConvertH160, PaymasterParams, ACCOUNT_CODE_STORAGE_ADDRESS,
19+
convert::ConvertH160, vm::ZkEnv, PaymasterParams, ACCOUNT_CODE_STORAGE_ADDRESS,
2020
IMMUTABLE_SIMULATOR_STORAGE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L2_BASE_TOKEN_ADDRESS,
2121
NONCE_HOLDER_ADDRESS,
2222
};
@@ -840,6 +840,7 @@ impl Backend {
840840
pub fn inspect_ref_zk(
841841
&mut self,
842842
env: &mut EnvWithHandlerCfg,
843+
zk_env: &ZkEnv,
843844
persisted_factory_deps: &mut HashMap<foundry_zksync_core::H256, Vec<u8>>,
844845
factory_deps: Option<Vec<Vec<u8>>>,
845846
paymaster_data: Option<PaymasterParams>,
@@ -851,6 +852,7 @@ impl Backend {
851852
factory_deps,
852853
paymaster_data,
853854
env,
855+
zk_env,
854856
self,
855857
)
856858
}

crates/evm/evm/src/executors/builder.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{executors::Executor, inspectors::InspectorStackBuilder};
22
use foundry_evm_core::backend::Backend;
3+
use foundry_zksync_core::vm::ZkEnv;
34
use revm::primitives::{Env, EnvWithHandlerCfg, SpecId};
45

56
/// The builder that allows to configure an evm [`Executor`] which a stack of optional
@@ -19,8 +20,10 @@ pub struct ExecutorBuilder {
1920
/// The spec ID.
2021
spec_id: SpecId,
2122

22-
use_zk: bool,
2323
legacy_assertions: bool,
24+
25+
use_zk: bool,
26+
zk_env: ZkEnv,
2427
}
2528

2629
impl Default for ExecutorBuilder {
@@ -30,8 +33,9 @@ impl Default for ExecutorBuilder {
3033
stack: InspectorStackBuilder::new(),
3134
gas_limit: None,
3235
spec_id: SpecId::LATEST,
33-
use_zk: false,
3436
legacy_assertions: false,
37+
use_zk: false,
38+
zk_env: Default::default(),
3539
}
3640
}
3741
}
@@ -67,24 +71,31 @@ impl ExecutorBuilder {
6771
self
6872
}
6973

74+
/// Sets the `legacy_assertions` flag.
75+
#[inline]
76+
pub fn legacy_assertions(mut self, legacy_assertions: bool) -> Self {
77+
self.legacy_assertions = legacy_assertions;
78+
self
79+
}
80+
7081
/// Sets the EVM spec to use
7182
#[inline]
7283
pub fn use_zk_vm(mut self, enable: bool) -> Self {
7384
self.use_zk = enable;
7485
self
7586
}
7687

77-
/// Sets the `legacy_assertions` flag.
88+
/// Sets zk_env
7889
#[inline]
79-
pub fn legacy_assertions(mut self, legacy_assertions: bool) -> Self {
80-
self.legacy_assertions = legacy_assertions;
90+
pub fn zk_env(mut self, zk_env: ZkEnv) -> Self {
91+
self.zk_env = zk_env;
8192
self
8293
}
8394

8495
/// Builds the executor as configured.
8596
#[inline]
8697
pub fn build(self, env: Env, db: Backend) -> Executor {
87-
let Self { mut stack, gas_limit, spec_id, legacy_assertions, use_zk } = self;
98+
let Self { mut stack, gas_limit, spec_id, legacy_assertions, use_zk, zk_env } = self;
8899
if stack.block.is_none() {
89100
stack.block = Some(env.block.clone());
90101
}
@@ -95,6 +106,7 @@ impl ExecutorBuilder {
95106
let env = EnvWithHandlerCfg::new_with_spec_id(Box::new(env), spec_id);
96107
let mut exec = Executor::new(db, env, stack.build(), gas_limit, legacy_assertions);
97108
exec.use_zk = use_zk;
109+
exec.zk_env = zk_env;
98110
exec
99111
}
100112
}

crates/evm/evm/src/executors/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use foundry_evm_core::{
2727
};
2828
use foundry_evm_coverage::HitMaps;
2929
use foundry_evm_traces::{SparsedTraceArena, TraceMode};
30-
use foundry_zksync_core::ZkTransactionMetadata;
30+
use foundry_zksync_core::{vm::ZkEnv, ZkTransactionMetadata};
3131
use revm::{
3232
db::{DatabaseCommit, DatabaseRef},
3333
interpreter::{return_ok, InstructionResult},
@@ -97,6 +97,7 @@ pub struct Executor {
9797
zk_persisted_factory_deps: HashMap<foundry_zksync_core::H256, Vec<u8>>,
9898

9999
pub use_zk: bool,
100+
pub zk_env: ZkEnv,
100101
}
101102

102103
impl Executor {
@@ -137,6 +138,7 @@ impl Executor {
137138
zk_tx: None,
138139
zk_persisted_factory_deps: Default::default(),
139140
use_zk: false,
141+
zk_env: Default::default(),
140142
}
141143
}
142144

@@ -453,6 +455,7 @@ impl Executor {
453455
env.tx.gas_price = self.env.tx.gas_price;
454456
backend.inspect_ref_zk(
455457
&mut env,
458+
&self.zk_env,
456459
&mut self.zk_persisted_factory_deps.clone(),
457460
Some(zk_tx.factory_deps.clone()),
458461
zk_tx.paymaster_data.clone(),
@@ -476,6 +479,7 @@ impl Executor {
476479
env.tx.gas_price = self.env.tx.gas_price;
477480
backend.inspect_ref_zk(
478481
&mut env,
482+
&self.zk_env,
479483
// this will persist the added factory deps,
480484
// no need to commit them later
481485
&mut self.zk_persisted_factory_deps,

crates/forge/src/multi_runner.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ impl MultiContractRunner {
256256
Some(artifact_id.version.clone()),
257257
self.dual_compiled_contracts.clone(),
258258
self.use_zk,
259+
None,
259260
);
260261

261262
let trace_mode = TraceMode::default()

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use foundry_test_utils::{
66
util::{self, OutputExt},
77
Filter, ZkSyncNode,
88
};
9+
use foundry_zksync_core::utils::MAX_L2_GAS_LIMIT;
910

1011
use crate::{config::TestConfig, test_helpers::TEST_DATA_DEFAULT};
1112

@@ -44,9 +45,9 @@ contract ZkLargeFactoryDependenciesScript is Script {
4445

4546
let node = ZkSyncNode::start();
4647

47-
// foundry default gas-limit is not enough to pay for factory deps in our current
48-
// default environment
49-
let gas_limit = u32::MAX >> 1;
48+
// foundry default gas-limit is not enough to pay for factory deps
49+
// with Anvil-zksync's environment
50+
let gas_limit = MAX_L2_GAS_LIMIT;
5051

5152
cmd.arg("script").args([
5253
"--zk-startup",

0 commit comments

Comments
 (0)