Skip to content

Commit

Permalink
feat: EVM simulator as optional for the server (#276)
Browse files Browse the repository at this point in the history
* Add evm simulator as optional for the server

* Changes to make it work against era-contracts `main`

* fmt

* Calculate bytecode of evm gas manager only if evm simulator flag is on

* Add multicall for get evm simulator bytecode hash

* Use bytecode of default account for the evm simulator if not present

* Remove unnecessary comments

* Use bytecode of default account for evm simulator in gas test sc

* Remove tests for the evm simulator

---------

Co-authored-by: Javier Chatruc <[email protected]>
  • Loading branch information
IAvecilla and jrchatruc authored Sep 19, 2024
1 parent ed97d24 commit f922068
Show file tree
Hide file tree
Showing 20 changed files with 460 additions and 60 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion contracts
Submodule contracts updated 368 files
2 changes: 2 additions & 0 deletions core/bin/system-constants-generator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ zksync_types.workspace = true
zksync_utils.workspace = true
zksync_contracts.workspace = true
zksync_multivm.workspace = true
zksync_config.workspace = true
zksync_env_config.workspace = true

codegen.workspace = true
serde.workspace = true
Expand Down
27 changes: 21 additions & 6 deletions core/bin/system-constants-generator/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::{cell::RefCell, rc::Rc};
use std::{cell::RefCell, rc::Rc, str::FromStr};

use once_cell::sync::Lazy;
use zksync_config::configs::use_evm_simulator;
use zksync_contracts::{
load_sys_contract, read_bootloader_code, read_bytecode_from_path, read_sys_contract_bytecode,
BaseSystemContracts, ContractLanguage, SystemContractCode,
};
use zksync_env_config::FromEnv;
use zksync_multivm::{
interface::{
storage::{InMemoryStorage, StorageView, WriteStorage},
Expand All @@ -24,8 +26,9 @@ use zksync_types::{
block::L2BlockHasher, ethabi::Token, fee::Fee, fee_model::BatchFeeInput, l1::L1Tx, l2::L2Tx,
utils::storage_key_for_eth_balance, AccountTreeId, Address, Execute, K256PrivateKey,
L1BatchNumber, L1TxCommonData, L2BlockNumber, L2ChainId, Nonce, ProtocolVersionId, StorageKey,
Transaction, BOOTLOADER_ADDRESS, SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_GAS_PRICE_POSITION,
SYSTEM_CONTEXT_TX_ORIGIN_POSITION, U256, ZKPORTER_IS_AVAILABLE,
Transaction, BOOTLOADER_ADDRESS, H256, SYSTEM_CONTEXT_ADDRESS,
SYSTEM_CONTEXT_GAS_PRICE_POSITION, SYSTEM_CONTEXT_TX_ORIGIN_POSITION, U256,
ZKPORTER_IS_AVAILABLE,
};
use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, u256_to_h256};

Expand Down Expand Up @@ -71,9 +74,21 @@ pub static GAS_TEST_SYSTEM_CONTRACTS: Lazy<BaseSystemContracts> = Lazy::new(|| {

let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol);
let hash = hash_bytecode(&bytecode);
let evm_simulator_bytecode =
read_sys_contract_bytecode("", "EvmInterpreter", ContractLanguage::Yul);
let evm_simulator_hash = hash_bytecode(&evm_simulator_bytecode);

let mut evm_simulator_bytecode = bytecode.clone();
let mut evm_simulator_hash =
H256::from_str("0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32")
.unwrap();

if use_evm_simulator::UseEvmSimulator::from_env()
.unwrap()
.use_evm_simulator
{
evm_simulator_bytecode =
read_sys_contract_bytecode("", "EvmInterpreter", ContractLanguage::Yul);
evm_simulator_hash = hash_bytecode(&evm_simulator_bytecode.clone());
}

BaseSystemContracts {
default_aa: SystemContractCode {
code: bytes_to_be_words(bytecode),
Expand Down
1 change: 1 addition & 0 deletions core/lib/config/src/configs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub mod pruning;
pub mod secrets;
pub mod snapshot_recovery;
pub mod snapshots_creator;
pub mod use_evm_simulator;
pub mod utils;
pub mod vm_runner;
pub mod wallets;
Expand Down
7 changes: 7 additions & 0 deletions core/lib/config/src/configs/use_evm_simulator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use serde::Deserialize;

/// Configuration for the use evm simulator
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct UseEvmSimulator {
pub use_evm_simulator: bool,
}
22 changes: 18 additions & 4 deletions core/lib/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{
fs::{self, File},
io::BufReader,
path::{Path, PathBuf},
str::FromStr,
};

use ethabi::{
Expand All @@ -16,6 +17,8 @@ use ethabi::{
};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use zksync_config::configs::use_evm_simulator::{self};
use zksync_env_config::FromEnv;
use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, env::Workspace};

pub mod test_contracts;
Expand Down Expand Up @@ -338,13 +341,24 @@ impl BaseSystemContracts {
let hash = hash_bytecode(&bytecode);

let default_aa = SystemContractCode {
code: bytes_to_be_words(bytecode),
code: bytes_to_be_words(bytecode.clone()),
hash,
};

let evm_simulator_bytecode =
read_sys_contract_bytecode("", "EvmInterpreter", ContractLanguage::Yul);
let evm_simulator_hash = hash_bytecode(&evm_simulator_bytecode);
// If evm simulator is not enabled, use the default account bytecode and hash.
let mut evm_simulator_bytecode = bytecode;
let mut evm_simulator_hash =
H256::from_str("0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32")
.unwrap();

if use_evm_simulator::UseEvmSimulator::from_env()
.unwrap()
.use_evm_simulator
{
evm_simulator_bytecode =
read_sys_contract_bytecode("", "EvmInterpreter", ContractLanguage::Yul);
evm_simulator_hash = hash_bytecode(&evm_simulator_bytecode);
}

let evm_simulator = SystemContractCode {
code: bytes_to_be_words(evm_simulator_bytecode),
Expand Down
1 change: 1 addition & 0 deletions core/lib/env_config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mod genesis;
mod prover_job_monitor;
#[cfg(test)]
mod test_utils;
mod use_evm_simulator;
mod vm_runner;
mod wallets;

Expand Down
9 changes: 9 additions & 0 deletions core/lib/env_config/src/use_evm_simulator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use zksync_config::configs::use_evm_simulator::UseEvmSimulator;

use crate::{envy_load, FromEnv};

impl FromEnv for UseEvmSimulator {
fn from_env() -> anyhow::Result<Self> {
envy_load("use_evm_simulator", "USE_EVM_SIMULATOR_")
}
}
2 changes: 2 additions & 0 deletions core/lib/multivm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ circuit_sequencer_api_1_4_2.workspace = true
circuit_sequencer_api_1_5_0.workspace = true

zksync_types.workspace = true
zksync_config.workspace = true
zksync_env_config.workspace = true
zksync_contracts.workspace = true
zksync_utils.workspace = true
zksync_system_constants.workspace = true
Expand Down
26 changes: 19 additions & 7 deletions core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use zk_evm_1_5_0::{
witness_trace::DummyTracer,
zkevm_opcode_defs::{decoding::EncodingModeProduction, Opcode, RetOpcode},
};
use zksync_config::configs::use_evm_simulator::{self};
use zksync_env_config::FromEnv;

use super::{EvmDeployTracer, PubdataTracer};
use crate::{
Expand Down Expand Up @@ -64,7 +66,7 @@ pub struct DefaultExecutionTracer<S: WriteStorage, H: HistoryMode> {
// take into account e.g circuits produced by the initial bootloader memory commitment.
pub(crate) circuits_tracer: CircuitsTracer<S, H>,
// This tracer is responsible for handling EVM deployments and providing the data to the code decommitter.
pub(crate) evm_deploy_tracer: EvmDeployTracer<S>,
pub(crate) evm_deploy_tracer: Option<EvmDeployTracer<S>>,
subversion: MultiVMSubversion,
storage: StoragePtr<S>,
_phantom: PhantomData<H>,
Expand All @@ -80,6 +82,9 @@ impl<S: WriteStorage, H: HistoryMode> DefaultExecutionTracer<S, H> {
pubdata_tracer: Option<PubdataTracer<S>>,
subversion: MultiVMSubversion,
) -> Self {
let active_evm = use_evm_simulator::UseEvmSimulator::from_env()
.unwrap()
.use_evm_simulator;
Self {
tx_has_been_processed: false,
execution_mode,
Expand All @@ -94,7 +99,11 @@ impl<S: WriteStorage, H: HistoryMode> DefaultExecutionTracer<S, H> {
pubdata_tracer,
ret_from_the_bootloader: None,
circuits_tracer: CircuitsTracer::new(),
evm_deploy_tracer: EvmDeployTracer::new(),
evm_deploy_tracer: if active_evm {
Some(EvmDeployTracer::new())
} else {
None
},
storage,
_phantom: PhantomData,
}
Expand Down Expand Up @@ -175,7 +184,9 @@ macro_rules! dispatch_tracers {
tracer.$function($( $params ),*);
}
$self.circuits_tracer.$function($( $params ),*);
$self.evm_deploy_tracer.$function($( $params ),*);
if let Some(tracer) = &mut $self.evm_deploy_tracer {
tracer.$function($( $params ),*);
}
};
}

Expand Down Expand Up @@ -293,10 +304,11 @@ impl<S: WriteStorage, H: HistoryMode> DefaultExecutionTracer<S, H> {
.finish_cycle(state, bootloader_state)
.stricter(&result);

result = self
.evm_deploy_tracer
.finish_cycle(state, bootloader_state)
.stricter(&result);
if let Some(evm_deploy_tracer) = &mut self.evm_deploy_tracer {
result = evm_deploy_tracer
.finish_cycle(state, bootloader_state)
.stricter(&result);
}

result.stricter(&self.should_stop_execution())
}
Expand Down
1 change: 1 addition & 0 deletions core/lib/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ zksync_basic_types.workspace = true
zksync_contracts.workspace = true
zksync_mini_merkle_tree.workspace = true
zksync_config.workspace = true
zksync_env_config.workspace = true
zksync_protobuf.workspace = true
zksync_crypto_primitives.workspace = true

Expand Down
54 changes: 42 additions & 12 deletions core/lib/types/src/system_contracts.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::path::PathBuf;
use std::{path::PathBuf, str::FromStr};

use once_cell::sync::Lazy;
use zksync_basic_types::{AccountTreeId, Address, H256, U256};
use zksync_config::configs::use_evm_simulator;
use zksync_contracts::{read_sys_contract_bytecode, ContractLanguage, SystemContractsRepo};
use zksync_env_config::FromEnv;
use zksync_system_constants::{
BOOTLOADER_UTILITIES_ADDRESS, CODE_ORACLE_ADDRESS, COMPRESSOR_ADDRESS, CREATE2_FACTORY_ADDRESS,
EVENT_WRITER_ADDRESS, EVM_GAS_MANAGER_ADDRESS, P256VERIFY_PRECOMPILE_ADDRESS,
Expand Down Expand Up @@ -179,23 +181,41 @@ static SYSTEM_CONTRACT_LIST: [(&str, &str, Address, ContractLanguage); 26] = [
];

static EVM_SIMULATOR_HASH: Lazy<H256> = Lazy::new(|| {
hash_bytecode(&read_sys_contract_bytecode(
"",
"EvmInterpreter",
ContractLanguage::Yul,
))
if use_evm_simulator::UseEvmSimulator::from_env()
.unwrap()
.use_evm_simulator
{
hash_bytecode(&read_sys_contract_bytecode(
"",
"EvmInterpreter",
ContractLanguage::Yul,
))
} else {
H256::from_str("0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32")
.unwrap()
}
});

pub fn get_evm_simulator_hash() -> H256 {
*EVM_SIMULATOR_HASH
}

static SYSTEM_CONTRACTS: Lazy<Vec<DeployedContract>> = Lazy::new(|| {
let evm_simulator_is_used = use_evm_simulator::UseEvmSimulator::from_env()
.unwrap()
.use_evm_simulator;
SYSTEM_CONTRACT_LIST
.iter()
.map(|(path, name, address, contract_lang)| DeployedContract {
account_id: AccountTreeId::new(*address),
bytecode: read_sys_contract_bytecode(path, name, contract_lang.clone()),
.filter_map(|(path, name, address, contract_lang)| {
let result = if *name == "EvmGasManager" && !evm_simulator_is_used {
None
} else {
Some(DeployedContract {
account_id: AccountTreeId::new(*address),
bytecode: read_sys_contract_bytecode(path, name, contract_lang.clone()),
})
};
result
})
.collect::<Vec<_>>()
});
Expand All @@ -207,12 +227,22 @@ pub fn get_system_smart_contracts() -> Vec<DeployedContract> {

/// Loads system contracts from a given directory.
pub fn get_system_smart_contracts_from_dir(path: PathBuf) -> Vec<DeployedContract> {
let evm_simulator_is_used = use_evm_simulator::UseEvmSimulator::from_env()
.unwrap()
.use_evm_simulator;
let repo = SystemContractsRepo { root: path };
SYSTEM_CONTRACT_LIST
.iter()
.map(|(path, name, address, contract_lang)| DeployedContract {
account_id: AccountTreeId::new(*address),
bytecode: repo.read_sys_contract_bytecode(path, name, contract_lang.clone()),
.filter_map(|(path, name, address, contract_lang)| {
let result = if *name == "EvmGasManager" && !evm_simulator_is_used {
None
} else {
Some(DeployedContract {
account_id: AccountTreeId::new(*address),
bytecode: repo.read_sys_contract_bytecode(path, name, contract_lang.clone()),
})
};
result
})
.collect::<Vec<_>>()
}
1 change: 1 addition & 0 deletions core/node/eth_sender/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ vise.workspace = true
zksync_types.workspace = true
zksync_dal.workspace = true
zksync_config.workspace = true
zksync_env_config.workspace = true
zksync_contracts.workspace = true
zksync_eth_client.workspace = true
zksync_utils.workspace = true
Expand Down
Loading

0 comments on commit f922068

Please sign in to comment.