From 63efb2e530d8b1445bdd58537d6f0cdb5593cd75 Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:13:12 +0300 Subject: [PATCH] feat(contract-verifier): Adjust contract verifier for zksolc 1.5.0 (#2255) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - `system-mode`, `force-evmla` flag are not provided for zksolc post v1.5.0 compilations - `solc-path` is not provided for system yul post v1.5.0 compilations ## Why ❔ Changes in compiler interface ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zk fmt` and `zk lint`. - [ ] Spellcheck has been run via `zk spellcheck`. --- Cargo.lock | 1 + core/lib/contract_verifier/Cargo.toml | 1 + core/lib/contract_verifier/src/lib.rs | 6 +- .../lib/contract_verifier/src/zksolc_utils.rs | 92 ++++++++++++++++--- .../types/src/contract_verification_api.rs | 2 +- 5 files changed, 87 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a99150fe01c0..ccfb6715884e 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,