From cbd69405e0be122b32e1376241d8ce8f735a34c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Rodr=C3=ADguez?= Date: Tue, 15 Oct 2024 09:01:12 -0300 Subject: [PATCH] feat: use new compilers api and add zkync solc test (#607) --- Cargo.lock | 14 +++---- crates/common/src/compile.rs | 2 +- crates/verify/src/etherscan/flatten.rs | 7 ++-- crates/verify/src/zk_provider.rs | 15 +++---- crates/zksync/compiler/src/lib.rs | 55 +++++++++++--------------- 5 files changed, 40 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a83c505f..0bcc73c0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1857,7 +1857,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools 0.10.5", + "itertools 0.11.0", "lazy_static", "lazycell", "log", @@ -5083,7 +5083,7 @@ dependencies = [ [[package]] name = "foundry-compilers" version = "0.11.1" -source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#b2aca7f87e0484d1e202d77a4ada8b46b059da6d" +source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#e3f44379f6bfb3c50e3a69acbeaa8f6da0cb4aae" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -5123,7 +5123,7 @@ dependencies = [ [[package]] name = "foundry-compilers-artifacts" version = "0.11.1" -source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#b2aca7f87e0484d1e202d77a4ada8b46b059da6d" +source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#e3f44379f6bfb3c50e3a69acbeaa8f6da0cb4aae" dependencies = [ "foundry-compilers-artifacts-solc", "foundry-compilers-artifacts-vyper", @@ -5133,7 +5133,7 @@ dependencies = [ [[package]] name = "foundry-compilers-artifacts-solc" version = "0.11.1" -source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#b2aca7f87e0484d1e202d77a4ada8b46b059da6d" +source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#e3f44379f6bfb3c50e3a69acbeaa8f6da0cb4aae" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -5156,7 +5156,7 @@ dependencies = [ [[package]] name = "foundry-compilers-artifacts-vyper" version = "0.11.1" -source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#b2aca7f87e0484d1e202d77a4ada8b46b059da6d" +source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#e3f44379f6bfb3c50e3a69acbeaa8f6da0cb4aae" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -5170,7 +5170,7 @@ dependencies = [ [[package]] name = "foundry-compilers-artifacts-zksolc" version = "0.11.1" -source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#b2aca7f87e0484d1e202d77a4ada8b46b059da6d" +source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#e3f44379f6bfb3c50e3a69acbeaa8f6da0cb4aae" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -5191,7 +5191,7 @@ dependencies = [ [[package]] name = "foundry-compilers-core" version = "0.11.1" -source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#b2aca7f87e0484d1e202d77a4ada8b46b059da6d" +source = "git+https://github.com/Moonsong-Labs/compilers?branch=zksync-v0.11.1#e3f44379f6bfb3c50e3a69acbeaa8f6da0cb4aae" dependencies = [ "alloy-primitives", "cfg-if 1.0.0", diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs index e0d89f914..47c25844b 100644 --- a/crates/common/src/compile.rs +++ b/crates/common/src/compile.rs @@ -299,7 +299,7 @@ impl ProjectCompiler { let files = self.files.clone(); { - let zksolc_version = ZkSolc::new(project.compiler.zksolc.clone()).version()?; + let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?; Report::new(SpinnerReporter::spawn_with(format!("Using zksolc-{zksolc_version}"))); } self.zksync_compile_with(&project.paths.root, || { diff --git a/crates/verify/src/etherscan/flatten.rs b/crates/verify/src/etherscan/flatten.rs index 0ce7571a3..84013560b 100644 --- a/crates/verify/src/etherscan/flatten.rs +++ b/crates/verify/src/etherscan/flatten.rs @@ -180,7 +180,7 @@ Diagnostics: {diags}", ) -> Result<()> { let solc_version = strip_build_meta(compiler_version.solc.clone()); let zksolc_version = strip_build_meta(compiler_version.zksolc.clone()); - let zksolc = ZkSolc::find_installed_version(&zksolc_version)? + let zksolc_path = ZkSolc::find_installed_version(&zksolc_version)? .unwrap_or(ZkSolc::blocking_install(&solc_version)?); let input = ZkSolcVersionedInput { @@ -202,9 +202,10 @@ Diagnostics: {diags}", SolcCompiler::Specific(solc) }; - let zksolc_compiler = ZkSolcCompiler { zksolc: zksolc.zksolc, solc: solc_compiler }; + let zksolc_compiler = ZkSolcCompiler { zksolc: zksolc_path, solc: solc_compiler }; + let zksolc = zksolc_compiler.zksolc(&input)?; - let out = zksolc_compiler.zksync_compile(&input)?; + let out = zksolc.compile(&input.input)?; if out.has_error() { let mut o = ZkAggregatedCompilerOutput::default(); o.extend(solc_version, raw_build_info_new(&input, &out, false)?, out); diff --git a/crates/verify/src/zk_provider.rs b/crates/verify/src/zk_provider.rs index 38c30944f..674c231c3 100644 --- a/crates/verify/src/zk_provider.rs +++ b/crates/verify/src/zk_provider.rs @@ -8,7 +8,7 @@ use foundry_compilers::{ compilers::CompilerSettings, resolver::parse::SolData, solc::{Solc, SolcCompiler}, - zksolc::{ZkSolc, ZkSolcCompiler}, + zksolc::{self, ZkSolc, ZkSolcCompiler}, zksync::artifact_output::zk::ZkArtifactOutput, Graph, Project, }; @@ -43,13 +43,11 @@ impl ZkVerificationContext { let mut project = foundry_zksync_compiler::config_create_project(&config, config.cache, false)?; project.no_artifacts = true; - let zksolc_version = ZkSolc::new(project.compiler.zksolc.clone()).version()?; - let mut is_zksync_solc = false; + let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?; - let solc_version = if let Some(solc) = &config.zksync.solc_path { - let solc = Solc::new(solc)?; - //TODO: determine if this solc is zksync or not - solc.version + 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)?; + (solc_type_and_version.version, solc_type_and_version.zksync_version.is_some()) } else { //if there's no `solc_path` specified then we use the same // as the project version @@ -64,8 +62,7 @@ impl ZkVerificationContext { let solc = Solc::new_with_version(solc_path, context_solc_version.clone()); project.compiler.solc = SolcCompiler::Specific(solc); - is_zksync_solc = true; - context_solc_version + (context_solc_version, true) }; let compiler_version = diff --git a/crates/zksync/compiler/src/lib.rs b/crates/zksync/compiler/src/lib.rs index 67a0fa89b..194ed318c 100644 --- a/crates/zksync/compiler/src/lib.rs +++ b/crates/zksync/compiler/src/lib.rs @@ -6,15 +6,10 @@ /// ZKSolc specific logic. mod zksolc; -use std::{ - path::{Path, PathBuf}, - process::{Command, Stdio}, - str::FromStr, -}; +use std::path::PathBuf; use foundry_config::{Config, SkipBuildFilters, SolcReq}; use semver::Version; -use tracing::{debug, trace}; pub use zksolc::*; pub mod libraries; @@ -23,7 +18,7 @@ use foundry_compilers::{ artifacts::Severity, error::SolcError, solc::{Solc, SolcCompiler, SolcLanguage}, - zksolc::{ZkSolc, ZkSolcCompiler, ZkSolcSettings}, + zksolc::{get_solc_version_info, ZkSolc, ZkSolcCompiler, ZkSolcSettings}, zksync::artifact_output::zk::ZkArtifactOutput, Project, ProjectBuilder, ProjectPathsConfig, }; @@ -87,9 +82,7 @@ pub fn config_create_project( ZkSolc::blocking_install(&default_version)?; zksolc = ZkSolc::find_installed_version(&default_version)?; } - zksolc - .map(|c| c.zksolc) - .unwrap_or_else(|| panic!("Could not install zksolc v{}", default_version)) + zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{}", default_version)) } else { "zksolc".into() }; @@ -116,7 +109,7 @@ fn config_solc_compiler(config: &Config) -> Result { if !path.is_file() { return Err(SolcError::msg(format!("`solc` {} does not exist", path.display()))) } - let version = solc_version(path)?; + let version = get_solc_version_info(path)?.version; let solc = Solc::new_with_version(path, Version::new(version.major, version.minor, version.patch)); return Ok(SolcCompiler::Specific(solc)) @@ -143,7 +136,7 @@ fn config_solc_compiler(config: &Config) -> Result { if !path.is_file() { return Err(SolcError::msg(format!("`solc` {} does not exist", path.display()))) } - let version = solc_version(path)?; + let version = get_solc_version_info(path)?.version; Solc::new_with_version( path, Version::new(version.major, version.minor, version.patch), @@ -197,7 +190,7 @@ pub fn config_ensure_zksolc( ZkSolc::blocking_install(version)?; zksolc = ZkSolc::find_installed_version(version)?; } - zksolc.map(|commmand| commmand.zksolc) + zksolc } SolcReq::Local(zksolc) => { if !zksolc.is_file() { @@ -215,25 +208,21 @@ pub fn config_ensure_zksolc( Ok(None) } -/// Given a solc path, get the semver. Works for both solc an zkVm solc. -// TODO: Maybe move this to compilers and use it to identify if used binary is zkVm or not -fn solc_version(path: &Path) -> Result { - let mut cmd = Command::new(path); - cmd.arg("--version").stdin(Stdio::piped()).stderr(Stdio::piped()).stdout(Stdio::piped()); - debug!(?cmd, "getting Solc version"); - let output = cmd.output().map_err(|e| SolcError::io(e, path))?; - trace!(?output); - if output.status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - let version = stdout - .lines() - .filter(|l| !l.trim().is_empty()) - .nth(1) - .ok_or_else(|| SolcError::msg("Version not found in Solc output"))?; - debug!(%version); - // NOTE: semver doesn't like `+` in g++ in build metadata which is invalid semver - Ok(Version::from_str(&version.trim_start_matches("Version: ").replace(".g++", ".gcc"))?) - } else { - Err(SolcError::solc_output(&output)) +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn zksync_project_has_zksync_solc_when_solc_req_is_a_version() { + let config = + Config { solc: 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"); + } } }