Skip to content

Commit

Permalink
feat: use new compilers api and add zkync solc test (#607)
Browse files Browse the repository at this point in the history
  • Loading branch information
elfedy authored Oct 15, 2024
1 parent 15bec2f commit cbd6940
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 53 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion crates/common/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, || {
Expand Down
7 changes: 4 additions & 3 deletions crates/verify/src/etherscan/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down
15 changes: 6 additions & 9 deletions crates/verify/src/zk_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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
Expand All @@ -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 =
Expand Down
55 changes: 22 additions & 33 deletions crates/zksync/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
};
Expand Down Expand Up @@ -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()
};
Expand All @@ -116,7 +109,7 @@ fn config_solc_compiler(config: &Config) -> Result<SolcCompiler, SolcError> {
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))
Expand All @@ -143,7 +136,7 @@ fn config_solc_compiler(config: &Config) -> Result<SolcCompiler, SolcError> {
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),
Expand Down Expand Up @@ -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() {
Expand All @@ -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<Version, SolcError> {
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");
}
}
}

0 comments on commit cbd6940

Please sign in to comment.