Skip to content

Commit 30f82a5

Browse files
committed
Move zksolc command from compiler to settings
1 parent ec63bec commit 30f82a5

File tree

12 files changed

+132
-262
lines changed

12 files changed

+132
-262
lines changed

crates/common/src/compile.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use foundry_compilers::{
2020
Artifact, Project, ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, SolcConfig,
2121
};
2222
use foundry_zksync_compilers::compilers::{
23-
artifact_output::zk::ZkArtifactOutput,
24-
zksolc::{ZkSolc, ZkSolcCompiler},
23+
artifact_output::zk::ZkArtifactOutput, zksolc::ZkSolcCompiler,
2524
};
2625

2726
use num_format::{Locale, ToFormattedString};
@@ -331,7 +330,7 @@ impl ProjectCompiler {
331330
let files = self.files.clone();
332331

333332
{
334-
let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?;
333+
let zksolc_version = project.settings.zksolc_version_ref();
335334
Report::new(SpinnerReporter::spawn_with(format!("Using zksolc-{zksolc_version}")));
336335
}
337336
self.zksync_compile_with(|| {

crates/config/src/zksync.rs

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl ZkSyncConfig {
115115
evm_version: EvmVersion,
116116
via_ir: bool,
117117
offline: bool,
118-
) -> ZkSolcSettings {
118+
) -> Result<ZkSolcSettings, SolcError> {
119119
let optimizer = Optimizer {
120120
enabled: Some(self.optimizer),
121121
mode: Some(self.optimizer_mode),
@@ -125,7 +125,7 @@ impl ZkSyncConfig {
125125
jump_table_density_threshold: None,
126126
};
127127

128-
let zk_settings = ZkSettings {
128+
let settings = ZkSettings {
129129
libraries,
130130
optimizer,
131131
evm_version: Some(evm_version),
@@ -147,16 +147,22 @@ impl ZkSyncConfig {
147147
suppressed_errors: self.suppressed_errors.clone(),
148148
};
149149

150-
let zksolc_path = get_zksolc_compiler(self.zksolc.as_ref(), offline)
151-
.unwrap_or_else(|e| panic!("Could not find zksolc compiler: {e}"));
150+
let zksolc_path = if let Some(path) = config_ensure_zksolc(self.zksolc.as_ref(), offline)? {
151+
path
152+
} else if !offline {
153+
let default_version = semver::Version::new(1, 5, 11);
154+
let mut zksolc = ZkSolc::find_installed_version(&default_version)?;
155+
if zksolc.is_none() {
156+
ZkSolc::blocking_install(&default_version)?;
157+
zksolc = ZkSolc::find_installed_version(&default_version)?;
158+
}
159+
zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{default_version}"))
160+
} else {
161+
"zksolc".into()
162+
};
152163

153164
// `cli_settings` get set from `Project` values when building `ZkSolcVersionedInput`
154-
ZkSolcSettings {
155-
settings: zk_settings,
156-
cli_settings: CliSettings::default(),
157-
zksolc_version: ZkSolc::get_version_for_path(zksolc_path.as_ref())
158-
.unwrap_or_else(|_| panic!("Could not find zksolc version for this path")),
159-
}
165+
ZkSolcSettings::new_from_path(settings, CliSettings::default(), zksolc_path)
160166
}
161167
}
162168

@@ -172,37 +178,15 @@ pub fn config_zksolc_settings(config: &Config) -> Result<ZkSolcSettings, SolcErr
172178
Err(e) => return Err(SolcError::msg(format!("Failed to parse libraries: {e}"))),
173179
};
174180

175-
Ok(config.zksync.settings(libraries, config.evm_version, config.via_ir, config.offline))
176-
}
177-
178-
/// get the configured `zksolc` compiler
179-
pub fn get_zksolc_compiler(zksolc: Option<&SolcReq>, offline: bool) -> Result<PathBuf, SolcError> {
180-
let zksolc = if let Some(zksolc) = config_ensure_zksolc(zksolc, offline)? {
181-
zksolc
182-
} else if !offline {
183-
let default_version = semver::Version::new(1, 5, 11);
184-
let mut zksolc = ZkSolc::find_installed_version(&default_version)?;
185-
if zksolc.is_none() {
186-
ZkSolc::blocking_install(&default_version)?;
187-
zksolc = ZkSolc::find_installed_version(&default_version)?;
188-
}
189-
zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{default_version}"))
190-
} else {
191-
"zksolc".into()
192-
};
193-
194-
Ok(zksolc)
181+
config.zksync.settings(libraries, config.evm_version, config.via_ir, config.offline)
195182
}
196183

197184
/// Return the configured `zksolc` compiler
198185
///
199186
/// If not `offline`, will install the default version automatically
200187
/// Will fallback to `zksolc` present in the environment
201188
pub fn config_zksolc_compiler(config: &Config) -> Result<ZkSolcCompiler, SolcError> {
202-
Ok(ZkSolcCompiler {
203-
zksolc: get_zksolc_compiler(config.zksync.zksolc.as_ref(), config.offline)?,
204-
solc: config_solc_compiler(config)?,
205-
})
189+
Ok(ZkSolcCompiler { solc: config_solc_compiler(config)? })
206190
}
207191

208192
/// Create a new ZKsync project

crates/linking/src/zksync.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub const DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION: Version = Version::new(1, 5, 9
4444
#[derive(Debug)]
4545
pub struct ZkLinker<'a> {
4646
pub linker: Linker<'a>,
47-
pub compiler: ZkSolcCompiler,
47+
pub compiler: PathBuf,
4848
pub compiler_output: &'a ProjectCompileOutput<ZkSolcCompiler, ZkArtifactOutput>,
4949
}
5050

@@ -57,7 +57,7 @@ impl<'a> ZkLinker<'a> {
5757
pub fn new(
5858
root: impl Into<PathBuf>,
5959
contracts: ArtifactContracts<CompactContractBytecodeCow<'a>>,
60-
compiler: ZkSolcCompiler,
60+
compiler: PathBuf,
6161
compiler_output: &'a ProjectCompileOutput<ZkSolcCompiler, ZkArtifactOutput>,
6262
) -> Self {
6363
Self { linker: Linker::new(root, contracts), compiler, compiler_output }
@@ -299,7 +299,7 @@ impl<'a> ZkLinker<'a> {
299299
contracts: &ArtifactContracts<CompactContractBytecodeCow<'a>>,
300300
target: &ArtifactId,
301301
libraries: &Libraries,
302-
zksolc: &ZkSolcCompiler,
302+
zksolc_path: &Path,
303303
) -> Result<CompactContractBytecodeCow<'a>, ZkLinkerError> {
304304
let artifact_to_link_id = |id: &ArtifactId| format!("{}:{}", id.source.display(), id.name);
305305

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

338338
let mut link_output =
339-
zk_link::zksolc_link(zksolc, zk_link::LinkJsonInput { bytecodes, libraries })
339+
zk_link::zksolc_link(zksolc_path, zk_link::LinkJsonInput { bytecodes, libraries })
340340
.expect("able to call zksolc --link"); // TODO(zk): proper error check
341341

342342
let link_id = &artifact_to_link_id(target);

crates/script/src/build/zksync.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,27 @@ use super::BuildData;
1818

1919
impl BuildData {
2020
fn get_zk_linker(&self, script_config: &ScriptConfig) -> Result<ZkLinker<'_>> {
21-
let zksolc = foundry_config::zksync::config_zksolc_compiler(&script_config.config)
21+
let zksolc_settings = foundry_config::zksync::config_zksolc_settings(&script_config.config)
2222
.context("retrieving zksolc compiler to be used for linking")?;
23-
let version = zksolc.version().context("trying to determine zksolc version")?;
23+
let version = zksolc_settings.zksolc_version_ref();
2424

2525
let Some(input) = self.zk_output.as_ref() else {
2626
eyre::bail!("unable to link zk artifacts if no zk compilation output is provided")
2727
};
2828

29-
let linker =
30-
ZkLinker::new(self.project_root.clone(), input.artifact_ids().collect(), zksolc, input);
29+
let linker = ZkLinker::new(
30+
self.project_root.clone(),
31+
input.artifact_ids().collect(),
32+
zksolc_settings.zksolc_path(),
33+
input,
34+
);
3135

3236
let mut libs = Default::default();
3337
linker.zk_collect_dependencies(&self.target, &mut libs, None)?;
3438

3539
// if there are no no libs, no linking will happen
3640
// so we can skip version check
37-
if !libs.is_empty() && version < DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION {
41+
if !libs.is_empty() && version < &DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION {
3842
eyre::bail!(
3943
"deploy-time linking not supported. minimum: {}, given: {}",
4044
DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION,

crates/strategy/zksync/src/executor/runner/libraries.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ impl ZksyncExecutorStrategyRunner {
5656
let contracts: ArtifactContracts<CompactContractBytecodeCow<'_>> =
5757
input.artifact_ids().collect();
5858

59-
let Ok(zksolc) = foundry_config::zksync::config_zksolc_compiler(config) else {
59+
let Ok(zksolc_settings) = foundry_config::zksync::config_zksolc_settings(config) else {
6060
tracing::error!("unable to determine zksolc compiler to be used for linking");
6161
// TODO(zk): better error
6262
return Err(LinkerError::CyclicDependency);
6363
};
64-
let version = zksolc.version().map_err(|_| LinkerError::CyclicDependency)?;
64+
let version = zksolc_settings.zksolc_version_ref();
6565

66-
let linker = ZkLinker::new(root, contracts.clone(), zksolc, input);
66+
let linker = ZkLinker::new(root, contracts.clone(), zksolc_settings.zksolc_path(), input);
6767

6868
let zk_linker_error_to_linker = |zk_error| match zk_error {
6969
ZkLinkerError::Inner(err) => err,
@@ -93,7 +93,7 @@ impl ZksyncExecutorStrategyRunner {
9393
// so we can skip the version check
9494
if !libraries.is_empty() {
9595
// TODO(zk): better error
96-
if version < DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION {
96+
if version < &DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION {
9797
tracing::error!(
9898
%version,
9999
minimum_version = %DEPLOY_TIME_LINKING_ZKSOLC_MIN_VERSION,

crates/verify/src/etherscan/flatten.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ Diagnostics: {diags}",
188188
},
189189
solc_version: solc_version.clone(),
190190
cli_settings: CliSettings::default(),
191+
zksolc_path: zksolc_path.clone(),
191192
};
192193

193194
let solc_compiler = if compiler_version.is_zksync_solc {
@@ -199,7 +200,7 @@ Diagnostics: {diags}",
199200
SolcCompiler::Specific(solc)
200201
};
201202

202-
let zksolc_compiler = ZkSolcCompiler { zksolc: zksolc_path, solc: solc_compiler };
203+
let zksolc_compiler = ZkSolcCompiler { solc: solc_compiler };
203204

204205
let out = zksolc_compiler.compile(&input)?;
205206
if out.errors.iter().any(|e| e.is_error()) {

crates/verify/src/zk_provider.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl ZkVerificationContext {
4545
let mut project =
4646
foundry_config::zksync::config_create_project(&config, config.cache, false)?;
4747
project.no_artifacts = true;
48-
let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?;
48+
let zksolc_version = project.settings.zksolc_version_ref();
4949

5050
let (solc_version, is_zksync_solc) = if let Some(solc) = &config.zksync.solc_path {
5151
let solc_type_and_version = zksolc::get_solc_version_info(solc)?;
@@ -68,7 +68,7 @@ impl ZkVerificationContext {
6868
};
6969

7070
let compiler_version =
71-
ZkVersion { zksolc: zksolc_version, solc: solc_version, is_zksync_solc };
71+
ZkVersion { zksolc: zksolc_version.clone(), solc: solc_version, is_zksync_solc };
7272

7373
Ok(Self { config, project, target_name, target_path, compiler_version })
7474
}

crates/zksync/compilers/src/compilers/zksolc/input.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub struct ZkSolcVersionedInput {
2525
pub solc_version: Version,
2626
/// zksolc cli settings
2727
pub cli_settings: solc::CliSettings,
28+
/// zksolc binary path
29+
pub zksolc_path: PathBuf,
2830
}
2931

3032
impl CompilerInput for ZkSolcVersionedInput {
@@ -40,10 +42,11 @@ impl CompilerInput for ZkSolcVersionedInput {
4042
language: Self::Language,
4143
version: Version,
4244
) -> Self {
45+
let zksolc_path = settings.zksolc_path();
4346
let ZkSolcSettings { settings, cli_settings, .. } = settings;
4447
let input = ZkSolcInput::new(language, sources, settings).sanitized(&version);
4548

46-
Self { solc_version: version, input, cli_settings }
49+
Self { solc_version: version, input, cli_settings, zksolc_path }
4750
}
4851

4952
fn language(&self) -> Self::Language {

crates/zksync/compilers/src/compilers/zksolc/mod.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,13 @@ impl ZkSolcOS {
123123
/// ZkSolc compiler
124124
#[derive(Debug, Clone)]
125125
pub struct ZkSolcCompiler {
126-
/// zksolc path
127-
pub zksolc: PathBuf,
128126
/// solc compiler to use along zksolc
129127
pub solc: SolcCompiler,
130128
}
131129

132130
impl Default for ZkSolcCompiler {
133131
fn default() -> Self {
134-
let zksolc =
135-
ZkSolc::get_path_for_version(&ZKSOLC_VERSION).expect("Could not install zksolc");
136-
Self { zksolc, solc: Default::default() }
132+
Self { solc: Default::default() }
137133
}
138134
}
139135

@@ -237,19 +233,14 @@ impl ZkSolcCompiler {
237233
}
238234
};
239235

240-
let mut zksolc = ZkSolc::new(self.zksolc.clone(), solc)?;
236+
let mut zksolc = ZkSolc::new(input.zksolc_path.clone(), solc)?;
241237

242238
zksolc.base_path.clone_from(&input.cli_settings.base_path);
243239
zksolc.allow_paths.clone_from(&input.cli_settings.allow_paths);
244240
zksolc.include_paths.clone_from(&input.cli_settings.include_paths);
245241

246242
Ok(zksolc)
247243
}
248-
249-
/// Retrieve the version of the specified `zksolc`
250-
pub fn version(&self) -> Result<Version> {
251-
ZkSolc::get_version_for_path(self.zksolc.as_ref())
252-
}
253244
}
254245

255246
/// Version metadata. Will include `zksync_version` if compiler is zksync solc.

crates/zksync/compilers/src/compilers/zksolc/settings.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_ty
44
use foundry_compilers::{
55
artifacts::{serde_helpers, EvmVersion, Libraries},
66
compilers::CompilerSettings,
7+
error::Result,
78
solc, CompilerSettingsRestrictions,
89
};
910
use foundry_compilers_artifacts_solc::{output_selection::OutputSelection, remappings::Remapping};
@@ -16,7 +17,7 @@ use std::{
1617
str::FromStr,
1718
};
1819

19-
use super::{ZkSolc, ZkSolcCompiler};
20+
use super::{ZkSolc, ZKSOLC_VERSION};
2021
///
2122
/// The Solidity compiler codegen.
2223
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
@@ -101,21 +102,65 @@ pub struct ZkSolcSettings {
101102
/// Additional CLI args configuration
102103
#[serde(flatten)]
103104
pub cli_settings: solc::CliSettings,
104-
/// The version of the zksolc compiler to use.
105-
pub zksolc_version: Version,
105+
/// The version of the zksolc compiler to use. Retrieved from `zksolc_path`
106+
zksolc_version: Version,
107+
/// zksolc path
108+
zksolc_path: PathBuf,
106109
}
107110

108111
impl Default for ZkSolcSettings {
109112
fn default() -> Self {
113+
let zksolc_path = ZkSolc::get_path_for_version(&ZKSOLC_VERSION)
114+
.expect("failed getting default zksolc version path");
110115
Self {
111116
settings: Default::default(),
112117
cli_settings: Default::default(),
113-
zksolc_version: ZkSolc::get_version_for_path(ZkSolcCompiler::default().zksolc.as_ref())
114-
.expect("Failed to get zksolc version"),
118+
zksolc_version: ZKSOLC_VERSION,
119+
zksolc_path,
115120
}
116121
}
117122
}
118123

124+
impl ZkSolcSettings {
125+
/// Initialize settings for a given zksolc path
126+
pub fn new_from_path(
127+
settings: ZkSettings,
128+
cli_settings: solc::CliSettings,
129+
zksolc_path: PathBuf,
130+
) -> Result<Self> {
131+
let zksolc_version = ZkSolc::get_version_for_path(&zksolc_path)?;
132+
Ok(Self { settings, cli_settings, zksolc_path, zksolc_version })
133+
}
134+
135+
/// Initialize settings for a given zksolc version
136+
pub fn new_from_version(
137+
settings: ZkSettings,
138+
cli_settings: solc::CliSettings,
139+
zksolc_version: Version,
140+
) -> Result<Self> {
141+
let zksolc_path = ZkSolc::get_path_for_version(&zksolc_version)?;
142+
Ok(Self { settings, cli_settings, zksolc_path, zksolc_version })
143+
}
144+
145+
/// Get zksolc path
146+
pub fn zksolc_path(&self) -> PathBuf {
147+
self.zksolc_path.clone()
148+
}
149+
150+
/// Get zksolc version
151+
pub fn zksolc_version_ref(&self) -> &Version {
152+
&self.zksolc_version
153+
}
154+
155+
/// Set a specific zksolc version
156+
pub fn set_zksolc_version(&mut self, zksolc_version: Version) -> Result<()> {
157+
let zksolc_path = ZkSolc::get_path_for_version(&zksolc_version)?;
158+
self.zksolc_version = zksolc_version;
159+
self.zksolc_path = zksolc_path;
160+
Ok(())
161+
}
162+
}
163+
119164
impl ZkSettings {
120165
/// Creates a new `Settings` instance with the given `output_selection`
121166
pub fn new(output_selection: impl Into<ZkOutputSelection>) -> Self {
@@ -225,8 +270,6 @@ impl CompilerSettings for ZkSolcSettings {
225270
..
226271
} = self;
227272

228-
println!("ybue: zksolc_version: {:?}", self.zksolc_version);
229-
230273
*via_ir == other.settings.via_ir &&
231274
*remappings == other.settings.remappings &&
232275
*evm_version == other.settings.evm_version &&

0 commit comments

Comments
 (0)