From 2473ce90b9a350feac7f84ba58b307d6c14d245a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 12:23:32 -0300 Subject: [PATCH 01/17] ok cache invaldation --- Cargo.lock | 70 +++++++++---------- crates/common/src/compile.rs | 3 +- crates/config/src/zksync.rs | 32 ++++++++- .../src/compilers/zksolc/settings.rs | 8 ++- 4 files changed, 73 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a00b550e7..af28454e47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1146,7 +1146,7 @@ dependencies = [ [[package]] name = "anvil" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-chains", "alloy-consensus 0.8.0", @@ -1217,7 +1217,7 @@ dependencies = [ [[package]] name = "anvil-core" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-consensus 0.8.0", "alloy-dyn-abi", @@ -1241,7 +1241,7 @@ dependencies = [ [[package]] name = "anvil-rpc" -version = "0.0.3" +version = "0.0.4" dependencies = [ "serde", "serde_json", @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "anvil-server" -version = "0.0.3" +version = "0.0.4" dependencies = [ "anvil-rpc", "async-trait", @@ -2517,7 +2517,7 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cast" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-chains", "alloy-consensus 0.8.0", @@ -2633,7 +2633,7 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chisel" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -4332,7 +4332,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "forge" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-chains", "alloy-consensus 0.8.0", @@ -4431,7 +4431,7 @@ dependencies = [ [[package]] name = "forge-doc" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "derive_more", @@ -4454,7 +4454,7 @@ dependencies = [ [[package]] name = "forge-fmt" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "ariadne", @@ -4470,7 +4470,7 @@ dependencies = [ [[package]] name = "forge-script" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-chains", "alloy-consensus 0.8.0", @@ -4519,7 +4519,7 @@ dependencies = [ [[package]] name = "forge-script-sequence" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-network 0.8.0", "alloy-primitives", @@ -4538,7 +4538,7 @@ dependencies = [ [[package]] name = "forge-sol-macro-gen" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-json-abi", "alloy-sol-macro-expander", @@ -4554,7 +4554,7 @@ dependencies = [ [[package]] name = "forge-verify" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -4616,7 +4616,7 @@ dependencies = [ [[package]] name = "foundry-cheatcodes" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-consensus 0.8.0", "alloy-dyn-abi", @@ -4668,7 +4668,7 @@ dependencies = [ [[package]] name = "foundry-cheatcodes-common" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "revm", @@ -4676,7 +4676,7 @@ dependencies = [ [[package]] name = "foundry-cheatcodes-spec" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-sol-types", "foundry-macros", @@ -4687,7 +4687,7 @@ dependencies = [ [[package]] name = "foundry-cli" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-chains", "alloy-dyn-abi", @@ -4730,7 +4730,7 @@ dependencies = [ [[package]] name = "foundry-common" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-consensus 0.8.0", "alloy-contract", @@ -4782,7 +4782,7 @@ dependencies = [ [[package]] name = "foundry-common-fmt" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-consensus 0.8.0", "alloy-dyn-abi", @@ -4910,7 +4910,7 @@ dependencies = [ [[package]] name = "foundry-config" -version = "0.0.3" +version = "0.0.4" dependencies = [ "Inflector", "alloy-chains", @@ -4949,7 +4949,7 @@ dependencies = [ [[package]] name = "foundry-debugger" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "crossterm", @@ -4967,7 +4967,7 @@ dependencies = [ [[package]] name = "foundry-evm" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -4998,7 +4998,7 @@ dependencies = [ [[package]] name = "foundry-evm-abi" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -5011,7 +5011,7 @@ dependencies = [ [[package]] name = "foundry-evm-core" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-consensus 0.8.0", "alloy-dyn-abi", @@ -5047,7 +5047,7 @@ dependencies = [ [[package]] name = "foundry-evm-coverage" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "eyre", @@ -5062,7 +5062,7 @@ dependencies = [ [[package]] name = "foundry-evm-fuzz" -version = "0.0.3" +version = "0.0.4" dependencies = [ "ahash", "alloy-dyn-abi", @@ -5089,7 +5089,7 @@ dependencies = [ [[package]] name = "foundry-evm-traces" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -5142,7 +5142,7 @@ dependencies = [ [[package]] name = "foundry-linking" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "foundry-compilers", @@ -5152,7 +5152,7 @@ dependencies = [ [[package]] name = "foundry-macros" -version = "0.0.3" +version = "0.0.4" dependencies = [ "proc-macro-error", "proc-macro2", @@ -5162,7 +5162,7 @@ dependencies = [ [[package]] name = "foundry-strategy-zksync" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -5189,7 +5189,7 @@ dependencies = [ [[package]] name = "foundry-test-utils" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "alloy-provider", @@ -5217,7 +5217,7 @@ dependencies = [ [[package]] name = "foundry-wallets" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-consensus 0.8.0", "alloy-dyn-abi", @@ -5248,7 +5248,7 @@ dependencies = [ [[package]] name = "foundry-zksync-compilers" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -5276,7 +5276,7 @@ dependencies = [ [[package]] name = "foundry-zksync-core" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-network 0.8.0", "alloy-primitives", @@ -5305,7 +5305,7 @@ dependencies = [ [[package]] name = "foundry-zksync-inspectors" -version = "0.0.3" +version = "0.0.4" dependencies = [ "alloy-primitives", "foundry-evm-core", diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs index c9d54835a2..16ea94fc88 100644 --- a/crates/common/src/compile.rs +++ b/crates/common/src/compile.rs @@ -25,6 +25,7 @@ use foundry_zksync_compilers::compilers::{ }; use num_format::{Locale, ToFormattedString}; + use std::{ collections::BTreeMap, fmt::Display, @@ -192,7 +193,7 @@ impl ProjectCompiler { let quiet = self.quiet.unwrap_or(false); let bail = self.bail.unwrap_or(true); - let output = with_compilation_reporter(self.quiet.unwrap_or(false), || { + let output = with_compilation_reporter(quiet, || { tracing::debug!("compiling project"); let timer = Instant::now(); diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 12db3a3296..270e69e45d 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -1,4 +1,5 @@ use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; +use core::iter; use foundry_compilers::{ artifacts::{EvmVersion, Libraries, Severity}, error::SolcError, @@ -21,7 +22,10 @@ use foundry_zksync_compilers::{ }; use semver::Version; use serde::{Deserialize, Serialize}; -use std::{collections::HashSet, path::PathBuf}; +use std::{ + collections::{BTreeMap, HashSet}, + path::PathBuf, +}; use crate::{Config, SkipBuildFilters, SolcReq}; @@ -114,6 +118,7 @@ impl ZkSyncConfig { libraries: Libraries, evm_version: EvmVersion, via_ir: bool, + zksolc_version: Option, ) -> ZkSolcSettings { let optimizer = Optimizer { enabled: Some(self.optimizer), @@ -144,6 +149,7 @@ impl ZkSyncConfig { codegen: if self.force_evmla { Codegen::EVMLA } else { Codegen::Yul }, suppressed_warnings: self.suppressed_warnings.clone(), suppressed_errors: self.suppressed_errors.clone(), + zksolc_version, }; // `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput` @@ -163,7 +169,14 @@ pub fn config_zksolc_settings(config: &Config) -> Result return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))), }; - Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir)) + let x = as Clone>::clone(&config.zksync.zksolc).unwrap(); + let version = x + .try_version() + .map_err(|e| SolcError::msg(format!("Failed to parse zksolc version: {e}")))?; + + print!("version: {:?}", version); + + Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir, Some(version))) } /// Create a new zkSync project @@ -172,10 +185,18 @@ pub fn config_create_project( cached: bool, no_artifacts: bool, ) -> Result, SolcError> { + let settings = config_zksolc_settings(config)?; + + print!("settings: {:?}", settings); + let mut builder = ProjectBuilder::::default() .artifacts(ZkArtifactOutput {}) .paths(config_project_paths(config)) - .settings(config_zksolc_settings(config)?) + .settings(settings.clone()) + .additional_settings(BTreeMap::from_iter(iter::once(( + "zksyn2c".to_string(), + settings.into(), + )))) .ignore_error_codes(config.ignored_error_codes.iter().copied().map(Into::into)) .ignore_paths(config.ignored_file_paths.clone()) .set_compiler_severity_filter(if config.deny_warnings { @@ -211,6 +232,11 @@ pub fn config_create_project( let zksolc_compiler = ZkSolcCompiler { zksolc, solc: config_solc_compiler(config)? }; + // builder.additional_settings(BTreeMap::from_iter(iter::once(( + // "zksync".to_string(), + // settings.into(), + // )))); + let project = builder.build(zksolc_compiler)?; if config.force { diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index 904175666d..bcea0cc9ba 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -87,6 +87,9 @@ pub struct ZkSettings { /// Suppressed `zksolc` errors. #[serde(default, skip_serializing_if = "HashSet::is_empty")] pub suppressed_errors: HashSet, + /// The version of the zksolc compiler to use. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub zksolc_version: Option, } /// Analogous to SolcSettings for zksolc compiler @@ -167,6 +170,7 @@ impl Default for ZkSettings { codegen: Default::default(), suppressed_errors: Default::default(), suppressed_warnings: Default::default(), + zksolc_version: None, } } } @@ -206,6 +210,7 @@ impl CompilerSettings for ZkSolcSettings { codegen, suppressed_warnings, suppressed_errors, + zksolc_version, }, .. } = self; @@ -222,7 +227,8 @@ impl CompilerSettings for ZkSolcSettings { *force_evmla == other.settings.force_evmla && *codegen == other.settings.codegen && *suppressed_warnings == other.settings.suppressed_warnings && - *suppressed_errors == other.settings.suppressed_errors + *suppressed_errors == other.settings.suppressed_errors && + *zksolc_version == other.settings.zksolc_version } fn with_remappings(mut self, remappings: &[Remapping]) -> Self { From ba1e537ce9e0ecbd44e30b5817d85d23d3e9e2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 13:15:06 -0300 Subject: [PATCH 02/17] Refactoring a little bit --- crates/config/src/zksync.rs | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 270e69e45d..888d7c7633 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -1,5 +1,4 @@ use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; -use core::iter; use foundry_compilers::{ artifacts::{EvmVersion, Libraries, Severity}, error::SolcError, @@ -22,10 +21,7 @@ use foundry_zksync_compilers::{ }; use semver::Version; use serde::{Deserialize, Serialize}; -use std::{ - collections::{BTreeMap, HashSet}, - path::PathBuf, -}; +use std::{collections::HashSet, path::PathBuf}; use crate::{Config, SkipBuildFilters, SolcReq}; @@ -169,8 +165,11 @@ pub fn config_zksolc_settings(config: &Config) -> Result return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))), }; - let x = as Clone>::clone(&config.zksync.zksolc).unwrap(); - let version = x + let version = config + .zksync + .zksolc + .clone() + .ok_or_else(|| SolcError::msg("zksolc version is not set"))? .try_version() .map_err(|e| SolcError::msg(format!("Failed to parse zksolc version: {e}")))?; @@ -185,18 +184,10 @@ pub fn config_create_project( cached: bool, no_artifacts: bool, ) -> Result, SolcError> { - let settings = config_zksolc_settings(config)?; - - print!("settings: {:?}", settings); - let mut builder = ProjectBuilder::::default() .artifacts(ZkArtifactOutput {}) .paths(config_project_paths(config)) - .settings(settings.clone()) - .additional_settings(BTreeMap::from_iter(iter::once(( - "zksyn2c".to_string(), - settings.into(), - )))) + .settings(config_zksolc_settings(config)?) .ignore_error_codes(config.ignored_error_codes.iter().copied().map(Into::into)) .ignore_paths(config.ignored_file_paths.clone()) .set_compiler_severity_filter(if config.deny_warnings { @@ -232,11 +223,6 @@ pub fn config_create_project( let zksolc_compiler = ZkSolcCompiler { zksolc, solc: config_solc_compiler(config)? }; - // builder.additional_settings(BTreeMap::from_iter(iter::once(( - // "zksync".to_string(), - // settings.into(), - // )))); - let project = builder.build(zksolc_compiler)?; if config.force { From d6401ecd66380bfd80e57cdf06b6eb011e777639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 15:36:36 -0300 Subject: [PATCH 03/17] Adding a test that proves this works now --- crates/config/src/zksync.rs | 2 - crates/forge/tests/it/zk/config.rs | 17 ++++++ crates/forge/tests/it/zk/linking.rs | 49 +++++++++++++++- crates/zksync/compilers/tests/zksync_tests.rs | 58 +++++++++++++++++++ 4 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 crates/forge/tests/it/zk/config.rs diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 888d7c7633..56cf29c48b 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -347,8 +347,6 @@ mod tests { use foundry_compilers::solc::SolcCompiler; use semver::Version; - use crate::Config; - use super::*; #[test] diff --git a/crates/forge/tests/it/zk/config.rs b/crates/forge/tests/it/zk/config.rs new file mode 100644 index 0000000000..f81d4316a2 --- /dev/null +++ b/crates/forge/tests/it/zk/config.rs @@ -0,0 +1,17 @@ + // test that checks that you have to recompile the project if the zksolc version changes (the + // cache is invalidated) + #[test] + fn zksync_project_has_zksync_solc_when_solc_req_is_a_version_and_zksolc_version_changes() { + let zk_config = zk_config(); + + let config = + Config { zksolc: Some(SolcReq::Version(Version::new(0, 8, 26))), ..Default::default() }; + let project = config_create_project(&config, false, true).unwrap(); + let solc_compiler = project.compiler.solc; + if let SolcCompiler::Specific(path) = solc_compiler { + let version = get_solc_version_info(&path.solc).unwrap(); + assert!(version.zksync_version.is_some()); + } else { + panic!("Expected SolcCompiler::Specific"); + } + } \ No newline at end of file diff --git a/crates/forge/tests/it/zk/linking.rs b/crates/forge/tests/it/zk/linking.rs index 4bdd728b7e..0ea0488b6b 100644 --- a/crates/forge/tests/it/zk/linking.rs +++ b/crates/forge/tests/it/zk/linking.rs @@ -1,6 +1,5 @@ -use foundry_test_utils::{forgetest_async, util, TestProject}; - use crate::test_helpers::{deploy_zk_contract, run_zk_script_test}; +use foundry_test_utils::{forgetest_async, util, TestProject}; // TODO(zk): add test that actually does the deployment // of the unlinked contract via script, once recursive linking is supported @@ -53,3 +52,49 @@ fn setup_libs_prj(prj: &mut TestProject) { ) .unwrap(); } + +// test that checks that you have to recompile the project if the zksolc version changes (the +// cache is invalidated) +// step 1, create a config with a specific zksolc version i.e 1.5.6 +// step 2, create a project with the config +// compile the project +// check that output contains the zksolc version 1.5.6 +// step 3, create a new config with a different zksolc version i.e 1.5.7 +// step 4, create a project with the new config +// compile the project +// check that output contains the zksolc version 1.5.7 (demonstrating that the cache was +// invalidated, and the project was recompiled) compile the project again, +// check the output once more it should say that the cache is ok +// forgetest_async!( +// zksync_project_has_zksync_solc_when_solc_req_is_a_version_and_zksolc_version_changes, +// |prj, cmd| { +// let mut zk_config = ForgeTestProfile::Default.zk_config(); + +// let project = config_create_project(&zk_config, false, true).unwrap(); + +// let version = get_solc_version_info(&path.solc).unwrap(); +// assert!(version.zksync_version.is_some()); +// assert_eq!(version.zksync_version.unwrap(), Version::new(1, 5, 6)); + +// zk_config.zksync.zksolc = Some(SolcReq::Version(Version::new(1, 5, 7))); +// let project = config_create_project(&zk_config, false, true).unwrap(); +// let solc_compiler = project.compiler.solc; +// if let SolcCompiler::Specific(path) = solc_compiler { +// let version = get_solc_version_info(&path.solc).unwrap(); +// assert!(version.zksync_version.is_some()); +// assert_eq!(version.zksync_version.unwrap(), Version::new(1, 5, 7)); +// } else { +// panic!("Expected SolcCompiler::Specific"); +// } + +// let project = config_create_project(&zk_config, false, true).unwrap(); +// let solc_compiler = project.compiler.solc; +// if let SolcCompiler::Specific(path) = solc_compiler { +// let version = get_solc_version_info(&path.solc).unwrap(); +// assert!(version.zksync_version.is_some()); +// assert_eq!(version.zksync_version.unwrap(), Version::new(1, 5, 7)); +// } else { +// panic!("Expected SolcCompiler::Specific"); +// } +// } +// ); diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index bb3e4a2d1b..a77d4ede86 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -1,3 +1,4 @@ +use core::{assert_eq, assert_ne}; use std::{ collections::{HashMap, HashSet}, fs, @@ -5,6 +6,7 @@ use std::{ str::FromStr, }; +use foundry_compilers::solc::Solc; use foundry_compilers_artifacts_solc::Remapping; use foundry_test_utils::foundry_compilers::{ buildinfo::BuildInfo, cache::CompilerCache, project_util::*, resolver::parse::SolData, @@ -654,3 +656,59 @@ fn zksync_can_compile_yul_sample() { assert!(!yul_bytecode.is_empty(), "SimpleStore bytecode is empty"); } + +// Test that checks that you have to recompile the project if the zksolc version changes (the +// cache is invalidated) +#[test] +fn zksync_detects_change_on_cache_if_zksolc_version_changes() { + let mut project = TempProject::::dapptools().unwrap(); + let solc = + Solc::find_or_install(&semver::Version::new(0, 8, 19)).expect("could not install solc"); + + project.project_mut().build_info = true; + project + .add_source( + "A", + r#" +pragma solidity ^0.8.10; +import "./B.sol"; +contract A { } +"#, + ) + .unwrap(); + + project + .add_source( + "B", + r" +pragma solidity ^0.8.10; +contract B { } +", + ) + .unwrap(); + + let config_1_5_6 = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 0)).unwrap(), + solc: foundry_compilers::solc::SolcCompiler::Specific(solc), + }; + project.project_mut().compiler = config_1_5_6; + + let compiled_1 = project.compile().unwrap(); + compiled_1.assert_success(); + + let cache = CompilerCache::::read(project.cache_path()).unwrap(); + + let config_1_5_7 = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 10)).unwrap(), + solc: Default::default(), + }; + project.project_mut().compiler = config_1_5_7; + + let compiled_2 = project.compile().unwrap(); + + assert!(!compiled_2.is_unchanged()); + + let latest_cache = CompilerCache::::read(project.cache_path()).unwrap(); + + assert_ne!(cache, latest_cache); +} From 5fc3aab9ef386f8cd568c2811dc7581bdb9c5a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 19:09:15 -0300 Subject: [PATCH 04/17] Adding the right test --- crates/forge/tests/cli/zk_build.rs | 71 +++++++++++++++++++ crates/forge/tests/it/zk/config.rs | 17 ----- crates/forge/tests/it/zk/linking.rs | 46 ------------ crates/zksync/compilers/tests/zksync_tests.rs | 57 --------------- 4 files changed, 71 insertions(+), 120 deletions(-) delete mode 100644 crates/forge/tests/it/zk/config.rs diff --git a/crates/forge/tests/cli/zk_build.rs b/crates/forge/tests/cli/zk_build.rs index aa350886b0..2cc6886bc4 100644 --- a/crates/forge/tests/cli/zk_build.rs +++ b/crates/forge/tests/cli/zk_build.rs @@ -1,3 +1,4 @@ +use foundry_common::fs; use foundry_test_utils::util::OutputExt; use regex::Regex; @@ -11,3 +12,73 @@ forgetest_init!(test_zk_build_sizes, |prj, cmd| { assert!(pattern.is_match(&stdout), "Unexpected size output:\n{stdout}"); }); + +// tests build output is as expected in zksync mode +forgetest_init!(test_zk_cache, |prj, cmd| { + let zk_toml = r#"[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] +solc = '0.8.26' + +[profile.default.zksync] +zksolc = '1.5.6' +"#; + + fs::write(prj.root().join("foundry.toml"), zk_toml).unwrap(); + + cmd.args(["build", "--zksync"]); + let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); + + let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_2 = Regex::new(r"No files changed, compilation skipped").unwrap(); + + assert!(pattern_1.is_match(&stdout_1)); + assert!(pattern_2.is_match(&stdout_2)); + + // assert!(pattern.is_match(&stdout), "Unexpected size output:\n{stdout}"); +}); + +// tests build output is as expected in zksync mode +forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { + let template_toml = r#"[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] +solc = '0.8.26' + +[profile.default.zksync] +"#; + + let toml_156 = format!( + r#"{} +zksolc = '1.5.6' +"#, + template_toml + ); + + let toml_157 = format!( + r#"{} +zksolc = '1.5.7' +"#, + template_toml + ); + + fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); + + cmd.args(["build", "--zksync"]); + let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); + + fs::remove_file(prj.root().join("foundry.toml")).unwrap(); + fs::write(prj.root().join("foundry.toml"), toml_157).unwrap(); + + let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_2 = Regex::new(r"Compiler run successful!").unwrap(); // if we see this, means the cache was invalidated + + assert!(pattern_1.is_match(&stdout_1)); + assert!(pattern_2.is_match(&stdout_2)); + + // assert!(pattern.is_match(&stdout), "Unexpected size output:\n{stdout}"); +}); diff --git a/crates/forge/tests/it/zk/config.rs b/crates/forge/tests/it/zk/config.rs deleted file mode 100644 index f81d4316a2..0000000000 --- a/crates/forge/tests/it/zk/config.rs +++ /dev/null @@ -1,17 +0,0 @@ - // test that checks that you have to recompile the project if the zksolc version changes (the - // cache is invalidated) - #[test] - fn zksync_project_has_zksync_solc_when_solc_req_is_a_version_and_zksolc_version_changes() { - let zk_config = zk_config(); - - let config = - Config { zksolc: Some(SolcReq::Version(Version::new(0, 8, 26))), ..Default::default() }; - let project = config_create_project(&config, false, true).unwrap(); - let solc_compiler = project.compiler.solc; - if let SolcCompiler::Specific(path) = solc_compiler { - let version = get_solc_version_info(&path.solc).unwrap(); - assert!(version.zksync_version.is_some()); - } else { - panic!("Expected SolcCompiler::Specific"); - } - } \ No newline at end of file diff --git a/crates/forge/tests/it/zk/linking.rs b/crates/forge/tests/it/zk/linking.rs index 0ea0488b6b..ac34fec255 100644 --- a/crates/forge/tests/it/zk/linking.rs +++ b/crates/forge/tests/it/zk/linking.rs @@ -52,49 +52,3 @@ fn setup_libs_prj(prj: &mut TestProject) { ) .unwrap(); } - -// test that checks that you have to recompile the project if the zksolc version changes (the -// cache is invalidated) -// step 1, create a config with a specific zksolc version i.e 1.5.6 -// step 2, create a project with the config -// compile the project -// check that output contains the zksolc version 1.5.6 -// step 3, create a new config with a different zksolc version i.e 1.5.7 -// step 4, create a project with the new config -// compile the project -// check that output contains the zksolc version 1.5.7 (demonstrating that the cache was -// invalidated, and the project was recompiled) compile the project again, -// check the output once more it should say that the cache is ok -// forgetest_async!( -// zksync_project_has_zksync_solc_when_solc_req_is_a_version_and_zksolc_version_changes, -// |prj, cmd| { -// let mut zk_config = ForgeTestProfile::Default.zk_config(); - -// let project = config_create_project(&zk_config, false, true).unwrap(); - -// let version = get_solc_version_info(&path.solc).unwrap(); -// assert!(version.zksync_version.is_some()); -// assert_eq!(version.zksync_version.unwrap(), Version::new(1, 5, 6)); - -// zk_config.zksync.zksolc = Some(SolcReq::Version(Version::new(1, 5, 7))); -// let project = config_create_project(&zk_config, false, true).unwrap(); -// let solc_compiler = project.compiler.solc; -// if let SolcCompiler::Specific(path) = solc_compiler { -// let version = get_solc_version_info(&path.solc).unwrap(); -// assert!(version.zksync_version.is_some()); -// assert_eq!(version.zksync_version.unwrap(), Version::new(1, 5, 7)); -// } else { -// panic!("Expected SolcCompiler::Specific"); -// } - -// let project = config_create_project(&zk_config, false, true).unwrap(); -// let solc_compiler = project.compiler.solc; -// if let SolcCompiler::Specific(path) = solc_compiler { -// let version = get_solc_version_info(&path.solc).unwrap(); -// assert!(version.zksync_version.is_some()); -// assert_eq!(version.zksync_version.unwrap(), Version::new(1, 5, 7)); -// } else { -// panic!("Expected SolcCompiler::Specific"); -// } -// } -// ); diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index a77d4ede86..927fbf0e7c 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -6,7 +6,6 @@ use std::{ str::FromStr, }; -use foundry_compilers::solc::Solc; use foundry_compilers_artifacts_solc::Remapping; use foundry_test_utils::foundry_compilers::{ buildinfo::BuildInfo, cache::CompilerCache, project_util::*, resolver::parse::SolData, @@ -656,59 +655,3 @@ fn zksync_can_compile_yul_sample() { assert!(!yul_bytecode.is_empty(), "SimpleStore bytecode is empty"); } - -// Test that checks that you have to recompile the project if the zksolc version changes (the -// cache is invalidated) -#[test] -fn zksync_detects_change_on_cache_if_zksolc_version_changes() { - let mut project = TempProject::::dapptools().unwrap(); - let solc = - Solc::find_or_install(&semver::Version::new(0, 8, 19)).expect("could not install solc"); - - project.project_mut().build_info = true; - project - .add_source( - "A", - r#" -pragma solidity ^0.8.10; -import "./B.sol"; -contract A { } -"#, - ) - .unwrap(); - - project - .add_source( - "B", - r" -pragma solidity ^0.8.10; -contract B { } -", - ) - .unwrap(); - - let config_1_5_6 = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 0)).unwrap(), - solc: foundry_compilers::solc::SolcCompiler::Specific(solc), - }; - project.project_mut().compiler = config_1_5_6; - - let compiled_1 = project.compile().unwrap(); - compiled_1.assert_success(); - - let cache = CompilerCache::::read(project.cache_path()).unwrap(); - - let config_1_5_7 = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 10)).unwrap(), - solc: Default::default(), - }; - project.project_mut().compiler = config_1_5_7; - - let compiled_2 = project.compile().unwrap(); - - assert!(!compiled_2.is_unchanged()); - - let latest_cache = CompilerCache::::read(project.cache_path()).unwrap(); - - assert_ne!(cache, latest_cache); -} From 82e9ca8108405b8297186bf350cec853b0a84b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 19:13:43 -0300 Subject: [PATCH 05/17] fmt --- crates/config/src/zksync.rs | 6 +++--- crates/forge/tests/cli/zk_build.rs | 4 ---- crates/forge/tests/it/zk/linking.rs | 3 ++- crates/zksync/compilers/tests/zksync_tests.rs | 1 - 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 56cf29c48b..fa54ed3ea5 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -173,12 +173,10 @@ pub fn config_zksolc_settings(config: &Config) -> Result Date: Fri, 24 Jan 2025 19:27:39 -0300 Subject: [PATCH 06/17] name --- crates/forge/tests/cli/zk_build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/forge/tests/cli/zk_build.rs b/crates/forge/tests/cli/zk_build.rs index 1e5cb1075d..9e6159dfa2 100644 --- a/crates/forge/tests/cli/zk_build.rs +++ b/crates/forge/tests/cli/zk_build.rs @@ -14,7 +14,7 @@ forgetest_init!(test_zk_build_sizes, |prj, cmd| { }); // tests build output is as expected in zksync mode -forgetest_init!(test_zk_cache, |prj, cmd| { +forgetest_init!(test_zk_cache_ok, |prj, cmd| { let zk_toml = r#"[profile.default] src = 'src' out = 'out' From 0384dcb293c0734da3e9a422c2769f83d866ae0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 19:35:46 -0300 Subject: [PATCH 07/17] clippy --- crates/forge/tests/cli/zk_build.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/forge/tests/cli/zk_build.rs b/crates/forge/tests/cli/zk_build.rs index 9e6159dfa2..6d7e4c417e 100644 --- a/crates/forge/tests/cli/zk_build.rs +++ b/crates/forge/tests/cli/zk_build.rs @@ -50,17 +50,15 @@ solc = '0.8.26' "#; let toml_156 = format!( - r#"{} + r#"{template_toml} zksolc = '1.5.6' -"#, - template_toml +"# ); let toml_157 = format!( - r#"{} + r#"{template_toml} zksolc = '1.5.7' -"#, - template_toml +"# ); fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); From ee16176232e40c8c8b303bc693df50255e665870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 19:56:26 -0300 Subject: [PATCH 08/17] changing the logic a little big, to avoid stuttering --- crates/config/src/zksync.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index fa54ed3ea5..e437bb4689 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -114,7 +114,6 @@ impl ZkSyncConfig { libraries: Libraries, evm_version: EvmVersion, via_ir: bool, - zksolc_version: Option, ) -> ZkSolcSettings { let optimizer = Optimizer { enabled: Some(self.optimizer), @@ -145,7 +144,7 @@ impl ZkSyncConfig { codegen: if self.force_evmla { Codegen::EVMLA } else { Codegen::Yul }, suppressed_warnings: self.suppressed_warnings.clone(), suppressed_errors: self.suppressed_errors.clone(), - zksolc_version, + zksolc_version: self.zksolc.as_ref().and_then(|req| req.try_version().ok()), }; // `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput` @@ -165,15 +164,7 @@ pub fn config_zksolc_settings(config: &Config) -> Result return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))), }; - let version = config - .zksync - .zksolc - .clone() - .ok_or_else(|| SolcError::msg("zksolc version is not set"))? - .try_version() - .map_err(|e| SolcError::msg(format!("Failed to parse zksolc version: {e}")))?; - - Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir, Some(version))) + Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir)) } /// Create a new ZKsync project From 79eb414d83f65ce266b000f61d92e5e8338ec7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Fri, 24 Jan 2025 19:58:44 -0300 Subject: [PATCH 09/17] comments --- crates/forge/tests/cli/zk_build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/forge/tests/cli/zk_build.rs b/crates/forge/tests/cli/zk_build.rs index 6d7e4c417e..207e9059ba 100644 --- a/crates/forge/tests/cli/zk_build.rs +++ b/crates/forge/tests/cli/zk_build.rs @@ -13,7 +13,7 @@ forgetest_init!(test_zk_build_sizes, |prj, cmd| { assert!(pattern.is_match(&stdout), "Unexpected size output:\n{stdout}"); }); -// tests build output is as expected in zksync mode +// tests cache works as expected in zksync mode forgetest_init!(test_zk_cache_ok, |prj, cmd| { let zk_toml = r#"[profile.default] src = 'src' @@ -38,7 +38,7 @@ zksolc = '1.5.6' assert!(pattern_2.is_match(&stdout_2)); }); -// tests build output is as expected in zksync mode +// tests cache is invalidated when zksolc version changes forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { let template_toml = r#"[profile.default] src = 'src' From af26a8c3a4fb47dd3445439ab0a2d1a072502665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Mon, 27 Jan 2025 12:44:32 -0300 Subject: [PATCH 10/17] PR feedback mostly moving things around --- Cargo.lock | 1 + crates/common/src/compile.rs | 2 +- crates/config/src/zksync.rs | 7 +- crates/forge/tests/cli/zk_build.rs | 65 ------------------ crates/zksync/compilers/Cargo.toml | 2 + .../compilers/src/compilers/zksolc/input.rs | 2 +- .../src/compilers/zksolc/settings.rs | 10 ++- crates/zksync/compilers/src/lib.rs | 2 + crates/zksync/compilers/tests/zksync_tests.rs | 68 +++++++++++++++++++ 9 files changed, 84 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af28454e47..8abb1836e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5262,6 +5262,7 @@ dependencies = [ "fs4 0.8.4", "itertools 0.13.0", "path-slash", + "regex", "reqwest 0.12.9", "semver 1.0.23", "serde", diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs index 16ea94fc88..8a853c43f9 100644 --- a/crates/common/src/compile.rs +++ b/crates/common/src/compile.rs @@ -193,7 +193,7 @@ impl ProjectCompiler { let quiet = self.quiet.unwrap_or(false); let bail = self.bail.unwrap_or(true); - let output = with_compilation_reporter(quiet, || { + let output = with_compilation_reporter(self.quiet.unwrap_or(false), || { tracing::debug!("compiling project"); let timer = Instant::now(); diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index e437bb4689..db43fb9c92 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -144,11 +144,14 @@ impl ZkSyncConfig { codegen: if self.force_evmla { Codegen::EVMLA } else { Codegen::Yul }, suppressed_warnings: self.suppressed_warnings.clone(), suppressed_errors: self.suppressed_errors.clone(), - zksolc_version: self.zksolc.as_ref().and_then(|req| req.try_version().ok()), }; // `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput` - ZkSolcSettings { settings: zk_settings, cli_settings: CliSettings::default() } + ZkSolcSettings { + settings: zk_settings, + cli_settings: CliSettings::default(), + zksolc_version: None, + } } } diff --git a/crates/forge/tests/cli/zk_build.rs b/crates/forge/tests/cli/zk_build.rs index 207e9059ba..aa350886b0 100644 --- a/crates/forge/tests/cli/zk_build.rs +++ b/crates/forge/tests/cli/zk_build.rs @@ -1,4 +1,3 @@ -use foundry_common::fs; use foundry_test_utils::util::OutputExt; use regex::Regex; @@ -12,67 +11,3 @@ forgetest_init!(test_zk_build_sizes, |prj, cmd| { assert!(pattern.is_match(&stdout), "Unexpected size output:\n{stdout}"); }); - -// tests cache works as expected in zksync mode -forgetest_init!(test_zk_cache_ok, |prj, cmd| { - let zk_toml = r#"[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -solc = '0.8.26' - -[profile.default.zksync] -zksolc = '1.5.6' -"#; - - fs::write(prj.root().join("foundry.toml"), zk_toml).unwrap(); - - cmd.args(["build", "--zksync"]); - let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); - - let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_2 = Regex::new(r"No files changed, compilation skipped").unwrap(); - - assert!(pattern_1.is_match(&stdout_1)); - assert!(pattern_2.is_match(&stdout_2)); -}); - -// tests cache is invalidated when zksolc version changes -forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { - let template_toml = r#"[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -solc = '0.8.26' - -[profile.default.zksync] -"#; - - let toml_156 = format!( - r#"{template_toml} -zksolc = '1.5.6' -"# - ); - - let toml_157 = format!( - r#"{template_toml} -zksolc = '1.5.7' -"# - ); - - fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); - - cmd.args(["build", "--zksync"]); - let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); - - fs::remove_file(prj.root().join("foundry.toml")).unwrap(); - fs::write(prj.root().join("foundry.toml"), toml_157).unwrap(); - - let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_2 = Regex::new(r"Compiler run successful!").unwrap(); // if we see this, means the cache was invalidated - - assert!(pattern_1.is_match(&stdout_1)); - assert!(pattern_2.is_match(&stdout_2)); -}); diff --git a/crates/zksync/compilers/Cargo.toml b/crates/zksync/compilers/Cargo.toml index 75168a002b..851f6c3756 100644 --- a/crates/zksync/compilers/Cargo.toml +++ b/crates/zksync/compilers/Cargo.toml @@ -38,3 +38,5 @@ similar-asserts.workspace = true fd-lock = "4.0.2" tempfile.workspace = true foundry-test-utils.workspace = true +regex = { workspace = true, default-features = false } + diff --git a/crates/zksync/compilers/src/compilers/zksolc/input.rs b/crates/zksync/compilers/src/compilers/zksolc/input.rs index ffa4cbdc76..a957fc593b 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/input.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/input.rs @@ -40,7 +40,7 @@ impl CompilerInput for ZkSolcVersionedInput { language: Self::Language, version: Version, ) -> Self { - let ZkSolcSettings { settings, cli_settings } = settings; + let ZkSolcSettings { settings, cli_settings, .. } = settings; let input = ZkSolcInput::new(language, sources, settings).sanitized(&version); Self { solc_version: version, input, cli_settings } diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index bcea0cc9ba..8320428120 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -87,9 +87,6 @@ pub struct ZkSettings { /// Suppressed `zksolc` errors. #[serde(default, skip_serializing_if = "HashSet::is_empty")] pub suppressed_errors: HashSet, - /// The version of the zksolc compiler to use. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub zksolc_version: Option, } /// Analogous to SolcSettings for zksolc compiler @@ -102,6 +99,9 @@ pub struct ZkSolcSettings { /// Additional CLI args configuration #[serde(flatten)] pub cli_settings: solc::CliSettings, + /// The version of the zksolc compiler to use. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub zksolc_version: Option, } impl ZkSettings { @@ -170,7 +170,6 @@ impl Default for ZkSettings { codegen: Default::default(), suppressed_errors: Default::default(), suppressed_warnings: Default::default(), - zksolc_version: None, } } } @@ -210,7 +209,6 @@ impl CompilerSettings for ZkSolcSettings { codegen, suppressed_warnings, suppressed_errors, - zksolc_version, }, .. } = self; @@ -228,7 +226,7 @@ impl CompilerSettings for ZkSolcSettings { *codegen == other.settings.codegen && *suppressed_warnings == other.settings.suppressed_warnings && *suppressed_errors == other.settings.suppressed_errors && - *zksolc_version == other.settings.zksolc_version + self.zksolc_version == other.zksolc_version } fn with_remappings(mut self, remappings: &[Remapping]) -> Self { diff --git a/crates/zksync/compilers/src/lib.rs b/crates/zksync/compilers/src/lib.rs index 4316c45df1..d91d856d70 100644 --- a/crates/zksync/compilers/src/lib.rs +++ b/crates/zksync/compilers/src/lib.rs @@ -13,4 +13,6 @@ pub mod libraries; #[cfg(test)] use foundry_test_utils as _; #[cfg(test)] +use regex as _; +#[cfg(test)] use tempfile as _; diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index bb3e4a2d1b..aa49cf6f0b 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -12,6 +12,7 @@ use foundry_test_utils::foundry_compilers::{ }; use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; +use foundry_test_utils::{forgetest_init, util::OutputExt}; use foundry_zksync_compilers::{ artifacts::{contract::Contract, error::Error}, compilers::{ @@ -19,6 +20,7 @@ use foundry_zksync_compilers::{ zksolc::{input::ZkSolcInput, ZkSolc, ZkSolcCompiler, ZkSolcSettings}, }, }; +use regex::Regex; #[test] fn zksync_can_compile_dapp_sample() { @@ -654,3 +656,69 @@ fn zksync_can_compile_yul_sample() { assert!(!yul_bytecode.is_empty(), "SimpleStore bytecode is empty"); } + +forgetest_init!(test_zk_cache_ok, |prj, cmd| { + let zk_toml = r#"[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] +solc = '0.8.26' + +[profile.default.zksync] +zksolc = '1.5.6' +"#; + + fs::write(prj.root().join("foundry.toml"), zk_toml).unwrap(); + + cmd.args(["build", "--zksync"]); + let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); + + let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_2 = Regex::new(r"No files changed, compilation skipped").unwrap(); + + assert!(pattern_1.is_match(&stdout_1)); + assert!(pattern_2.is_match(&stdout_2)); +}); + +// tests cache is invalidated when zksolc version changes +forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { + let template_toml = r#"[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] +solc = '0.8.26' + +[profile.default.zksync] +"#; + + let toml_156 = format!( + r#"{template_toml} +zksolc = '1.5.6' +"# + ); + + let toml_157 = format!( + r#"{template_toml} +zksolc = '1.5.7' +"# + ); + + fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); + + cmd.args(["build", "--zksync"]); + let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); + + fs::remove_file(prj.root().join("foundry.toml")).unwrap(); + fs::write(prj.root().join("foundry.toml"), toml_157).unwrap(); + + let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); + let pattern_2 = Regex::new(r"Compiler run successful!").unwrap(); // if we see this, means the cache was invalidated + + print!("stdout_1: {}", stdout_1); + print!("stdout_2: {}", stdout_2); + + assert!(pattern_1.is_match(&stdout_1)); + assert!(pattern_2.is_match(&stdout_2)); +}); From c177bfcfc863b3fce7122a7462987f824713d9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Mon, 27 Jan 2025 13:07:08 -0300 Subject: [PATCH 11/17] Getting the zksolc_version for path as well --- crates/config/src/zksync.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index db43fb9c92..e10c63bd32 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -146,11 +146,17 @@ impl ZkSyncConfig { suppressed_errors: self.suppressed_errors.clone(), }; + let zksolc_version = self.zksolc.as_ref().map(|req| match req { + SolcReq::Version(version) => version.clone(), + SolcReq::Local(path) => ZkSolc::get_version_for_path(path) + .unwrap_or_else(|_| panic!("Could not find zksolc version for this path")), + }); + // `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput` ZkSolcSettings { settings: zk_settings, cli_settings: CliSettings::default(), - zksolc_version: None, + zksolc_version, } } } From 3db5b6a847184c9eefa930a3abeaa831c6eca11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Mon, 27 Jan 2025 16:29:12 -0300 Subject: [PATCH 12/17] calling the logic that ensures a default --- crates/config/src/zksync.rs | 39 +++++++++++-------- .../src/compilers/zksolc/settings.rs | 18 +++++++-- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index e0a6f2846a..a3d8f53440 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -114,6 +114,7 @@ impl ZkSyncConfig { libraries: Libraries, evm_version: EvmVersion, via_ir: bool, + offline: bool, ) -> ZkSolcSettings { let optimizer = Optimizer { enabled: Some(self.optimizer), @@ -146,17 +147,15 @@ impl ZkSyncConfig { suppressed_errors: self.suppressed_errors.clone(), }; - let zksolc_version = self.zksolc.as_ref().map(|req| match req { - SolcReq::Version(version) => version.clone(), - SolcReq::Local(path) => ZkSolc::get_version_for_path(path) - .unwrap_or_else(|_| panic!("Could not find zksolc version for this path")), - }); + let zksolc_path = get_zksolc_compiler(self.zksolc.as_ref(), offline) + .unwrap_or_else(|e| panic!("Could not find zksolc compiler: {e}")); // `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput` ZkSolcSettings { settings: zk_settings, cli_settings: CliSettings::default(), - zksolc_version, + zksolc_version: ZkSolc::get_version_for_path(zksolc_path.as_ref()) + .unwrap_or_else(|_| panic!("Could not find zksolc version for this path")), } } } @@ -173,19 +172,14 @@ pub fn config_zksolc_settings(config: &Config) -> Result return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))), }; - Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir)) + Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir, config.offline)) } -/// Return the configured `zksolc` compiler -/// -/// If not `offline`, will install the default version automatically -/// Will fallback to `zksolc` present in the environment -pub fn config_zksolc_compiler(config: &Config) -> Result { - let zksolc = if let Some(zksolc) = - config_ensure_zksolc(config.zksync.zksolc.as_ref(), config.offline)? - { +/// get the configured `zksolc` compiler +pub fn get_zksolc_compiler(zksolc: Option<&SolcReq>, offline: bool) -> Result { + let zksolc = if let Some(zksolc) = config_ensure_zksolc(zksolc, offline)? { zksolc - } else if !config.offline { + } else if !offline { let default_version = semver::Version::new(1, 5, 10); let mut zksolc = ZkSolc::find_installed_version(&default_version)?; if zksolc.is_none() { @@ -197,7 +191,18 @@ pub fn config_zksolc_compiler(config: &Config) -> Result Result { + Ok(ZkSolcCompiler { + zksolc: get_zksolc_compiler(config.zksync.zksolc.as_ref(), config.offline)?, + solc: config_solc_compiler(config)?, + }) } /// Create a new ZKsync project diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index 8320428120..4866618c76 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -15,6 +15,8 @@ use std::{ path::{Path, PathBuf}, str::FromStr, }; + +use super::{ZkSolc, ZkSolcCompiler}; /// /// The Solidity compiler codegen. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -90,7 +92,7 @@ pub struct ZkSettings { } /// Analogous to SolcSettings for zksolc compiler -#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct ZkSolcSettings { /// JSON settings expected by Solc @@ -100,8 +102,18 @@ pub struct ZkSolcSettings { #[serde(flatten)] pub cli_settings: solc::CliSettings, /// The version of the zksolc compiler to use. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub zksolc_version: Option, + pub zksolc_version: Version, +} + +impl Default for ZkSolcSettings { + fn default() -> Self { + Self { + settings: Default::default(), + cli_settings: Default::default(), + zksolc_version: ZkSolc::get_version_for_path(ZkSolcCompiler::default().zksolc.as_ref()) + .expect("Failed to get zksolc version"), + } + } } impl ZkSettings { From 2b7b3218dab4d33b6e59ea3cc96b300249d2a0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn?= Date: Mon, 27 Jan 2025 19:51:39 -0300 Subject: [PATCH 13/17] new tests --- .../compilers/src/compilers/zksolc/mod.rs | 6 +- .../src/compilers/zksolc/settings.rs | 2 + crates/zksync/compilers/tests/zksync_tests.rs | 245 +++++++++++++----- 3 files changed, 194 insertions(+), 59 deletions(-) diff --git a/crates/zksync/compilers/src/compilers/zksolc/mod.rs b/crates/zksync/compilers/src/compilers/zksolc/mod.rs index 6159919430..35fecfc06a 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/mod.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/mod.rs @@ -40,7 +40,7 @@ pub const ZKSOLC: &str = "zksolc"; /// ZKsync solc release used for all ZKsync solc versions pub const ZKSYNC_SOLC_RELEASE: Version = Version::new(1, 0, 1); /// Default zksolc version -pub const ZKSOLC_VERSION: Version = Version::new(1, 5, 10); +pub const ZKSOLC_VERSION: Version = Version::new(1, 5, 9); #[cfg(test)] macro_rules! take_solc_installer_lock { @@ -151,7 +151,11 @@ impl Compiler for ZkSolcCompiler { ) -> Result> { let zksolc = self.zksolc(input)?; + println!("paso por aca 1"); + let mut zk_output = zksolc.compile(&input.input)?; + println!("zk_output {:?}", zk_output); + let mut metadata = BTreeMap::new(); if let Some(solc_version) = zk_output.version.take() { metadata.insert("solcVersion".to_string(), solc_version.into()); diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index 4866618c76..7f804fb77b 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -225,6 +225,8 @@ impl CompilerSettings for ZkSolcSettings { .. } = self; + println!("ybue: zksolc_version: {:?}", self.zksolc_version); + *via_ir == other.settings.via_ir && *remappings == other.settings.remappings && *evm_version == other.settings.evm_version && diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index aa49cf6f0b..d8de00315e 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -5,6 +5,7 @@ use std::{ str::FromStr, }; +use foundry_compilers::ProjectCompileOutput; use foundry_compilers_artifacts_solc::Remapping; use foundry_test_utils::foundry_compilers::{ buildinfo::BuildInfo, cache::CompilerCache, project_util::*, resolver::parse::SolData, @@ -58,6 +59,7 @@ fn test_zksync_can_compile_contract_with_suppressed_errors(compiler: ZkSolcCompi // .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) // .try_init() // .ok(); + let mut project = TempProject::::dapptools().unwrap(); project.project_mut().compiler = compiler; @@ -78,16 +80,59 @@ fn test_zksync_can_compile_contract_with_suppressed_errors(compiler: ZkSolcCompi .unwrap(); let compiled = project.compile().unwrap(); + assert!(compiled.has_compiler_errors()); project.project_mut().settings.settings.suppressed_errors = HashSet::from([ErrorType::SendTransfer]); let compiled = project.compile().unwrap(); + + let cache = CompilerCache::::read(project.cache_path()).unwrap(); + print!("CAAACHEE {:?}", cache); + compiled.assert_success(); assert!(compiled.find_first("Erroneous").is_some()); } +fn test_zksync_can_compile_with_version( + project: &mut TempProject, + compiler: ZkSolcCompiler, +) -> ProjectCompileOutput { + // let _ = tracing_subscriber::fmt() + // .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + // .try_init() + // .ok(); + + project.project_mut().compiler = compiler; + + project + .add_source( + "A", + r#" +pragma solidity ^0.8.10; +import "./B.sol"; +contract A { } +"#, + ) + .unwrap(); + + project + .add_source( + "B", + r" +pragma solidity ^0.8.10; +contract B { } +", + ) + .unwrap(); + + project.project_mut().settings.settings.suppressed_errors = + HashSet::from([ErrorType::SendTransfer]); + + project.compile().unwrap() +} + #[test] fn zksync_can_compile_contract_with_suppressed_errors() { test_zksync_can_compile_contract_with_suppressed_errors(ZkSolcCompiler::default()); @@ -657,68 +702,152 @@ fn zksync_can_compile_yul_sample() { assert!(!yul_bytecode.is_empty(), "SimpleStore bytecode is empty"); } -forgetest_init!(test_zk_cache_ok, |prj, cmd| { - let zk_toml = r#"[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -solc = '0.8.26' - -[profile.default.zksync] -zksolc = '1.5.6' -"#; - - fs::write(prj.root().join("foundry.toml"), zk_toml).unwrap(); - - cmd.args(["build", "--zksync"]); - let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); - - let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_2 = Regex::new(r"No files changed, compilation skipped").unwrap(); - - assert!(pattern_1.is_match(&stdout_1)); - assert!(pattern_2.is_match(&stdout_2)); -}); - -// tests cache is invalidated when zksolc version changes -forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { - let template_toml = r#"[profile.default] -src = 'src' -out = 'out' -libs = ['lib'] -solc = '0.8.26' - -[profile.default.zksync] -"#; - - let toml_156 = format!( - r#"{template_toml} -zksolc = '1.5.6' -"# - ); +// forgetest_init!(test_zk_cache_ok, |prj, cmd| { +// let zk_toml = r#"[profile.default] +// src = 'src' +// out = 'out' +// libs = ['lib'] +// solc = '0.8.26' - let toml_157 = format!( - r#"{template_toml} -zksolc = '1.5.7' -"# - ); +// [profile.default.zksync] +// zksolc = '1.5.6' +// "#; + +// fs::write(prj.root().join("foundry.toml"), zk_toml).unwrap(); + +// cmd.args(["build", "--zksync"]); +// let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); +// let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); + +// let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); +// let pattern_2 = Regex::new(r"No files changed, compilation skipped").unwrap(); + +// assert!(pattern_1.is_match(&stdout_1)); +// assert!(pattern_2.is_match(&stdout_2)); +// }); + +// // tests cache is invalidated when zksolc version changes +// forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { +// let template_toml = r#"[profile.default] +// src = 'src' +// out = 'out' +// libs = ['lib'] +// solc = '0.8.26' + +// [profile.default.zksync] +// "#; + +// let toml_156 = format!( +// r#"{template_toml} +// zksolc = '1.5.6' +// "# +// ); + +// let toml_157 = format!( +// r#"{template_toml} +// zksolc = '1.5.7' +// "# +// ); + +// fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); + +// cmd.args(["build", "--zksync"]); +// let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); +// let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); + +// fs::remove_file(prj.root().join("foundry.toml")).unwrap(); +// fs::write(prj.root().join("foundry.toml"), toml_157).unwrap(); + +// let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); +// let pattern_2 = Regex::new(r"Compiler run successful!").unwrap(); // if we see this, means +// the cache was invalidated + +// print!("stdout_1: {}", stdout_1); +// print!("stdout_2: {}", stdout_2); - fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); +// assert!(pattern_1.is_match(&stdout_1)); +// assert!(pattern_2.is_match(&stdout_2)); +// }); - cmd.args(["build", "--zksync"]); - let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); +// Test that checks that you have to recompile the project if the zksolc version changes (the +// cache is invalidated) - fs::remove_file(prj.root().join("foundry.toml")).unwrap(); - fs::write(prj.root().join("foundry.toml"), toml_157).unwrap(); +#[test] +fn zksync_detects_change_on_cache_if_zksolc_version_changes() { + let mut project = TempProject::::dapptools().unwrap(); + + project.project_mut().build_info = true; + project + .add_source( + "A", + r#" +pragma solidity ^0.8.10; +import "./B.sol"; +contract A { } +"#, + ) + .unwrap(); + + project + .add_source( + "B", + r" +pragma solidity ^0.8.10; +contract B { } +", + ) + .unwrap(); + + let config_1_5_6 = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 6)).unwrap(), + solc: Default::default(), + }; + project.project_mut().compiler = config_1_5_6; + + let compiled_1 = project.compile().unwrap(); + compiled_1.assert_success(); + + let cache = CompilerCache::::read(project.cache_path()).unwrap(); + + let config_1_5_7 = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 7)).unwrap(), + solc: Default::default(), + }; + project.project_mut().compiler = config_1_5_7; - let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); - let pattern_2 = Regex::new(r"Compiler run successful!").unwrap(); // if we see this, means the cache was invalidated + let compiled_2 = project.compile().unwrap(); - print!("stdout_1: {}", stdout_1); - print!("stdout_2: {}", stdout_2); + assert!(compiled_2.is_unchanged()); - assert!(pattern_1.is_match(&stdout_1)); - assert!(pattern_2.is_match(&stdout_2)); -}); + let latest_cache = CompilerCache::::read(project.cache_path()).unwrap(); + + assert_ne!(cache, latest_cache); +} + +#[test] +fn test_nuevo_vamoaver() { + let mut project = TempProject::::dapptools().unwrap(); + + let compiler_1_5_6 = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 6)).unwrap(), + solc: Default::default(), + }; + let compiled_1 = test_zksync_can_compile_with_version(&mut project, compiler_1_5_6); + + assert!(!compiled_1.is_unchanged()); + + let cache = CompilerCache::::read(project.cache_path()).unwrap(); + + let compiler_1_5_7 = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 7)).unwrap(), + solc: Default::default(), + }; + + let compiled_2 = test_zksync_can_compile_with_version(&mut project, compiler_1_5_7); + + assert!(compiled_2.is_unchanged()); + + let latest_cache = CompilerCache::::read(project.cache_path()).unwrap(); + + assert_ne!(cache, latest_cache); +} From 30f82a588d4b8d7ce8e1ccb4c042f46c1f4cf45f Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 29 Jan 2025 10:09:44 -0300 Subject: [PATCH 14/17] Move zksolc command from compiler to settings --- crates/common/src/compile.rs | 5 +- crates/config/src/zksync.rs | 52 ++--- crates/linking/src/zksync.rs | 8 +- crates/script/src/build/zksync.rs | 14 +- .../zksync/src/executor/runner/libraries.rs | 8 +- crates/verify/src/etherscan/flatten.rs | 3 +- crates/verify/src/zk_provider.rs | 4 +- .../compilers/src/compilers/zksolc/input.rs | 5 +- .../compilers/src/compilers/zksolc/mod.rs | 13 +- .../src/compilers/zksolc/settings.rs | 57 ++++- crates/zksync/compilers/src/link.rs | 14 +- crates/zksync/compilers/tests/zksync_tests.rs | 211 +++--------------- 12 files changed, 132 insertions(+), 262 deletions(-) diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs index 8a853c43f9..566a0be425 100644 --- a/crates/common/src/compile.rs +++ b/crates/common/src/compile.rs @@ -20,8 +20,7 @@ use foundry_compilers::{ Artifact, Project, ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, SolcConfig, }; use foundry_zksync_compilers::compilers::{ - artifact_output::zk::ZkArtifactOutput, - zksolc::{ZkSolc, ZkSolcCompiler}, + artifact_output::zk::ZkArtifactOutput, zksolc::ZkSolcCompiler, }; use num_format::{Locale, ToFormattedString}; @@ -331,7 +330,7 @@ impl ProjectCompiler { let files = self.files.clone(); { - let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?; + let zksolc_version = project.settings.zksolc_version_ref(); Report::new(SpinnerReporter::spawn_with(format!("Using zksolc-{zksolc_version}"))); } self.zksync_compile_with(|| { diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 6b525f552a..8ea5e1cdf2 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -115,7 +115,7 @@ impl ZkSyncConfig { evm_version: EvmVersion, via_ir: bool, offline: bool, - ) -> ZkSolcSettings { + ) -> Result { let optimizer = Optimizer { enabled: Some(self.optimizer), mode: Some(self.optimizer_mode), @@ -125,7 +125,7 @@ impl ZkSyncConfig { jump_table_density_threshold: None, }; - let zk_settings = ZkSettings { + let settings = ZkSettings { libraries, optimizer, evm_version: Some(evm_version), @@ -147,16 +147,22 @@ impl ZkSyncConfig { suppressed_errors: self.suppressed_errors.clone(), }; - let zksolc_path = get_zksolc_compiler(self.zksolc.as_ref(), offline) - .unwrap_or_else(|e| panic!("Could not find zksolc compiler: {e}")); + let zksolc_path = if let Some(path) = config_ensure_zksolc(self.zksolc.as_ref(), offline)? { + path + } else if !offline { + let default_version = semver::Version::new(1, 5, 11); + let mut zksolc = ZkSolc::find_installed_version(&default_version)?; + if zksolc.is_none() { + ZkSolc::blocking_install(&default_version)?; + zksolc = ZkSolc::find_installed_version(&default_version)?; + } + zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{default_version}")) + } else { + "zksolc".into() + }; // `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput` - ZkSolcSettings { - settings: zk_settings, - cli_settings: CliSettings::default(), - zksolc_version: ZkSolc::get_version_for_path(zksolc_path.as_ref()) - .unwrap_or_else(|_| panic!("Could not find zksolc version for this path")), - } + ZkSolcSettings::new_from_path(settings, CliSettings::default(), zksolc_path) } } @@ -172,26 +178,7 @@ pub fn config_zksolc_settings(config: &Config) -> Result return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))), }; - Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir, config.offline)) -} - -/// get the configured `zksolc` compiler -pub fn get_zksolc_compiler(zksolc: Option<&SolcReq>, offline: bool) -> Result { - let zksolc = if let Some(zksolc) = config_ensure_zksolc(zksolc, offline)? { - zksolc - } else if !offline { - let default_version = semver::Version::new(1, 5, 11); - let mut zksolc = ZkSolc::find_installed_version(&default_version)?; - if zksolc.is_none() { - ZkSolc::blocking_install(&default_version)?; - zksolc = ZkSolc::find_installed_version(&default_version)?; - } - zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{default_version}")) - } else { - "zksolc".into() - }; - - Ok(zksolc) + config.zksync.settings(libraries, config.evm_version, config.via_ir, config.offline) } /// Return the configured `zksolc` compiler @@ -199,10 +186,7 @@ pub fn get_zksolc_compiler(zksolc: Option<&SolcReq>, offline: bool) -> Result Result { - Ok(ZkSolcCompiler { - zksolc: get_zksolc_compiler(config.zksync.zksolc.as_ref(), config.offline)?, - solc: config_solc_compiler(config)?, - }) + Ok(ZkSolcCompiler { solc: config_solc_compiler(config)? }) } /// Create a new ZKsync project diff --git a/crates/linking/src/zksync.rs b/crates/linking/src/zksync.rs index 5afa522e19..ee649793c5 100644 --- a/crates/linking/src/zksync.rs +++ b/crates/linking/src/zksync.rs @@ -44,7 +44,7 @@ pub const DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION: Version = Version::new(1, 5, 9 #[derive(Debug)] pub struct ZkLinker<'a> { pub linker: Linker<'a>, - pub compiler: ZkSolcCompiler, + pub compiler: PathBuf, pub compiler_output: &'a ProjectCompileOutput, } @@ -57,7 +57,7 @@ impl<'a> ZkLinker<'a> { pub fn new( root: impl Into, contracts: ArtifactContracts>, - compiler: ZkSolcCompiler, + compiler: PathBuf, compiler_output: &'a ProjectCompileOutput, ) -> Self { Self { linker: Linker::new(root, contracts), compiler, compiler_output } @@ -299,7 +299,7 @@ impl<'a> ZkLinker<'a> { contracts: &ArtifactContracts>, target: &ArtifactId, libraries: &Libraries, - zksolc: &ZkSolcCompiler, + zksolc_path: &Path, ) -> Result, ZkLinkerError> { let artifact_to_link_id = |id: &ArtifactId| format!("{}:{}", id.source.display(), id.name); @@ -336,7 +336,7 @@ impl<'a> ZkLinker<'a> { .collect::>(); let mut link_output = - zk_link::zksolc_link(zksolc, zk_link::LinkJsonInput { bytecodes, libraries }) + zk_link::zksolc_link(zksolc_path, zk_link::LinkJsonInput { bytecodes, libraries }) .expect("able to call zksolc --link"); // TODO(zk): proper error check let link_id = &artifact_to_link_id(target); diff --git a/crates/script/src/build/zksync.rs b/crates/script/src/build/zksync.rs index 43d5245a39..25727347da 100644 --- a/crates/script/src/build/zksync.rs +++ b/crates/script/src/build/zksync.rs @@ -18,23 +18,27 @@ use super::BuildData; impl BuildData { fn get_zk_linker(&self, script_config: &ScriptConfig) -> Result> { - let zksolc = foundry_config::zksync::config_zksolc_compiler(&script_config.config) + let zksolc_settings = foundry_config::zksync::config_zksolc_settings(&script_config.config) .context("retrieving zksolc compiler to be used for linking")?; - let version = zksolc.version().context("trying to determine zksolc version")?; + let version = zksolc_settings.zksolc_version_ref(); let Some(input) = self.zk_output.as_ref() else { eyre::bail!("unable to link zk artifacts if no zk compilation output is provided") }; - let linker = - ZkLinker::new(self.project_root.clone(), input.artifact_ids().collect(), zksolc, input); + let linker = ZkLinker::new( + self.project_root.clone(), + input.artifact_ids().collect(), + zksolc_settings.zksolc_path(), + input, + ); let mut libs = Default::default(); linker.zk_collect_dependencies(&self.target, &mut libs, None)?; // if there are no no libs, no linking will happen // so we can skip version check - if !libs.is_empty() && version < DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION { + if !libs.is_empty() && version < &DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION { eyre::bail!( "deploy-time linking not supported. minimum: {}, given: {}", DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION, diff --git a/crates/strategy/zksync/src/executor/runner/libraries.rs b/crates/strategy/zksync/src/executor/runner/libraries.rs index 6ef5004123..e3833dd248 100644 --- a/crates/strategy/zksync/src/executor/runner/libraries.rs +++ b/crates/strategy/zksync/src/executor/runner/libraries.rs @@ -56,14 +56,14 @@ impl ZksyncExecutorStrategyRunner { let contracts: ArtifactContracts> = input.artifact_ids().collect(); - let Ok(zksolc) = foundry_config::zksync::config_zksolc_compiler(config) else { + let Ok(zksolc_settings) = foundry_config::zksync::config_zksolc_settings(config) else { tracing::error!("unable to determine zksolc compiler to be used for linking"); // TODO(zk): better error return Err(LinkerError::CyclicDependency); }; - let version = zksolc.version().map_err(|_| LinkerError::CyclicDependency)?; + let version = zksolc_settings.zksolc_version_ref(); - let linker = ZkLinker::new(root, contracts.clone(), zksolc, input); + let linker = ZkLinker::new(root, contracts.clone(), zksolc_settings.zksolc_path(), input); let zk_linker_error_to_linker = |zk_error| match zk_error { ZkLinkerError::Inner(err) => err, @@ -93,7 +93,7 @@ impl ZksyncExecutorStrategyRunner { // so we can skip the version check if !libraries.is_empty() { // TODO(zk): better error - if version < DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION { + if version < &DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION { tracing::error!( %version, minimum_version = %DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION, diff --git a/crates/verify/src/etherscan/flatten.rs b/crates/verify/src/etherscan/flatten.rs index 40ae509087..878a63c340 100644 --- a/crates/verify/src/etherscan/flatten.rs +++ b/crates/verify/src/etherscan/flatten.rs @@ -188,6 +188,7 @@ Diagnostics: {diags}", }, solc_version: solc_version.clone(), cli_settings: CliSettings::default(), + zksolc_path: zksolc_path.clone(), }; let solc_compiler = if compiler_version.is_zksync_solc { @@ -199,7 +200,7 @@ Diagnostics: {diags}", SolcCompiler::Specific(solc) }; - let zksolc_compiler = ZkSolcCompiler { zksolc: zksolc_path, solc: solc_compiler }; + let zksolc_compiler = ZkSolcCompiler { solc: solc_compiler }; let out = zksolc_compiler.compile(&input)?; if out.errors.iter().any(|e| e.is_error()) { diff --git a/crates/verify/src/zk_provider.rs b/crates/verify/src/zk_provider.rs index 1f85797f41..4834c5d83c 100644 --- a/crates/verify/src/zk_provider.rs +++ b/crates/verify/src/zk_provider.rs @@ -45,7 +45,7 @@ impl ZkVerificationContext { let mut project = foundry_config::zksync::config_create_project(&config, config.cache, false)?; project.no_artifacts = true; - let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?; + let zksolc_version = project.settings.zksolc_version_ref(); let (solc_version, is_zksync_solc) = if let Some(solc) = &config.zksync.solc_path { let solc_type_and_version = zksolc::get_solc_version_info(solc)?; @@ -68,7 +68,7 @@ impl ZkVerificationContext { }; let compiler_version = - ZkVersion { zksolc: zksolc_version, solc: solc_version, is_zksync_solc }; + ZkVersion { zksolc: zksolc_version.clone(), solc: solc_version, is_zksync_solc }; Ok(Self { config, project, target_name, target_path, compiler_version }) } diff --git a/crates/zksync/compilers/src/compilers/zksolc/input.rs b/crates/zksync/compilers/src/compilers/zksolc/input.rs index a957fc593b..cbe74a188a 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/input.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/input.rs @@ -25,6 +25,8 @@ pub struct ZkSolcVersionedInput { pub solc_version: Version, /// zksolc cli settings pub cli_settings: solc::CliSettings, + /// zksolc binary path + pub zksolc_path: PathBuf, } impl CompilerInput for ZkSolcVersionedInput { @@ -40,10 +42,11 @@ impl CompilerInput for ZkSolcVersionedInput { language: Self::Language, version: Version, ) -> Self { + let zksolc_path = settings.zksolc_path(); let ZkSolcSettings { settings, cli_settings, .. } = settings; let input = ZkSolcInput::new(language, sources, settings).sanitized(&version); - Self { solc_version: version, input, cli_settings } + Self { solc_version: version, input, cli_settings, zksolc_path } } fn language(&self) -> Self::Language { diff --git a/crates/zksync/compilers/src/compilers/zksolc/mod.rs b/crates/zksync/compilers/src/compilers/zksolc/mod.rs index bcff91876e..f8b202c6d2 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/mod.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/mod.rs @@ -123,17 +123,13 @@ impl ZkSolcOS { /// ZkSolc compiler #[derive(Debug, Clone)] pub struct ZkSolcCompiler { - /// zksolc path - pub zksolc: PathBuf, /// solc compiler to use along zksolc pub solc: SolcCompiler, } impl Default for ZkSolcCompiler { fn default() -> Self { - let zksolc = - ZkSolc::get_path_for_version(&ZKSOLC_VERSION).expect("Could not install zksolc"); - Self { zksolc, solc: Default::default() } + Self { solc: Default::default() } } } @@ -237,7 +233,7 @@ impl ZkSolcCompiler { } }; - let mut zksolc = ZkSolc::new(self.zksolc.clone(), solc)?; + let mut zksolc = ZkSolc::new(input.zksolc_path.clone(), solc)?; zksolc.base_path.clone_from(&input.cli_settings.base_path); zksolc.allow_paths.clone_from(&input.cli_settings.allow_paths); @@ -245,11 +241,6 @@ impl ZkSolcCompiler { Ok(zksolc) } - - /// Retrieve the version of the specified `zksolc` - pub fn version(&self) -> Result { - ZkSolc::get_version_for_path(self.zksolc.as_ref()) - } } /// Version metadata. Will include `zksync_version` if compiler is zksync solc. diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index 7f804fb77b..0cbedd0454 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -4,6 +4,7 @@ use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_ty use foundry_compilers::{ artifacts::{serde_helpers, EvmVersion, Libraries}, compilers::CompilerSettings, + error::Result, solc, CompilerSettingsRestrictions, }; use foundry_compilers_artifacts_solc::{output_selection::OutputSelection, remappings::Remapping}; @@ -16,7 +17,7 @@ use std::{ str::FromStr, }; -use super::{ZkSolc, ZkSolcCompiler}; +use super::{ZkSolc, ZKSOLC_VERSION}; /// /// The Solidity compiler codegen. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -101,21 +102,65 @@ pub struct ZkSolcSettings { /// Additional CLI args configuration #[serde(flatten)] pub cli_settings: solc::CliSettings, - /// The version of the zksolc compiler to use. - pub zksolc_version: Version, + /// The version of the zksolc compiler to use. Retrieved from `zksolc_path` + zksolc_version: Version, + /// zksolc path + zksolc_path: PathBuf, } impl Default for ZkSolcSettings { fn default() -> Self { + let zksolc_path = ZkSolc::get_path_for_version(&ZKSOLC_VERSION) + .expect("failed getting default zksolc version path"); Self { settings: Default::default(), cli_settings: Default::default(), - zksolc_version: ZkSolc::get_version_for_path(ZkSolcCompiler::default().zksolc.as_ref()) - .expect("Failed to get zksolc version"), + zksolc_version: ZKSOLC_VERSION, + zksolc_path, } } } +impl ZkSolcSettings { + /// Initialize settings for a given zksolc path + pub fn new_from_path( + settings: ZkSettings, + cli_settings: solc::CliSettings, + zksolc_path: PathBuf, + ) -> Result { + let zksolc_version = ZkSolc::get_version_for_path(&zksolc_path)?; + Ok(Self { settings, cli_settings, zksolc_path, zksolc_version }) + } + + /// Initialize settings for a given zksolc version + pub fn new_from_version( + settings: ZkSettings, + cli_settings: solc::CliSettings, + zksolc_version: Version, + ) -> Result { + let zksolc_path = ZkSolc::get_path_for_version(&zksolc_version)?; + Ok(Self { settings, cli_settings, zksolc_path, zksolc_version }) + } + + /// Get zksolc path + pub fn zksolc_path(&self) -> PathBuf { + self.zksolc_path.clone() + } + + /// Get zksolc version + pub fn zksolc_version_ref(&self) -> &Version { + &self.zksolc_version + } + + /// Set a specific zksolc version + pub fn set_zksolc_version(&mut self, zksolc_version: Version) -> Result<()> { + let zksolc_path = ZkSolc::get_path_for_version(&zksolc_version)?; + self.zksolc_version = zksolc_version; + self.zksolc_path = zksolc_path; + Ok(()) + } +} + impl ZkSettings { /// Creates a new `Settings` instance with the given `output_selection` pub fn new(output_selection: impl Into) -> Self { @@ -225,8 +270,6 @@ impl CompilerSettings for ZkSolcSettings { .. } = self; - println!("ybue: zksolc_version: {:?}", self.zksolc_version); - *via_ir == other.settings.via_ir && *remappings == other.settings.remappings && *evm_version == other.settings.evm_version && diff --git a/crates/zksync/compilers/src/link.rs b/crates/zksync/compilers/src/link.rs index 05d84c5e7a..b9a97c507e 100644 --- a/crates/zksync/compilers/src/link.rs +++ b/crates/zksync/compilers/src/link.rs @@ -12,8 +12,6 @@ use alloy_primitives::{ use foundry_compilers::error::SolcError; use serde::{Deserialize, Serialize}; -use crate::compilers::zksolc::ZkSolcCompiler; - type LinkId = String; /// A library that zksolc will link against @@ -108,12 +106,8 @@ fn map_io_err(zksolc_path: &Path) -> impl FnOnce(std::io::Error) -> SolcError + /// Invoke `zksolc link` given the `zksolc` binary and json input to use #[tracing::instrument(level = tracing::Level::TRACE, ret)] -pub fn zksolc_link( - zksolc: &ZkSolcCompiler, - input: LinkJsonInput, -) -> Result { - let zksolc = &zksolc.zksolc; - let mut cmd = Command::new(zksolc); +pub fn zksolc_link(zksolc_path: &Path, input: LinkJsonInput) -> Result { + let mut cmd = Command::new(zksolc_path); cmd.arg("--standard-json") .arg("--link") @@ -121,12 +115,12 @@ pub fn zksolc_link( .stderr(Stdio::piped()) .stdout(Stdio::piped()); - let mut child = cmd.spawn().map_err(map_io_err(zksolc))?; + let mut child = cmd.spawn().map_err(map_io_err(zksolc_path))?; let stdin = child.stdin.as_mut().unwrap(); let _ = serde_json::to_writer(stdin, &input); - let output = child.wait_with_output().map_err(map_io_err(zksolc))?; + let output = child.wait_with_output().map_err(map_io_err(zksolc_path))?; tracing::trace!(?output); if output.status.success() { diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index d8de00315e..2ff3cf948d 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -5,7 +5,6 @@ use std::{ str::FromStr, }; -use foundry_compilers::ProjectCompileOutput; use foundry_compilers_artifacts_solc::Remapping; use foundry_test_utils::foundry_compilers::{ buildinfo::BuildInfo, cache::CompilerCache, project_util::*, resolver::parse::SolData, @@ -13,15 +12,14 @@ use foundry_test_utils::foundry_compilers::{ }; use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; -use foundry_test_utils::{forgetest_init, util::OutputExt}; use foundry_zksync_compilers::{ artifacts::{contract::Contract, error::Error}, compilers::{ artifact_output::zk::ZkArtifactOutput, - zksolc::{input::ZkSolcInput, ZkSolc, ZkSolcCompiler, ZkSolcSettings}, + zksolc::{input::ZkSolcInput, ZkSolcCompiler, ZkSolcSettings, ZKSOLC_VERSION}, }, }; -use regex::Regex; +use semver::Version; #[test] fn zksync_can_compile_dapp_sample() { @@ -54,14 +52,14 @@ fn zksync_can_compile_dapp_sample() { assert_eq!(cache, updated_cache); } -fn test_zksync_can_compile_contract_with_suppressed_errors(compiler: ZkSolcCompiler) { +fn test_zksync_can_compile_contract_with_suppressed_errors(zksolc_version: Version) { // let _ = tracing_subscriber::fmt() // .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) // .try_init() // .ok(); let mut project = TempProject::::dapptools().unwrap(); - project.project_mut().compiler = compiler; + project.project_mut().settings.set_zksolc_version(zksolc_version).unwrap(); project .add_source( @@ -88,72 +86,27 @@ fn test_zksync_can_compile_contract_with_suppressed_errors(compiler: ZkSolcCompi let compiled = project.compile().unwrap(); - let cache = CompilerCache::::read(project.cache_path()).unwrap(); - print!("CAAACHEE {:?}", cache); - compiled.assert_success(); assert!(compiled.find_first("Erroneous").is_some()); } -fn test_zksync_can_compile_with_version( - project: &mut TempProject, - compiler: ZkSolcCompiler, -) -> ProjectCompileOutput { - // let _ = tracing_subscriber::fmt() - // .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) - // .try_init() - // .ok(); - - project.project_mut().compiler = compiler; - - project - .add_source( - "A", - r#" -pragma solidity ^0.8.10; -import "./B.sol"; -contract A { } -"#, - ) - .unwrap(); - - project - .add_source( - "B", - r" -pragma solidity ^0.8.10; -contract B { } -", - ) - .unwrap(); - - project.project_mut().settings.settings.suppressed_errors = - HashSet::from([ErrorType::SendTransfer]); - - project.compile().unwrap() -} - #[test] fn zksync_can_compile_contract_with_suppressed_errors() { - test_zksync_can_compile_contract_with_suppressed_errors(ZkSolcCompiler::default()); + test_zksync_can_compile_contract_with_suppressed_errors(ZKSOLC_VERSION); } #[test] fn zksync_pre_1_5_7_can_compile_contract_with_suppressed_errors() { - let compiler = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 6)).unwrap(), - solc: Default::default(), - }; - test_zksync_can_compile_contract_with_suppressed_errors(compiler); + test_zksync_can_compile_contract_with_suppressed_errors(Version::new(1, 5, 6)); } -fn test_zksync_can_compile_contract_with_suppressed_warnings(compiler: ZkSolcCompiler) { +fn test_zksync_can_compile_contract_with_suppressed_warnings(zksolc_version: Version) { // let _ = tracing_subscriber::fmt() // .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) // .try_init() // .ok(); let mut project = TempProject::::dapptools().unwrap(); - project.project_mut().compiler = compiler; + project.project_mut().settings.set_zksolc_version(zksolc_version).unwrap(); project .add_source( @@ -201,23 +154,19 @@ fn test_zksync_can_compile_contract_with_suppressed_warnings(compiler: ZkSolcCom #[test] fn zksync_can_compile_contract_with_suppressed_warnings() { - test_zksync_can_compile_contract_with_suppressed_warnings(ZkSolcCompiler::default()); + test_zksync_can_compile_contract_with_suppressed_warnings(ZKSOLC_VERSION); } #[test] fn zksync_pre_1_5_7_can_compile_contract_with_suppressed_warnings() { - let compiler = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 6)).unwrap(), - solc: Default::default(), - }; - test_zksync_can_compile_contract_with_suppressed_warnings(compiler); + test_zksync_can_compile_contract_with_suppressed_warnings(Version::new(1, 5, 6)); } fn test_zksync_can_compile_contract_with_assembly_create_suppressed_warnings( - compiler: ZkSolcCompiler, + zksolc_version: Version, ) { let mut project = TempProject::::dapptools().unwrap(); - project.project_mut().compiler = compiler; + project.project_mut().settings.set_zksolc_version(zksolc_version).unwrap(); project .add_source( @@ -269,11 +218,9 @@ fn test_zksync_can_compile_contract_with_assembly_create_suppressed_warnings( #[test] fn zksync_can_compile_contract_with_assembly_create_suppressed_warnings_1_5_10() { - let compiler = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 10)).unwrap(), - solc: Default::default(), - }; - test_zksync_can_compile_contract_with_assembly_create_suppressed_warnings(compiler); + test_zksync_can_compile_contract_with_assembly_create_suppressed_warnings(Version::new( + 1, 5, 10, + )); } #[test] @@ -702,81 +649,12 @@ fn zksync_can_compile_yul_sample() { assert!(!yul_bytecode.is_empty(), "SimpleStore bytecode is empty"); } -// forgetest_init!(test_zk_cache_ok, |prj, cmd| { -// let zk_toml = r#"[profile.default] -// src = 'src' -// out = 'out' -// libs = ['lib'] -// solc = '0.8.26' - -// [profile.default.zksync] -// zksolc = '1.5.6' -// "#; - -// fs::write(prj.root().join("foundry.toml"), zk_toml).unwrap(); - -// cmd.args(["build", "--zksync"]); -// let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); -// let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); - -// let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); -// let pattern_2 = Regex::new(r"No files changed, compilation skipped").unwrap(); - -// assert!(pattern_1.is_match(&stdout_1)); -// assert!(pattern_2.is_match(&stdout_2)); -// }); - -// // tests cache is invalidated when zksolc version changes -// forgetest_init!(test_zk_cache_invalid_on_version_changed, |prj, cmd| { -// let template_toml = r#"[profile.default] -// src = 'src' -// out = 'out' -// libs = ['lib'] -// solc = '0.8.26' - -// [profile.default.zksync] -// "#; - -// let toml_156 = format!( -// r#"{template_toml} -// zksolc = '1.5.6' -// "# -// ); - -// let toml_157 = format!( -// r#"{template_toml} -// zksolc = '1.5.7' -// "# -// ); - -// fs::write(prj.root().join("foundry.toml"), toml_156).unwrap(); - -// cmd.args(["build", "--zksync"]); -// let stdout_1 = cmd.assert_success().get_output().stdout_lossy(); -// let pattern_1 = Regex::new(r"Compiler run successful").unwrap(); - -// fs::remove_file(prj.root().join("foundry.toml")).unwrap(); -// fs::write(prj.root().join("foundry.toml"), toml_157).unwrap(); - -// let stdout_2 = cmd.assert_success().get_output().stdout_lossy(); -// let pattern_2 = Regex::new(r"Compiler run successful!").unwrap(); // if we see this, means -// the cache was invalidated - -// print!("stdout_1: {}", stdout_1); -// print!("stdout_2: {}", stdout_2); - -// assert!(pattern_1.is_match(&stdout_1)); -// assert!(pattern_2.is_match(&stdout_2)); -// }); - -// Test that checks that you have to recompile the project if the zksolc version changes (the -// cache is invalidated) - #[test] fn zksync_detects_change_on_cache_if_zksolc_version_changes() { let mut project = TempProject::::dapptools().unwrap(); project.project_mut().build_info = true; + project .add_source( "A", @@ -798,56 +676,29 @@ contract B { } ) .unwrap(); - let config_1_5_6 = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 6)).unwrap(), - solc: Default::default(), - }; - project.project_mut().compiler = config_1_5_6; + project.project_mut().settings.set_zksolc_version(Version::new(1, 5, 6)).unwrap(); let compiled_1 = project.compile().unwrap(); compiled_1.assert_success(); - let cache = CompilerCache::::read(project.cache_path()).unwrap(); - - let config_1_5_7 = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 7)).unwrap(), - solc: Default::default(), - }; - project.project_mut().compiler = config_1_5_7; + for bi in compiled_1.output().build_infos.iter() { + let zksolc_version = + bi.build_info.get("output").unwrap()["metadata"]["zksolcVersion"].to_string(); + assert_eq!(zksolc_version, "\"1.5.6\""); + } let compiled_2 = project.compile().unwrap(); - assert!(compiled_2.is_unchanged()); - let latest_cache = CompilerCache::::read(project.cache_path()).unwrap(); - - assert_ne!(cache, latest_cache); -} - -#[test] -fn test_nuevo_vamoaver() { - let mut project = TempProject::::dapptools().unwrap(); - - let compiler_1_5_6 = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 6)).unwrap(), - solc: Default::default(), - }; - let compiled_1 = test_zksync_can_compile_with_version(&mut project, compiler_1_5_6); + project.project_mut().settings.set_zksolc_version(Version::new(1, 5, 7)).unwrap(); - assert!(!compiled_1.is_unchanged()); + let compiled_3 = project.compile().unwrap(); + compiled_3.assert_success(); + assert!(!compiled_3.is_unchanged()); - let cache = CompilerCache::::read(project.cache_path()).unwrap(); - - let compiler_1_5_7 = ZkSolcCompiler { - zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 7)).unwrap(), - solc: Default::default(), - }; - - let compiled_2 = test_zksync_can_compile_with_version(&mut project, compiler_1_5_7); - - assert!(compiled_2.is_unchanged()); - - let latest_cache = CompilerCache::::read(project.cache_path()).unwrap(); - - assert_ne!(cache, latest_cache); + for bi in compiled_3.output().build_infos.iter() { + let zksolc_version = + bi.build_info.get("output").unwrap()["metadata"]["zksolcVersion"].to_string(); + assert_eq!(zksolc_version, "\"1.5.7\""); + } } From b83538c625877ca29bbcc9449ba582070ba718f2 Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 29 Jan 2025 10:21:08 -0300 Subject: [PATCH 15/17] Remove regex --- Cargo.lock | 1 - crates/zksync/compilers/Cargo.toml | 1 - crates/zksync/compilers/src/lib.rs | 2 -- 3 files changed, 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7e81f861a..31eaef07c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5178,7 +5178,6 @@ dependencies = [ "fs4 0.8.4", "itertools 0.13.0", "path-slash", - "regex", "reqwest 0.12.9", "semver 1.0.23", "serde", diff --git a/crates/zksync/compilers/Cargo.toml b/crates/zksync/compilers/Cargo.toml index c675121368..9f538b587f 100644 --- a/crates/zksync/compilers/Cargo.toml +++ b/crates/zksync/compilers/Cargo.toml @@ -37,5 +37,4 @@ similar-asserts.workspace = true fd-lock = "4.0.2" tempfile.workspace = true foundry-test-utils.workspace = true -regex = { workspace = true, default-features = false } diff --git a/crates/zksync/compilers/src/lib.rs b/crates/zksync/compilers/src/lib.rs index 19579c8c78..4fd584b52f 100644 --- a/crates/zksync/compilers/src/lib.rs +++ b/crates/zksync/compilers/src/lib.rs @@ -13,6 +13,4 @@ pub mod link; #[cfg(test)] use foundry_test_utils as _; #[cfg(test)] -use regex as _; -#[cfg(test)] use tempfile as _; From 0562ba697dcb1c40781eac257d9d7312af9e7983 Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 29 Jan 2025 10:27:49 -0300 Subject: [PATCH 16/17] remove unused methods --- crates/config/src/zksync.rs | 10 +--------- .../zksync/compilers/src/compilers/zksolc/settings.rs | 10 ---------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 8ea5e1cdf2..61f1e56668 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -181,14 +181,6 @@ pub fn config_zksolc_settings(config: &Config) -> Result Result { - Ok(ZkSolcCompiler { solc: config_solc_compiler(config)? }) -} - /// Create a new ZKsync project pub fn config_create_project( config: &Config, @@ -216,7 +208,7 @@ pub fn config_create_project( builder = builder.sparse_output(filter); } - let zksolc_compiler = config_zksolc_compiler(config)?; + let zksolc_compiler = ZkSolcCompiler { solc: config_solc_compiler(config)? }; let project = builder.build(zksolc_compiler)?; diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index 0cbedd0454..e7cc0d2c15 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -132,16 +132,6 @@ impl ZkSolcSettings { Ok(Self { settings, cli_settings, zksolc_path, zksolc_version }) } - /// Initialize settings for a given zksolc version - pub fn new_from_version( - settings: ZkSettings, - cli_settings: solc::CliSettings, - zksolc_version: Version, - ) -> Result { - let zksolc_path = ZkSolc::get_path_for_version(&zksolc_version)?; - Ok(Self { settings, cli_settings, zksolc_path, zksolc_version }) - } - /// Get zksolc path pub fn zksolc_path(&self) -> PathBuf { self.zksolc_path.clone() From 1729e37fe35fc2a489d2fe14ee090c02761c965b Mon Sep 17 00:00:00 2001 From: Jrigada Date: Wed, 29 Jan 2025 10:50:20 -0300 Subject: [PATCH 17/17] Cargo clippy --- crates/verify/src/etherscan/flatten.rs | 2 +- crates/zksync/compilers/src/compilers/zksolc/mod.rs | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/crates/verify/src/etherscan/flatten.rs b/crates/verify/src/etherscan/flatten.rs index 878a63c340..184b7072ab 100644 --- a/crates/verify/src/etherscan/flatten.rs +++ b/crates/verify/src/etherscan/flatten.rs @@ -188,7 +188,7 @@ Diagnostics: {diags}", }, solc_version: solc_version.clone(), cli_settings: CliSettings::default(), - zksolc_path: zksolc_path.clone(), + zksolc_path, }; let solc_compiler = if compiler_version.is_zksync_solc { diff --git a/crates/zksync/compilers/src/compilers/zksolc/mod.rs b/crates/zksync/compilers/src/compilers/zksolc/mod.rs index f8b202c6d2..eaf0a2075e 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/mod.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/mod.rs @@ -121,18 +121,12 @@ impl ZkSolcOS { } /// ZkSolc compiler -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct ZkSolcCompiler { /// solc compiler to use along zksolc pub solc: SolcCompiler, } -impl Default for ZkSolcCompiler { - fn default() -> Self { - Self { solc: Default::default() } - } -} - impl Compiler for ZkSolcCompiler { type Input = ZkSolcVersionedInput; type CompilationError = Error;