Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/common/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ 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};

use std::{
collections::BTreeMap,
fmt::Display,
Expand Down Expand Up @@ -330,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(|| {
Expand Down
51 changes: 21 additions & 30 deletions crates/config/src/zksync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ impl ZkSyncConfig {
libraries: Libraries,
evm_version: EvmVersion,
via_ir: bool,
) -> ZkSolcSettings {
offline: bool,
) -> Result<ZkSolcSettings, SolcError> {
let optimizer = Optimizer {
enabled: Some(self.optimizer),
mode: Some(self.optimizer_mode),
Expand All @@ -124,7 +125,7 @@ impl ZkSyncConfig {
jump_table_density_threshold: None,
};

let zk_settings = ZkSettings {
let settings = ZkSettings {
libraries,
optimizer,
evm_version: Some(evm_version),
Expand All @@ -146,8 +147,22 @@ impl ZkSyncConfig {
suppressed_errors: self.suppressed_errors.clone(),
};

let zksolc_path = if let Some(path) = config_ensure_zksolc(self.zksolc.as_ref(), offline)? {
Comment thread
elfedy marked this conversation as resolved.
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() }
ZkSolcSettings::new_from_path(settings, CliSettings::default(), zksolc_path)
}
}

Expand All @@ -163,34 +178,10 @@ pub fn config_zksolc_settings(config: &Config) -> Result<ZkSolcSettings, SolcErr
Err(e) => return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))),
};

Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir))
}

/// 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<ZkSolcCompiler, SolcError> {
let zksolc = if let Some(zksolc) =
config_ensure_zksolc(config.zksync.zksolc.as_ref(), config.offline)?
{
zksolc
} else if !config.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(ZkSolcCompiler { zksolc, solc: config_solc_compiler(config)? })
config.zksync.settings(libraries, config.evm_version, config.via_ir, config.offline)
}

/// Create a new zkSync project
/// Create a new ZKsync project
pub fn config_create_project(
config: &Config,
cached: bool,
Expand All @@ -217,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)?;

Expand Down
8 changes: 4 additions & 4 deletions crates/linking/src/zksync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ZkSolcCompiler, ZkArtifactOutput>,
}

Expand All @@ -57,7 +57,7 @@ impl<'a> ZkLinker<'a> {
pub fn new(
root: impl Into<PathBuf>,
contracts: ArtifactContracts<CompactContractBytecodeCow<'a>>,
compiler: ZkSolcCompiler,
compiler: PathBuf,
compiler_output: &'a ProjectCompileOutput<ZkSolcCompiler, ZkArtifactOutput>,
) -> Self {
Self { linker: Linker::new(root, contracts), compiler, compiler_output }
Expand Down Expand Up @@ -299,7 +299,7 @@ impl<'a> ZkLinker<'a> {
contracts: &ArtifactContracts<CompactContractBytecodeCow<'a>>,
target: &ArtifactId,
libraries: &Libraries,
zksolc: &ZkSolcCompiler,
zksolc_path: &Path,
) -> Result<CompactContractBytecodeCow<'a>, ZkLinkerError> {
let artifact_to_link_id = |id: &ArtifactId| format!("{}:{}", id.source.display(), id.name);

Expand Down Expand Up @@ -336,7 +336,7 @@ impl<'a> ZkLinker<'a> {
.collect::<HashSet<_>>();

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);
Expand Down
14 changes: 9 additions & 5 deletions crates/script/src/build/zksync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,27 @@ use super::BuildData;

impl BuildData {
fn get_zk_linker(&self, script_config: &ScriptConfig) -> Result<ZkLinker<'_>> {
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,
Expand Down
8 changes: 4 additions & 4 deletions crates/strategy/zksync/src/executor/runner/libraries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ impl ZksyncExecutorStrategyRunner {
let contracts: ArtifactContracts<CompactContractBytecodeCow<'_>> =
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,
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion crates/verify/src/etherscan/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ Diagnostics: {diags}",
},
solc_version: solc_version.clone(),
cli_settings: CliSettings::default(),
zksolc_path,
};

let solc_compiler = if compiler_version.is_zksync_solc {
Expand All @@ -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()) {
Expand Down
4 changes: 2 additions & 2 deletions crates/verify/src/zk_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand All @@ -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 })
}
Expand Down
1 change: 1 addition & 0 deletions crates/zksync/compilers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ similar-asserts.workspace = true
fd-lock = "4.0.2"
tempfile.workspace = true
foundry-test-utils.workspace = true

7 changes: 5 additions & 2 deletions crates/zksync/compilers/src/compilers/zksolc/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -40,10 +42,11 @@ impl CompilerInput for ZkSolcVersionedInput {
language: Self::Language,
version: Version,
) -> Self {
let ZkSolcSettings { settings, cli_settings } = settings;
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 {
Expand Down
20 changes: 3 additions & 17 deletions crates/zksync/compilers/src/compilers/zksolc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,12 @@ impl ZkSolcOS {
}

/// ZkSolc compiler
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
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() }
}
}

impl Compiler for ZkSolcCompiler {
type Input = ZkSolcVersionedInput;
type CompilationError = Error;
Expand All @@ -152,6 +142,7 @@ impl Compiler for ZkSolcCompiler {
let zksolc = self.zksolc(input)?;

let mut zk_output = zksolc.compile(&input.input)?;

let mut metadata = BTreeMap::new();
if let Some(solc_version) = zk_output.version.take() {
metadata.insert("solcVersion".to_string(), solc_version.into());
Expand Down Expand Up @@ -236,19 +227,14 @@ 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);
zksolc.include_paths.clone_from(&input.cli_settings.include_paths);

Ok(zksolc)
}

/// Retrieve the version of the specified `zksolc`
pub fn version(&self) -> Result<Version> {
ZkSolc::get_version_for_path(self.zksolc.as_ref())
}
}

/// Version metadata. Will include `zksync_version` if compiler is zksync solc.
Expand Down
Loading