diff --git a/Cargo.lock b/Cargo.lock index 622f3beff8d0..32ee93ab6505 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8307,6 +8307,7 @@ dependencies = [ "hex", "lazy_static", "regex", + "semver", "serde", "serde_json", "tempfile", diff --git a/core/lib/contract_verifier/Cargo.toml b/core/lib/contract_verifier/Cargo.toml index 5b5ab4b5e429..ea84024cba98 100644 --- a/core/lib/contract_verifier/Cargo.toml +++ b/core/lib/contract_verifier/Cargo.toml @@ -31,3 +31,4 @@ lazy_static.workspace = true tempfile.workspace = true regex.workspace = true tracing.workspace = true +semver.workspace = true diff --git a/core/lib/contract_verifier/src/lib.rs b/core/lib/contract_verifier/src/lib.rs index 3ff4c2e18c77..224d4b292347 100644 --- a/core/lib/contract_verifier/src/lib.rs +++ b/core/lib/contract_verifier/src/lib.rs @@ -153,7 +153,11 @@ impl ContractVerifier { )); } - let zksolc = ZkSolc::new(zksolc_path, solc_path); + let zksolc = ZkSolc::new( + zksolc_path, + solc_path, + request.req.compiler_versions.zk_compiler_version(), + ); let output = time::timeout(config.compilation_timeout(), zksolc.async_compile(input)) .await diff --git a/core/lib/contract_verifier/src/zksolc_utils.rs b/core/lib/contract_verifier/src/zksolc_utils.rs index 4952c1e21d0d..08004632bcec 100644 --- a/core/lib/contract_verifier/src/zksolc_utils.rs +++ b/core/lib/contract_verifier/src/zksolc_utils.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, io::Write, path::PathBuf, process::Stdio}; +use semver::Version; use serde::{Deserialize, Serialize}; use crate::error::ContractVerifierError; @@ -77,13 +78,19 @@ impl Default for Optimizer { pub struct ZkSolc { zksolc_path: PathBuf, solc_path: PathBuf, + zksolc_version: String, } impl ZkSolc { - pub fn new(zksolc_path: impl Into, solc_path: impl Into) -> Self { + pub fn new( + zksolc_path: impl Into, + solc_path: impl Into, + zksolc_version: String, + ) -> Self { ZkSolc { zksolc_path: zksolc_path.into(), solc_path: solc_path.into(), + zksolc_version, } } @@ -93,26 +100,36 @@ impl ZkSolc { ) -> Result { use tokio::io::AsyncWriteExt; let mut command = tokio::process::Command::new(&self.zksolc_path); + command.stdout(Stdio::piped()).stderr(Stdio::piped()); + match &input { ZkSolcInput::StandardJson(input) => { - if input.settings.is_system { - command.arg("--system-mode"); - } - if input.settings.force_evmla { - command.arg("--force-evmla"); + if !self.is_post_1_5_0() { + if input.settings.is_system { + command.arg("--system-mode"); + } + if input.settings.force_evmla { + command.arg("--force-evmla"); + } } + + command.arg("--solc").arg(self.solc_path.to_str().unwrap()); } ZkSolcInput::YulSingleFile { is_system, .. } => { - if *is_system { - command.arg("--system-mode"); + if self.is_post_1_5_0() { + if *is_system { + command.arg("--enable-eravm-extensions"); + } else { + command.arg("--solc").arg(self.solc_path.to_str().unwrap()); + } + } else { + if *is_system { + command.arg("--system-mode"); + } + command.arg("--solc").arg(self.solc_path.to_str().unwrap()); } } } - command - .arg("--solc") - .arg(self.solc_path.to_str().unwrap()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()); match input { ZkSolcInput::StandardJson(input) => { let mut child = command @@ -181,4 +198,53 @@ impl ZkSolc { } } } + + pub fn is_post_1_5_0(&self) -> bool { + // Special case + if &self.zksolc_version == "vm-1.5.0-a167aa3" { + false + } else if let Some(version) = self.zksolc_version.strip_prefix("v") { + if let Ok(semver) = Version::parse(version) { + let target = Version::new(1, 5, 0); + semver >= target + } else { + true + } + } else { + true + } + } +} + +#[cfg(test)] +mod tests { + use crate::zksolc_utils::ZkSolc; + + #[test] + fn check_is_post_1_5_0() { + // Special case. + let mut zksolc = ZkSolc::new(".", ".", "vm-1.5.0-a167aa3".to_string()); + assert!(!zksolc.is_post_1_5_0(), "vm-1.5.0-a167aa3"); + + zksolc.zksolc_version = "v1.5.0".to_string(); + assert!(zksolc.is_post_1_5_0(), "v1.5.0"); + + zksolc.zksolc_version = "v1.5.1".to_string(); + assert!(zksolc.is_post_1_5_0(), "v1.5.1"); + + zksolc.zksolc_version = "v1.10.1".to_string(); + assert!(zksolc.is_post_1_5_0(), "v1.10.1"); + + zksolc.zksolc_version = "v2.0.0".to_string(); + assert!(zksolc.is_post_1_5_0(), "v2.0.0"); + + zksolc.zksolc_version = "v1.4.15".to_string(); + assert!(!zksolc.is_post_1_5_0(), "v1.4.15"); + + zksolc.zksolc_version = "v1.3.21".to_string(); + assert!(!zksolc.is_post_1_5_0(), "v1.3.21"); + + zksolc.zksolc_version = "v0.5.1".to_string(); + assert!(!zksolc.is_post_1_5_0(), "v0.5.1"); + } } diff --git a/core/lib/types/src/contract_verification_api.rs b/core/lib/types/src/contract_verification_api.rs index 033bb9dc9f36..588de3cb675e 100644 --- a/core/lib/types/src/contract_verification_api.rs +++ b/core/lib/types/src/contract_verification_api.rs @@ -140,7 +140,7 @@ pub struct VerificationIncomingRequest { pub optimizer_mode: Option, #[serde(default)] pub constructor_arguments: Bytes, - #[serde(default)] + #[serde(default, alias = "enableEraVMExtensions")] pub is_system: bool, #[serde(default)] pub force_evmla: bool,