diff --git a/.gitmodules b/.gitmodules index 72622394..d6c442b9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,6 @@ url = https://github.com/ethereum/solidity branch = develop [submodule "era-contracts"] - path = era-contracts - url = https://github.com/matter-labs/era-contracts - branch = stable/evm-emulator + path = era-contracts + url = https://github.com/matter-labs/era-contracts + branch = evm-emulator/fixes diff --git a/Cargo.lock b/Cargo.lock index 068057f0..05c0aa33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -739,7 +739,7 @@ dependencies = [ "solidity-adapter", "web3", "which", - "zkevm_opcode_defs", + "zkevm_opcode_defs 0.150.6", "zkevm_tester", "zksync_vm2", ] @@ -1112,7 +1112,7 @@ dependencies = [ "num", "semver 1.0.23", "serde", - "zkevm_opcode_defs", + "zkevm_opcode_defs 0.150.6", ] [[package]] @@ -1139,7 +1139,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.64", - "zkevm_opcode_defs", + "zkevm_opcode_defs 0.150.6", ] [[package]] @@ -1163,7 +1163,7 @@ dependencies = [ "serde", "serde_json", "which", - "zkevm_opcode_defs", + "zkevm_opcode_defs 0.150.6", ] [[package]] @@ -4610,9 +4610,8 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c14bda6c101389145cd01fac900f1392876bc0284d98faf7f376237baa2cb19d" +version = "0.150.18" +source = "git+https://github.com/matter-labs/zksync-protocol?branch=evm-emulator/testing#fdf2edf79d85011e849cce04cb051ecb0c86ac15" dependencies = [ "anyhow", "lazy_static", @@ -4620,7 +4619,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions", + "zk_evm_abstractions 0.150.18", ] [[package]] @@ -4633,7 +4632,19 @@ dependencies = [ "num_enum", "serde", "static_assertions", - "zkevm_opcode_defs", + "zkevm_opcode_defs 0.150.6", +] + +[[package]] +name = "zk_evm_abstractions" +version = "0.150.18" +source = "git+https://github.com/matter-labs/zksync-protocol?branch=evm-emulator/testing#fdf2edf79d85011e849cce04cb051ecb0c86ac15" +dependencies = [ + "anyhow", + "num_enum", + "serde", + "static_assertions", + "zkevm_opcode_defs 0.150.18", ] [[package]] @@ -4653,10 +4664,26 @@ dependencies = [ "sha3 0.10.8", ] +[[package]] +name = "zkevm_opcode_defs" +version = "0.150.18" +source = "git+https://github.com/matter-labs/zksync-protocol?branch=evm-emulator/testing#fdf2edf79d85011e849cce04cb051ecb0c86ac15" +dependencies = [ + "bitflags 2.6.0", + "blake2", + "ethereum-types", + "k256", + "lazy_static", + "p256", + "serde", + "sha2 0.10.8", + "sha3 0.10.8", +] + [[package]] name = "zkevm_tester" version = "1.5.0" -source = "git+https://github.com/matter-labs/era-zkevm_tester?branch=v1.5.0#393e31814c6838378d84e9932f1b378c1da5b5fe" +source = "git+https://github.com/0xVolosnikov/era-zkevm_tester?rev=cbade136a9060abd8ec29e06ed6c1bd14dec4ff6#cbade136a9060abd8ec29e06ed6c1bd14dec4ff6" dependencies = [ "anyhow", "ethabi", @@ -4679,8 +4706,8 @@ source = "git+https://github.com/matter-labs/vm2#457d8a7eea9093af9440662e33e598c dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions", - "zkevm_opcode_defs", + "zk_evm_abstractions 0.150.6", + "zkevm_opcode_defs 0.150.6", "zksync_vm2_interface", ] diff --git a/compiler_tester/Cargo.toml b/compiler_tester/Cargo.toml index 092d386e..9a8ec61e 100644 --- a/compiler_tester/Cargo.toml +++ b/compiler_tester/Cargo.toml @@ -44,7 +44,7 @@ evm = { git = "https://github.com/rust-ethereum/evm", rev = "f7a23df6c478ca6a151 revm = { git = "https://github.com/bluealloy/revm", rev = "fa5650ee8a4d802f4f3557014dd157adfb074460" } zkevm_opcode_defs = "=0.150.6" -zkevm_tester = { git = "https://github.com/matter-labs/era-zkevm_tester", branch = "v1.5.0" } +zkevm_tester = { git = "https://github.com/0xVolosnikov/era-zkevm_tester", rev = "cbade136a9060abd8ec29e06ed6c1bd14dec4ff6" } vm2 = { git = "https://github.com/matter-labs/vm2", optional = true, package = "zksync_vm2" } era-compiler-common = { git = "https://github.com/matter-labs/era-compiler-common", branch = "main" } diff --git a/compiler_tester/src/directories/matter_labs/test/metadata/evm_contract.rs b/compiler_tester/src/directories/matter_labs/test/metadata/evm_contract.rs index 1bef195e..35f17d0a 100644 --- a/compiler_tester/src/directories/matter_labs/test/metadata/evm_contract.rs +++ b/compiler_tester/src/directories/matter_labs/test/metadata/evm_contract.rs @@ -42,7 +42,8 @@ impl EVMContract { pub fn runtime_code(&self, instruction_name: &str) -> String { let repeats = match instruction_name { "RETURNDATASIZE" | "RETURNDATACOPY" | "EXTCODESIZE" | "EXTCODEHASH" | "EXTCODECOPY" - | "CALL" | "STATICCALL" | "DELEGATECALL" | "CREATE" | "CREATE2" => 1, + | "CALL" | "STATICCALL" | "DELEGATECALL" | "CREATE" | "CREATE2" | "RETURN" + | "REVERT" | "STOP" | "INVALID" => 1, _ => Self::RUNTIME_CODE_REPEATS, }; diff --git a/compiler_tester/src/vm/eravm/deployers/system_contract_deployer.rs b/compiler_tester/src/vm/eravm/deployers/system_contract_deployer.rs index dabbf3cf..cf0a23e6 100644 --- a/compiler_tester/src/vm/eravm/deployers/system_contract_deployer.rs +++ b/compiler_tester/src/vm/eravm/deployers/system_contract_deployer.rs @@ -209,13 +209,25 @@ impl EraVMDeployer for SystemContractDeployer { calldata.extend(deploy_code); calldata.extend(constructor_calldata); - vm.execute::( + let mut result = vm.execute::( test_name, entry_address, caller, Some(context_u128_value), calldata, Some(vm_launch_option), - ) + )?; + + if result.output.return_data.len() > 1 { + let gas_left = result + .output + .return_data + .remove(0) + .unwrap_certain_as_ref() + .as_u64(); + result.gas = EraVM::EVM_CALL_GAS_LIMIT - gas_left; + } + + Ok(result) } } diff --git a/compiler_tester/src/vm/eravm/mod.rs b/compiler_tester/src/vm/eravm/mod.rs index fef2e60c..92eb0086 100644 --- a/compiler_tester/src/vm/eravm/mod.rs +++ b/compiler_tester/src/vm/eravm/mod.rs @@ -21,7 +21,9 @@ use std::time::Instant; use colored::Colorize; use solidity_adapter::EVMVersion; +use zkevm_opcode_defs::ADDRESS_CONTRACT_DEPLOYER; +use crate::utils; use crate::vm::execution_result::ExecutionResult; use self::system_context::SystemContext; @@ -49,6 +51,8 @@ pub struct EraVM { storage_transient: HashMap, /// The current EVM block number. current_evm_block_number: u128, + /// The target instruction set. + target: era_compiler_common::Target, } impl EraVM { @@ -59,6 +63,9 @@ impl EraVM { /// The extra amount of gas consumed by every call to the EVM interpreter. pub const EVM_INTERPRETER_GAS_OVERHEAD: u64 = 2500; + /// The `allowedBytecodesToDeploy` variable storage slot in the `ContractDeployer` contract. + pub const CONTRACT_DEPLOYER_ALLOWED_BYTECODES_MODE_SLOT: u64 = 1; + /// The `passGas` variable transient storage slot in the `EvmGasManager` contract. pub const EVM_GAS_MANAGER_GAS_TRANSIENT_SLOT: u64 = 4; @@ -122,9 +129,18 @@ impl EraVM { system_contracts_save_path, )?; - let storage = SystemContext::create_storage(target); + let mut storage = SystemContext::create_storage(target); let storage_transient = HashMap::new(); + // TODO move to the SystemContext after EVM emulator is ready + storage.insert( + zkevm_tester::compiler_tests::StorageKey { + address: web3::types::Address::from_low_u64_be(ADDRESS_CONTRACT_DEPLOYER.into()), + key: web3::types::U256::from(Self::CONTRACT_DEPLOYER_ALLOWED_BYTECODES_MODE_SLOT), + }, + web3::types::H256::from_low_u64_be(1), // Allow EVM contracts deployment + ); + let mut vm = Self { known_contracts: HashMap::new(), default_aa_code_hash: web3::types::U256::from_big_endian( @@ -146,6 +162,7 @@ impl EraVM { storage_transient, published_evm_bytecodes: HashMap::new(), current_evm_block_number: SystemContext::INITIAL_BLOCK_NUMBER, + target, }; vm.add_known_contract( @@ -340,6 +357,34 @@ impl EraVM { 0, ); + if self.target == era_compiler_common::Target::EVM { + // Increase deployment nonce of caller by 1 if it is 0 (we pretend that it is a contract) + let address_h256 = utils::address_to_h256(&caller); + let bytes = [ + address_h256.as_bytes(), + &[0; era_compiler_common::BYTE_LENGTH_FIELD], + ] + .concat(); + let key = web3::signing::keccak256(&bytes).into(); + let storage_key = zkevm_tester::compiler_tests::StorageKey { + address: web3::types::Address::from_low_u64_be( + zkevm_opcode_defs::ADDRESS_NONCE_HOLDER.into(), + ), + key, + }; + let prev_raw_nonce = self + .storage + .entry(storage_key) + .or_insert(web3::types::H256::zero()); + let prev_raw_nonce_uint = utils::h256_to_u256(prev_raw_nonce); + if (prev_raw_nonce_uint >> 128) == web3::types::U256::zero() { + let new_raw_nonce = prev_raw_nonce_uint + + (web3::types::U256::from(1) << web3::types::U256::from(128)); + self.storage + .insert(storage_key, utils::u256_to_h256(&new_raw_nonce)); + } + } + #[cfg(not(feature = "vm2"))] { let snapshot = zkevm_tester::compiler_tests::run_vm_multi_contracts( diff --git a/compiler_tester/src/vm/eravm/system_contracts.rs b/compiler_tester/src/vm/eravm/system_contracts.rs index 88aa8130..244558bd 100644 --- a/compiler_tester/src/vm/eravm/system_contracts.rs +++ b/compiler_tester/src/vm/eravm/system_contracts.rs @@ -63,8 +63,7 @@ impl SystemContracts { "era-contracts/system-contracts/contracts/precompiles/SHA256.yul"; /// The `identity` system contract implementation path. - const PATH_IDENTITY: (&'static str, &'static str) = - ("tests/solidity/simple/system/identity.sol", "Identity"); + const PATH_IDENTITY: &'static str = "era-contracts/system-contracts/contracts/precompiles/Identity.yul"; /// The `ecadd` system contract implementation path. const PATH_ECADD: &'static str = @@ -189,6 +188,10 @@ impl SystemContracts { web3::types::Address::from_low_u64_be(zkevm_opcode_defs::ADDRESS_SHA256.into()), Self::PATH_SHA256.to_owned(), ), + ( + web3::types::Address::from_low_u64_be(zkevm_opcode_defs::ADDRESS_IDENTITY.into()), + Self::PATH_IDENTITY.to_owned(), + ), ( web3::types::Address::from_low_u64_be( zkevm_opcode_defs::system_params::ADDRESS_ECADD.into(), @@ -201,6 +204,12 @@ impl SystemContracts { ), Self::PATH_ECMUL.to_owned(), ), + ( + web3::types::Address::from_low_u64_be( + zkevm_opcode_defs::system_params::ADDRESS_IDENTITY.into(), + ), + Self::PATH_IDENTITY, + ), ( web3::types::Address::from_low_u64_be( zkevm_opcode_defs::ADDRESS_EVENT_WRITER.into(), @@ -225,10 +234,6 @@ impl SystemContracts { Some(Self::PATH_EMPTY_CONTRACT.1), ), ), - ( - web3::types::Address::from_low_u64_be(zkevm_opcode_defs::ADDRESS_IDENTITY.into()), - Self::normalize_name_fs(Self::PATH_IDENTITY.0, Some(Self::PATH_IDENTITY.1)), - ), ( web3::types::Address::from_low_u64_be( zkevm_opcode_defs::ADDRESS_ACCOUNT_CODE_STORAGE.into(), @@ -313,8 +318,7 @@ impl SystemContracts { "6", "-eravm-enable-split-loop-phi-live-ranges", "-tail-merge-only-bbs-without-succ", - "-join-globalcopies", - "-disable-early-taildup", + "-tail-dup-fallthrough-bbs", ] .into_iter() .map(|option| option.to_owned()) diff --git a/era-contracts b/era-contracts index daba783e..a5390403 160000 --- a/era-contracts +++ b/era-contracts @@ -1 +1 @@ -Subproject commit daba783e8ee9ad578a69a1a15716b5fd3680a5bd +Subproject commit a539040301bfdac86f8d5d87e4a213b9f76ea422 diff --git a/ethereum.yaml b/ethereum.yaml index aed98eaa..1ee114bd 100644 --- a/ethereum.yaml +++ b/ethereum.yaml @@ -3296,7 +3296,8 @@ entries: version: '>=0.6.0' failed_create.sol: hash: '0xcd337f294254561827a382cdd146e09d' - enabled: true + enabled: false + comment: 'TODO: out-of-ergs in underlying EraVM' version: '>=0.7.0' file_level_call_via_module.sol: hash: '0x7484f59b7118567c0bb54761d5b87405' @@ -6170,7 +6171,8 @@ entries: version: '>=0.6.2' create.sol: hash: '0xa937f29a18a9b48c6ed9813c4cdfd006' - enabled: true + enabled: false + comment: 'TODO: VM implementation in Solidity tests is invalid' version: '>=0.7.0' invalid_error_encoding.sol: hash: '0x87c1bfbd0f7d4b04f99dd8c7043c15fc' diff --git a/system-contracts-stable-build b/system-contracts-stable-build index 0da7f24c..0ede4316 100644 Binary files a/system-contracts-stable-build and b/system-contracts-stable-build differ